diff --git a/apps/emqx_modules/i18n/emqx_telemetry_api_i18n.conf b/apps/emqx_modules/i18n/emqx_telemetry_api_i18n.conf new file mode 100644 index 000000000..a8f562065 --- /dev/null +++ b/apps/emqx_modules/i18n/emqx_telemetry_api_i18n.conf @@ -0,0 +1,121 @@ +emqx_telemetry_api { + + get_telemetry_status_api { + desc { + en: """Get telemetry status""" + zh: """获取遥测状态""" + } + } + + update_telemetry_status_api { + desc { + en: """Enable or disable telemetry""" + zh: """更新遥测状态""" + } + } + + get_telemetry_data_api { + desc { + en: """Get telemetry data""" + zh: """获取遥测数据""" + } + } + + enable { + desc { + en: """Enable telemetry""" + zh: """启用遥测""" + } + } + + emqx_version { + desc { + en: """Get emqx version""" + zh: """获取 emqx 版本""" + } + } + + license { + desc { + en: """Get license information""" + zh: """获取 license 信息""" + } + } + + os_name { + desc { + en: """Get OS name""" + zh: """获取操作系统名称""" + } + } + + os_version { + desc { + en: """Get OS version""" + zh: """获取操作系统版本""" + } + } + + otp_version { + desc { + en: """Get Erlang OTP version""" + zh: """获取 OTP 版本""" + } + } + + up_time { + desc { + en: """Get uptime""" + zh: """获取运行时间""" + } + } + + uuid { + desc { + en: """Get UUID""" + zh: """获取 UUID""" + } + } + + nodes_uuid { + desc { + en: """Get nodes UUID""" + zh: """获取节点 UUID""" + } + } + + active_plugins { + desc { + en: """Get active plugins""" + zh: """获取活跃插件""" + } + } + + active_modules { + desc { + en: """Get active modules""" + zh: """获取活跃模块""" + } + } + + num_clients { + desc { + en: """Get number of clients""" + zh: """获取客户端数量""" + } + } + + messages_received { + desc { + en: """Get number of messages received""" + zh: """获取接收到的消息数量""" + } + } + + messages_sent { + desc { + en: """Get number of messages sent""" + zh: """获取发送的消息数量""" + } + } +} diff --git a/apps/emqx_modules/i18n/emqx_topic_metrics_api_i18n.conf b/apps/emqx_modules/i18n/emqx_topic_metrics_api_i18n.conf new file mode 100644 index 000000000..3725ccd13 --- /dev/null +++ b/apps/emqx_modules/i18n/emqx_topic_metrics_api_i18n.conf @@ -0,0 +1,238 @@ +emqx_topic_metrics_api { + get_topic_metrics_api { + desc { + en: """List Topic metrics""" + zh: """获取主题监控数据""" + } + } + + reset_topic_metrics_api{ + desc { + en: """Reset telemetry status""" + zh: """重置主题监控状态""" + } + } + + post_topic_metrics_api { + desc { + en: """Create Topic metrics""" + zh: """创建主题监控数据""" + } + } + + gat_topic_metrics_data_api { + desc { + en: """Get Topic metrics""" + zh: """获取主题监控数据""" + } + } + + delete_topic_metrics_data_api { + desc { + en: """Delete Topic metrics""" + zh: """删除主题监控数据""" + } + } + + topic_metrics_api_response409 { + desc { + en: """Conflict. Topic metrics exceeded max limit 512""" + zh: """冲突。主题监控数据超过最大限制512""" + } + } + + topic_metrics_api_response400 { + desc { + en: """Bad Request. Already exists or bad topic name""" + zh: """错误请求。已存在或错误的主题名称""" + } + } + + topic_metrics_api_response404 { + desc { + en: """Not Found. Topic metrics not found""" + zh: """未找到。主题监控数据未找到""" + } + } + + reset_topic_desc { + en: """Topic Name. If this parameter is not present,all created topic metrics will be reset.""" + zh: """主题名称。如果此参数不存在,则所有创建的主题监控数据都将重置。""" + } + + topic { + desc { + en: """Topic""" + zh: """主题""" + } + } + + topic_in_body { + desc { + en: """Raw topic string""" + zh: """主题字符串""" + } + } + + topic_in_path { + desc { + en: """Topic string. Notice: Topic string in url path must be encoded""" + zh: """主题字符串。注意:主题字符串在url路径中必须编码""" + } + } + + action { + desc { + en: """Action. Only support reset""" + zh: """操作,仅支持 reset""" + } + } + + create_time { + desc { + en: """Create time""" + zh: """创建时间。标准 rfc3339 时间格式,例如:2018-01-01T12:00:00Z""" + } + } + + reset_time { + desc { + en: """Reset time. In rfc3339. Nullable if never reset""" + zh: """重置时间。标准 rfc3339 时间格式,例如:2018-01-01T12:00:00Z。如果从未重置则为空""" + } + } + + metrics { + desc { + en: """Metrics""" + zh: """监控数据""" + } + } + + message_dropped_count { + desc { + en: """Dropped messages count""" + zh: """丢弃消息数量""" + } + } + + message_dropped_rate { + desc { + en: """Dropped messages rate""" + zh: """丢弃消息速率""" + } + } + + message_in_count { + desc { + en: """In messages count""" + zh: """接收消息数量""" + } + } + + message_in_rate { + desc { + en: """In messages rate""" + zh: """接收消息速率""" + } + } + + message_out_count { + desc { + en: """Out messages count""" + zh: """发送消息数量""" + } + } + + message_out_rate { + desc { + en: """Out messages rate""" + zh: """发送消息速率""" + } + } + + message_qos0_in_count { + desc { + en: """QoS0 in messages count""" + zh: """QoS0 接收消息数量""" + } + } + + message_qos0_in_rate { + desc { + en: """QoS0 in messages rate""" + zh: """QoS0 接收消息速率""" + } + } + + message_qos0_out_count { + desc { + en: """QoS0 out messages count""" + zh: """QoS0 发送消息数量""" + } + } + + message_qos0_out_rate { + desc { + en: """QoS0 out messages rate""" + zh: """QoS0 发送消息速率""" + } + } + + message_qos1_in_count { + desc { + en: """QoS1 in messages count""" + zh: """QoS1 接收消息数量""" + } + } + + message_qos1_in_rate { + desc { + en: """QoS1 in messages rate""" + zh: """QoS1 接收消息速率""" + } + } + + message_qos1_out_count { + desc { + en: """QoS1 out messages count""" + zh: """QoS1 发送消息数量""" + } + } + + message_qos1_out_rate { + desc { + en: """QoS1 out messages rate""" + zh: """QoS1 发送消息速率""" + } + } + + message_qos2_in_count { + desc { + en: """QoS2 in messages count""" + zh: """QoS2 接收消息数量""" + } + } + + message_qos2_in_rate { + desc { + en: """QoS2 in messages rate""" + zh: """QoS2 接收消息速率""" + } + } + + message_qos2_out_count { + desc { + en: """QoS2 out messages count""" + zh: """QoS2 发送消息数量""" + } + } + + message_qos2_out_rate { + desc { + en: """QoS2 out messages rate""" + zh: """QoS2 发送消息速率""" + } + } + +} diff --git a/apps/emqx_modules/src/emqx_telemetry_api.erl b/apps/emqx_modules/src/emqx_telemetry_api.erl index 7d65cbd7e..46b3922b5 100644 --- a/apps/emqx_modules/src/emqx_telemetry_api.erl +++ b/apps/emqx_modules/src/emqx_telemetry_api.erl @@ -18,6 +18,7 @@ -behaviour(minirest_api). +-include_lib("hocon/include/hoconsc.hrl"). -include_lib("typerefl/include/types.hrl"). -import(hoconsc, [mk/2, ref/1, ref/2, array/1]). @@ -50,18 +51,17 @@ schema("/telemetry/status") -> 'operationId' => status, get => #{ - description => <<"Get telemetry status">>, + description => ?DESC(get_telemetry_status_api), responses => - #{200 => status_schema(<<"Get telemetry status">>)} + #{200 => status_schema(?DESC(get_telemetry_status_api))} }, put => #{ - description => <<"Enable or disable telemetry">>, - 'requestBody' => status_schema(<<"Enable or disable telemetry">>), + description => ?DESC(update_telemetry_status_api), + 'requestBody' => status_schema(?DESC(update_telemetry_status_api)), responses => #{ - 200 => status_schema(<<"Enable or disable telemetry successfully">>), - 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad Request">>) + 200 => status_schema(?DESC(update_telemetry_status_api)) } } }; @@ -70,9 +70,9 @@ schema("/telemetry/data") -> 'operationId' => data, get => #{ - description => <<"Get telemetry data">>, + description => ?DESC(get_telemetry_data_api), responses => - #{200 => mk(ref(?MODULE, telemetry), #{desc => <<"Get telemetry data">>})} + #{200 => mk(ref(?MODULE, telemetry), #{desc => ?DESC(get_telemetry_data_api)})} } }. @@ -85,7 +85,7 @@ fields(status) -> mk( boolean(), #{ - desc => <<"Telemetry status">>, + desc => ?DESC(enable), default => true, example => false } @@ -97,7 +97,7 @@ fields(telemetry) -> mk( string(), #{ - desc => <<"EMQX Version">>, + desc => ?DESC(emqx_version), example => <<"5.0.0-beta.3-32d1547c">> } )}, @@ -105,7 +105,7 @@ fields(telemetry) -> mk( map(), #{ - desc => <<"EMQX License">>, + desc => ?DESC(license), example => #{edition => <<"community">>} } )}, @@ -113,7 +113,7 @@ fields(telemetry) -> mk( string(), #{ - desc => <<"OS Name">>, + desc => ?DESC(os_name), example => <<"Linux">> } )}, @@ -121,7 +121,7 @@ fields(telemetry) -> mk( string(), #{ - desc => <<"OS Version">>, + desc => ?DESC(os_version), example => <<"20.04">> } )}, @@ -129,7 +129,7 @@ fields(telemetry) -> mk( string(), #{ - desc => <<"Erlang/OTP Version">>, + desc => ?DESC(otp_version), example => <<"24">> } )}, @@ -137,7 +137,7 @@ fields(telemetry) -> mk( integer(), #{ - desc => <<"EMQX Runtime">>, + desc => ?DESC(up_time), example => 20220113 } )}, @@ -145,7 +145,7 @@ fields(telemetry) -> mk( string(), #{ - desc => <<"EMQX UUID">>, + desc => ?DESC(uuid), example => <<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">> } )}, @@ -153,7 +153,7 @@ fields(telemetry) -> mk( array(binary()), #{ - desc => <<"EMQX Cluster Nodes UUID">>, + desc => ?DESC(nodes_uuid), example => [ <<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">>, <<"ZZZZZZZZ-CCCC-BBBB-2022-DDDDEEEEFFF">> @@ -164,7 +164,7 @@ fields(telemetry) -> mk( array(binary()), #{ - desc => <<"EMQX Active Plugins">>, + desc => ?DESC(active_plugins), example => [<<"Plugin A">>, <<"Plugin B">>] } )}, @@ -172,7 +172,7 @@ fields(telemetry) -> mk( array(binary()), #{ - desc => <<"EMQX Active Modules">>, + desc => ?DESC(active_modules), example => [<<"Module A">>, <<"Module B">>] } )}, @@ -180,7 +180,7 @@ fields(telemetry) -> mk( integer(), #{ - desc => <<"EMQX Current Connections">>, + desc => ?DESC(num_clients), example => 20220113 } )}, @@ -188,7 +188,7 @@ fields(telemetry) -> mk( integer(), #{ - desc => <<"EMQX Current Received Message">>, + desc => ?DESC(messages_received), example => 2022 } )}, @@ -196,7 +196,7 @@ fields(telemetry) -> mk( integer(), #{ - desc => <<"EMQX Current Sent Message">>, + desc => ?DESC(messages_sent), example => 2022 } )} diff --git a/apps/emqx_modules/src/emqx_topic_metrics_api.erl b/apps/emqx_modules/src/emqx_topic_metrics_api.erl index 2b0e2f8f2..b216fe44b 100644 --- a/apps/emqx_modules/src/emqx_topic_metrics_api.erl +++ b/apps/emqx_modules/src/emqx_topic_metrics_api.erl @@ -18,6 +18,7 @@ -behaviour(minirest_api). +-include_lib("hocon/include/hoconsc.hrl"). -include_lib("typerefl/include/types.hrl"). -include("emqx_modules.hrl"). @@ -68,19 +69,19 @@ schema("/mqtt/topic_metrics") -> 'operationId' => topic_metrics, get => #{ - description => <<"List topic metrics">>, + description => ?DESC(get_topic_metrics_api), tags => ?API_TAG_MQTT, responses => #{ 200 => mk(array(hoconsc:ref(topic_metrics)), #{ - desc => <<"List all topic metrics">> + desc => ?DESC(get_topic_metrics_api) }) } }, put => #{ - description => <<"Reset topic metrics by topic name. Or reset all Topic Metrics">>, + description => ?DESC(reset_topic_metrics_api), tags => ?API_TAG_MQTT, 'requestBody' => emqx_dashboard_swagger:schema_with_examples( ref(reset), @@ -88,28 +89,28 @@ schema("/mqtt/topic_metrics") -> ), responses => #{ - 204 => <<"Reset topic metrics successfully">>, + 204 => ?DESC(reset_topic_metrics_api), 404 => emqx_dashboard_swagger:error_codes( - [?TOPIC_NOT_FOUND], <<"Topic not found">> + [?TOPIC_NOT_FOUND], ?DESC(topic_metrics_api_response404) ) } }, post => #{ - description => <<"Create topic metrics">>, + description => ?DESC(post_topic_metrics_api), tags => ?API_TAG_MQTT, 'requestBody' => [topic(body)], responses => #{ - 204 => <<"Create topic metrics success">>, + 204 => ?DESC(post_topic_metrics_api), 409 => emqx_dashboard_swagger:error_codes( [?EXCEED_LIMIT], - <<"Topic metrics exceeded max limit 512">> + ?DESC(topic_metrics_api_response409) ), 400 => emqx_dashboard_swagger:error_codes( [?BAD_REQUEST, ?BAD_TOPIC], - <<"Topic metrics already existed or bad topic">> + ?DESC(topic_metrics_api_response400) ) } } @@ -119,29 +120,29 @@ schema("/mqtt/topic_metrics/:topic") -> 'operationId' => operate_topic_metrics, get => #{ - description => <<"Get topic metrics">>, + description => ?DESC(gat_topic_metrics_data_api), tags => ?API_TAG_MQTT, parameters => [topic(path)], responses => #{ - 200 => mk(ref(topic_metrics), #{desc => <<"Topic metrics">>}), + 200 => mk(ref(topic_metrics), #{desc => ?DESC(topic)}), 404 => emqx_dashboard_swagger:error_codes( [?TOPIC_NOT_FOUND], - <<"Topic not found">> + ?DESC(topic_metrics_api_response404) ) } }, delete => #{ - description => <<"Remove the topic metrics">>, + description => ?DESC(delete_topic_metrics_data_api), tags => ?API_TAG_MQTT, parameters => [topic(path)], responses => #{ - 204 => <<"Removed topic metrics successfully">>, + 204 => ?DESC(delete_topic_metrics_data_api), 404 => emqx_dashboard_swagger:error_codes( [?TOPIC_NOT_FOUND], - <<"Topic not found">> + ?DESC(topic_metrics_api_response404) ) } } @@ -153,11 +154,7 @@ fields(reset) -> mk( binary(), #{ - desc => - << - "Topic Name. If this parameter is not present," - " all created topic metrics will be reset" - >>, + desc => ?DESC(reset_topic_desc), example => <<"testtopic/1">>, required => false } @@ -166,7 +163,7 @@ fields(reset) -> mk( string(), #{ - desc => <<"Action Name. Only as a \"reset\"">>, + desc => ?DESC(action), enum => [reset], required => true, example => <<"reset">> @@ -179,7 +176,7 @@ fields(topic_metrics) -> mk( binary(), #{ - desc => <<"Topic Name">>, + desc => ?DESC(topic), example => <<"testtopic/1">>, required => true } @@ -188,7 +185,7 @@ fields(topic_metrics) -> mk( emqx_datetime:epoch_second(), #{ - desc => <<"Topic Metrics created date time, in rfc3339">>, + desc => ?DESC(create_time), required => true, example => <<"2022-01-14T21:48:47+08:00">> } @@ -197,8 +194,7 @@ fields(topic_metrics) -> mk( emqx_datetime:epoch_second(), #{ - desc => - <<"Topic Metrics reset date time, in rfc3339. Nullable if never reset">>, + desc => ?DESC(reset_time), required => false, example => <<"2022-01-14T21:48:47+08:00">> } @@ -207,164 +203,51 @@ fields(topic_metrics) -> mk( ref(metrics), #{ - desc => <<"Topic Metrics fields">>, + desc => ?DESC(metrics), required => true } )} ]; fields(metrics) -> - [ - {'messages.dropped.count', - mk( - integer(), - #{ - desc => <<"Message dropped count">>, - example => 0 - } - )}, - {'messages.dropped.rate', - mk( - number(), - #{ - desc => <<"Message dropped rate in 5s">>, - example => 0 - } - )}, - {'messages.in.count', - mk( - integer(), - #{ - desc => <<"Message received count">>, - example => 0 - } - )}, - {'messages.in.rate', - mk( - number(), - #{ - desc => <<"Message received rate in 5s">>, - example => 0 - } - )}, - {'messages.out.count', - mk( - integer(), - #{ - desc => <<"Message sent count">>, - example => 0 - } - )}, - {'messages.out.rate', - mk( - number(), - #{ - desc => <<"Message sent rate in 5s">>, - example => 0 - } - )}, - {'messages.qos0.in.count', - mk( - integer(), - #{ - desc => <<"Message with QoS 0 received count">>, - example => 0 - } - )}, - {'messages.qos0.in.rate', - mk( - number(), - #{ - desc => <<"Message with QoS 0 received rate in 5s">>, - example => 0 - } - )}, - {'messages.qos0.out.count', - mk( - integer(), - #{ - desc => <<"Message with QoS 0 sent count">>, - example => 0 - } - )}, - {'messages.qos0.out.rate', - mk( - number(), - #{ - desc => <<"Message with QoS 0 sent rate in 5s">>, - example => 0 - } - )}, - {'messages.qos1.in.count', - mk( - integer(), - #{ - desc => <<"Message with QoS 1 received count">>, - example => 0 - } - )}, - {'messages.qos1.in.rate', - mk( - number(), - #{ - desc => <<"Message with QoS 1 received rate in 5s">>, - example => 0 - } - )}, - {'messages.qos1.out.count', - mk( - integer(), - #{ - desc => <<"Message with QoS 1 sent count">>, - example => 0 - } - )}, - {'messages.qos1.out.rate', - mk( - number(), - #{ - desc => <<"Message with QoS 1 sent rate in 5s">>, - example => 0 - } - )}, - {'messages.qos2.in.count', - mk( - integer(), - #{ - desc => <<"Message with QoS 2 sent count">>, - example => 0 - } - )}, - {'messages.qos2.in.rate', - mk( - number(), - #{ - desc => <<"Message with QoS 2 received rate in 5s">>, - example => 0 - } - )}, - {'messages.qos2.out.count', - mk( - integer(), - #{ - desc => <<"Message with QoS 2 sent count">>, - example => 0 - } - )}, - {'messages.qos2.out.rate', - mk( - number(), - #{ - desc => <<"Message with QoS 2 sent rate in 5s">>, - example => 0 - } - )} - ]. + Integers = [ + 'message.dropped.count', + 'message.in.count', + 'message.out.count', + 'message.qos0.in.count', + 'message.qos0.out.count', + 'message.qos1.in.count', + 'message.qos1.out.count', + 'message.qos2.in.count', + 'message.qos2.out.count' + ], + Numbers = [ + 'message.dropped.rate', + 'message.in.rate', + 'message.out.rate', + 'message.qos0.in.rate', + 'message.qos0.out.rate', + 'message.qos1.in.rate', + 'message.qos1.out.rate', + 'message.qos2.in.rate', + 'message.qos2.out.rate' + ], + ToDesc = + fun(Key) -> + %% message.dropped.rate -> message_dropped_rate + Str = string:replace(atom_to_binary(Key, utf8), ".", "_", all), + NKey = binary_to_atom(list_to_binary(Str), utf8), + ?DESC(NKey) + end, + [{Key, mk(integer(), #{desc => ToDesc(Key), example => 0})} || Key <- Integers] + ++ + [{Key, mk(number(), #{desc => ToDesc(Key), example => 0})} || Key <- Numbers]. + topic(In) -> Desc = case In of - body -> <<"Raw topic string">>; - path -> <<"Notice: Topic string in url path must be encoded">> + body -> ?DESC(topic_in_body); + path -> ?DESC(topic_in_path) end, {topic, mk(