Merge pull request #7724 from DDDHuang/tm_t_api_desc

fix: telemetry & topic metrics support i18n
This commit is contained in:
DDDHuang 2022-04-22 22:02:13 +08:00 committed by GitHub
commit 575d34cb69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 438 additions and 196 deletions

View File

@ -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: """获取发送的消息数量"""
}
}
}

View File

@ -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 发送消息速率"""
}
}
}

View File

@ -18,6 +18,7 @@
-behaviour(minirest_api). -behaviour(minirest_api).
-include_lib("hocon/include/hoconsc.hrl").
-include_lib("typerefl/include/types.hrl"). -include_lib("typerefl/include/types.hrl").
-import(hoconsc, [mk/2, ref/1, ref/2, array/1]). -import(hoconsc, [mk/2, ref/1, ref/2, array/1]).
@ -50,18 +51,17 @@ schema("/telemetry/status") ->
'operationId' => status, 'operationId' => status,
get => get =>
#{ #{
description => <<"Get telemetry status">>, description => ?DESC(get_telemetry_status_api),
responses => responses =>
#{200 => status_schema(<<"Get telemetry status">>)} #{200 => status_schema(?DESC(get_telemetry_status_api))}
}, },
put => put =>
#{ #{
description => <<"Enable or disable telemetry">>, description => ?DESC(update_telemetry_status_api),
'requestBody' => status_schema(<<"Enable or disable telemetry">>), 'requestBody' => status_schema(?DESC(update_telemetry_status_api)),
responses => responses =>
#{ #{
200 => status_schema(<<"Enable or disable telemetry successfully">>), 200 => status_schema(?DESC(update_telemetry_status_api))
400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad Request">>)
} }
} }
}; };
@ -70,9 +70,9 @@ schema("/telemetry/data") ->
'operationId' => data, 'operationId' => data,
get => get =>
#{ #{
description => <<"Get telemetry data">>, description => ?DESC(get_telemetry_data_api),
responses => 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( mk(
boolean(), boolean(),
#{ #{
desc => <<"Telemetry status">>, desc => ?DESC(enable),
default => true, default => true,
example => false example => false
} }
@ -97,7 +97,7 @@ fields(telemetry) ->
mk( mk(
string(), string(),
#{ #{
desc => <<"EMQX Version">>, desc => ?DESC(emqx_version),
example => <<"5.0.0-beta.3-32d1547c">> example => <<"5.0.0-beta.3-32d1547c">>
} }
)}, )},
@ -105,7 +105,7 @@ fields(telemetry) ->
mk( mk(
map(), map(),
#{ #{
desc => <<"EMQX License">>, desc => ?DESC(license),
example => #{edition => <<"community">>} example => #{edition => <<"community">>}
} }
)}, )},
@ -113,7 +113,7 @@ fields(telemetry) ->
mk( mk(
string(), string(),
#{ #{
desc => <<"OS Name">>, desc => ?DESC(os_name),
example => <<"Linux">> example => <<"Linux">>
} }
)}, )},
@ -121,7 +121,7 @@ fields(telemetry) ->
mk( mk(
string(), string(),
#{ #{
desc => <<"OS Version">>, desc => ?DESC(os_version),
example => <<"20.04">> example => <<"20.04">>
} }
)}, )},
@ -129,7 +129,7 @@ fields(telemetry) ->
mk( mk(
string(), string(),
#{ #{
desc => <<"Erlang/OTP Version">>, desc => ?DESC(otp_version),
example => <<"24">> example => <<"24">>
} }
)}, )},
@ -137,7 +137,7 @@ fields(telemetry) ->
mk( mk(
integer(), integer(),
#{ #{
desc => <<"EMQX Runtime">>, desc => ?DESC(up_time),
example => 20220113 example => 20220113
} }
)}, )},
@ -145,7 +145,7 @@ fields(telemetry) ->
mk( mk(
string(), string(),
#{ #{
desc => <<"EMQX UUID">>, desc => ?DESC(uuid),
example => <<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">> example => <<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">>
} }
)}, )},
@ -153,7 +153,7 @@ fields(telemetry) ->
mk( mk(
array(binary()), array(binary()),
#{ #{
desc => <<"EMQX Cluster Nodes UUID">>, desc => ?DESC(nodes_uuid),
example => [ example => [
<<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">>, <<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">>,
<<"ZZZZZZZZ-CCCC-BBBB-2022-DDDDEEEEFFF">> <<"ZZZZZZZZ-CCCC-BBBB-2022-DDDDEEEEFFF">>
@ -164,7 +164,7 @@ fields(telemetry) ->
mk( mk(
array(binary()), array(binary()),
#{ #{
desc => <<"EMQX Active Plugins">>, desc => ?DESC(active_plugins),
example => [<<"Plugin A">>, <<"Plugin B">>] example => [<<"Plugin A">>, <<"Plugin B">>]
} }
)}, )},
@ -172,7 +172,7 @@ fields(telemetry) ->
mk( mk(
array(binary()), array(binary()),
#{ #{
desc => <<"EMQX Active Modules">>, desc => ?DESC(active_modules),
example => [<<"Module A">>, <<"Module B">>] example => [<<"Module A">>, <<"Module B">>]
} }
)}, )},
@ -180,7 +180,7 @@ fields(telemetry) ->
mk( mk(
integer(), integer(),
#{ #{
desc => <<"EMQX Current Connections">>, desc => ?DESC(num_clients),
example => 20220113 example => 20220113
} }
)}, )},
@ -188,7 +188,7 @@ fields(telemetry) ->
mk( mk(
integer(), integer(),
#{ #{
desc => <<"EMQX Current Received Message">>, desc => ?DESC(messages_received),
example => 2022 example => 2022
} }
)}, )},
@ -196,7 +196,7 @@ fields(telemetry) ->
mk( mk(
integer(), integer(),
#{ #{
desc => <<"EMQX Current Sent Message">>, desc => ?DESC(messages_sent),
example => 2022 example => 2022
} }
)} )}

View File

@ -18,6 +18,7 @@
-behaviour(minirest_api). -behaviour(minirest_api).
-include_lib("hocon/include/hoconsc.hrl").
-include_lib("typerefl/include/types.hrl"). -include_lib("typerefl/include/types.hrl").
-include("emqx_modules.hrl"). -include("emqx_modules.hrl").
@ -68,19 +69,19 @@ schema("/mqtt/topic_metrics") ->
'operationId' => topic_metrics, 'operationId' => topic_metrics,
get => get =>
#{ #{
description => <<"List topic metrics">>, description => ?DESC(get_topic_metrics_api),
tags => ?API_TAG_MQTT, tags => ?API_TAG_MQTT,
responses => responses =>
#{ #{
200 => 200 =>
mk(array(hoconsc:ref(topic_metrics)), #{ mk(array(hoconsc:ref(topic_metrics)), #{
desc => <<"List all topic metrics">> desc => ?DESC(get_topic_metrics_api)
}) })
} }
}, },
put => put =>
#{ #{
description => <<"Reset topic metrics by topic name. Or reset all Topic Metrics">>, description => ?DESC(reset_topic_metrics_api),
tags => ?API_TAG_MQTT, tags => ?API_TAG_MQTT,
'requestBody' => emqx_dashboard_swagger:schema_with_examples( 'requestBody' => emqx_dashboard_swagger:schema_with_examples(
ref(reset), ref(reset),
@ -88,28 +89,28 @@ schema("/mqtt/topic_metrics") ->
), ),
responses => responses =>
#{ #{
204 => <<"Reset topic metrics successfully">>, 204 => ?DESC(reset_topic_metrics_api),
404 => 404 =>
emqx_dashboard_swagger:error_codes( emqx_dashboard_swagger:error_codes(
[?TOPIC_NOT_FOUND], <<"Topic not found">> [?TOPIC_NOT_FOUND], ?DESC(topic_metrics_api_response404)
) )
} }
}, },
post => post =>
#{ #{
description => <<"Create topic metrics">>, description => ?DESC(post_topic_metrics_api),
tags => ?API_TAG_MQTT, tags => ?API_TAG_MQTT,
'requestBody' => [topic(body)], 'requestBody' => [topic(body)],
responses => responses =>
#{ #{
204 => <<"Create topic metrics success">>, 204 => ?DESC(post_topic_metrics_api),
409 => emqx_dashboard_swagger:error_codes( 409 => emqx_dashboard_swagger:error_codes(
[?EXCEED_LIMIT], [?EXCEED_LIMIT],
<<"Topic metrics exceeded max limit 512">> ?DESC(topic_metrics_api_response409)
), ),
400 => emqx_dashboard_swagger:error_codes( 400 => emqx_dashboard_swagger:error_codes(
[?BAD_REQUEST, ?BAD_TOPIC], [?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, 'operationId' => operate_topic_metrics,
get => get =>
#{ #{
description => <<"Get topic metrics">>, description => ?DESC(gat_topic_metrics_data_api),
tags => ?API_TAG_MQTT, tags => ?API_TAG_MQTT,
parameters => [topic(path)], parameters => [topic(path)],
responses => responses =>
#{ #{
200 => mk(ref(topic_metrics), #{desc => <<"Topic metrics">>}), 200 => mk(ref(topic_metrics), #{desc => ?DESC(topic)}),
404 => emqx_dashboard_swagger:error_codes( 404 => emqx_dashboard_swagger:error_codes(
[?TOPIC_NOT_FOUND], [?TOPIC_NOT_FOUND],
<<"Topic not found">> ?DESC(topic_metrics_api_response404)
) )
} }
}, },
delete => delete =>
#{ #{
description => <<"Remove the topic metrics">>, description => ?DESC(delete_topic_metrics_data_api),
tags => ?API_TAG_MQTT, tags => ?API_TAG_MQTT,
parameters => [topic(path)], parameters => [topic(path)],
responses => responses =>
#{ #{
204 => <<"Removed topic metrics successfully">>, 204 => ?DESC(delete_topic_metrics_data_api),
404 => emqx_dashboard_swagger:error_codes( 404 => emqx_dashboard_swagger:error_codes(
[?TOPIC_NOT_FOUND], [?TOPIC_NOT_FOUND],
<<"Topic not found">> ?DESC(topic_metrics_api_response404)
) )
} }
} }
@ -153,11 +154,7 @@ fields(reset) ->
mk( mk(
binary(), binary(),
#{ #{
desc => desc => ?DESC(reset_topic_desc),
<<
"Topic Name. If this parameter is not present,"
" all created topic metrics will be reset"
>>,
example => <<"testtopic/1">>, example => <<"testtopic/1">>,
required => false required => false
} }
@ -166,7 +163,7 @@ fields(reset) ->
mk( mk(
string(), string(),
#{ #{
desc => <<"Action Name. Only as a \"reset\"">>, desc => ?DESC(action),
enum => [reset], enum => [reset],
required => true, required => true,
example => <<"reset">> example => <<"reset">>
@ -179,7 +176,7 @@ fields(topic_metrics) ->
mk( mk(
binary(), binary(),
#{ #{
desc => <<"Topic Name">>, desc => ?DESC(topic),
example => <<"testtopic/1">>, example => <<"testtopic/1">>,
required => true required => true
} }
@ -188,7 +185,7 @@ fields(topic_metrics) ->
mk( mk(
emqx_datetime:epoch_second(), emqx_datetime:epoch_second(),
#{ #{
desc => <<"Topic Metrics created date time, in rfc3339">>, desc => ?DESC(create_time),
required => true, required => true,
example => <<"2022-01-14T21:48:47+08:00">> example => <<"2022-01-14T21:48:47+08:00">>
} }
@ -197,8 +194,7 @@ fields(topic_metrics) ->
mk( mk(
emqx_datetime:epoch_second(), emqx_datetime:epoch_second(),
#{ #{
desc => desc => ?DESC(reset_time),
<<"Topic Metrics reset date time, in rfc3339. Nullable if never reset">>,
required => false, required => false,
example => <<"2022-01-14T21:48:47+08:00">> example => <<"2022-01-14T21:48:47+08:00">>
} }
@ -207,164 +203,51 @@ fields(topic_metrics) ->
mk( mk(
ref(metrics), ref(metrics),
#{ #{
desc => <<"Topic Metrics fields">>, desc => ?DESC(metrics),
required => true required => true
} }
)} )}
]; ];
fields(metrics) -> fields(metrics) ->
[ Integers = [
{'messages.dropped.count', 'message.dropped.count',
mk( 'message.in.count',
integer(), 'message.out.count',
#{ 'message.qos0.in.count',
desc => <<"Message dropped count">>, 'message.qos0.out.count',
example => 0 'message.qos1.in.count',
} 'message.qos1.out.count',
)}, 'message.qos2.in.count',
{'messages.dropped.rate', 'message.qos2.out.count'
mk( ],
number(), Numbers = [
#{ 'message.dropped.rate',
desc => <<"Message dropped rate in 5s">>, 'message.in.rate',
example => 0 'message.out.rate',
} 'message.qos0.in.rate',
)}, 'message.qos0.out.rate',
{'messages.in.count', 'message.qos1.in.rate',
mk( 'message.qos1.out.rate',
integer(), 'message.qos2.in.rate',
#{ 'message.qos2.out.rate'
desc => <<"Message received count">>, ],
example => 0 ToDesc =
} fun(Key) ->
)}, %% message.dropped.rate -> message_dropped_rate
{'messages.in.rate', Str = string:replace(atom_to_binary(Key, utf8), ".", "_", all),
mk( NKey = binary_to_atom(list_to_binary(Str), utf8),
number(), ?DESC(NKey)
#{ end,
desc => <<"Message received rate in 5s">>, [{Key, mk(integer(), #{desc => ToDesc(Key), example => 0})} || Key <- Integers]
example => 0 ++
} [{Key, mk(number(), #{desc => ToDesc(Key), example => 0})} || Key <- Numbers].
)},
{'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
}
)}
].
topic(In) -> topic(In) ->
Desc = Desc =
case In of case In of
body -> <<"Raw topic string">>; body -> ?DESC(topic_in_body);
path -> <<"Notice: Topic string in url path must be encoded">> path -> ?DESC(topic_in_path)
end, end,
{topic, {topic,
mk( mk(