From c6b0e8806f8648db5ccc7157ba8bd102be386051 Mon Sep 17 00:00:00 2001 From: ieQu1 <99872536+ieQu1@users.noreply.github.com> Date: Tue, 22 Mar 2022 15:23:48 +0100 Subject: [PATCH] docs(schema): Add descriptions to the schema --- apps/emqx/etc/emqx.conf | 4 +- .../emqx_limiter/src/emqx_limiter_schema.erl | 6 +- apps/emqx/src/emqx_schema.erl | 321 +++++++++++++++--- .../src/emqx_dashboard_schema.erl | 40 ++- apps/emqx_modules/src/emqx_modules_schema.erl | 21 +- 5 files changed, 312 insertions(+), 80 deletions(-) diff --git a/apps/emqx/etc/emqx.conf b/apps/emqx/etc/emqx.conf index e6249a039..286be934f 100644 --- a/apps/emqx/etc/emqx.conf +++ b/apps/emqx/etc/emqx.conf @@ -1016,7 +1016,7 @@ broker { ## - local: only lock the session locally on the current node ## - one: select only one remove node to lock the session ## - quorum: select some nodes to lock the session - ## - all: lock the session on all of the nodes in the cluster + ## - all: lock the session on all the nodes in the cluster ## Default: quorum session_locking_strategy = quorum @@ -1027,7 +1027,7 @@ broker { ## - random: dispatch the message to a random selected subscriber ## - round_robin: select the subscribers in a round-robin manner ## - sticky: always use the last selected subscriber to dispatch, - ## until the susbcriber disconnected. + ## until the subscriber disconnected. ## - hash: select the subscribers by the hash of clientIds ## Default: round_robin shared_subscription_strategy = round_robin diff --git a/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl b/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl index f4c403b56..8421a7399 100644 --- a/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl +++ b/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl @@ -107,8 +107,8 @@ fields(limiter_opts) -> [ {rate, sc(rate(), #{default => "infinity", desc => "The rate"})} , {burst, sc(burst_rate(), #{default => "0/0s", - desc => "The burst, This value is based on rate." - " This value + rate = the maximum limit that can be achieved when limiter burst" + desc => "The burst, This value is based on rate.
+ This value + rate = the maximum limit that can be achieved when limiter burst." })} , {bucket, sc(map("bucket name", ref(bucket_opts)), #{desc => "Buckets config"})} ]; @@ -121,7 +121,7 @@ fields(bucket_opts) -> , {per_client, sc(ref(client_bucket), #{default => #{}, desc => "The rate limit for each user of the bucket," - "this field is not required" + " this field is not required" })} ]; diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 022ab3664..b54ff2356 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -936,7 +936,12 @@ fields("ws_opts") -> {"mqtt_path", sc( string(), - #{default => "/mqtt"} + #{ + default => "/mqtt", + desc => + "WebSocket's MQTT protocol path. So the address of\n" + " EMQX Broker's WebSocket is: ws://{ip}:{port}/mqtt" + } )}, {"mqtt_piggyback", sc( @@ -946,52 +951,99 @@ fields("ws_opts") -> {"compress", sc( boolean(), - #{default => false} + #{ + default => false, + desc => + "If true, compress WebSocket messages using zlib.
\n" + " The configuration items under deflate_opts belong to the compression-related parameter configuration." + } )}, {"idle_timeout", sc( duration(), - #{default => "15s"} + #{ + default => "15s", + desc => + "The idle time after the TCP connection is established
\n" + " If no packets are received within this time, the connection will be closed." + } )}, {"max_frame_size", sc( hoconsc:union([infinity, integer()]), - #{default => infinity} + #{ + default => infinity, + desc => "The maximum length of a single MQTT packet." + } )}, {"fail_if_no_subprotocol", sc( boolean(), - #{default => true} + #{ + default => true, + desc => + "If true, the server will return an error when\n" + " the client does not carry the Sec-WebSocket-Protocol field.\n" + "
Note: WeChat applet needs to disable this verification." + } )}, {"supported_subprotocols", sc( comma_separated_list(), - #{default => "mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5"} + #{ + default => "mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5", + desc => "Comma-separated list of supported subprotocols." + } )}, {"check_origin_enable", sc( boolean(), - #{default => false} + #{ + default => false, + desc => + "If true, origin HTTP header will be\n" + " validated against the list of allowed origins configured in check_origins\n" + " parameter." + } )}, {"allow_origin_absence", sc( boolean(), - #{default => true} + #{ + default => true, + desc => + "If false and check_origin_enable is\n" + " true, the server will reject requests that don't have origin\n" + " HTTP header." + } )}, {"check_origins", sc( hoconsc:array(binary()), - #{default => []} + #{ + default => [], + desc => "List of allowed origins.
See check_origin_enable." + } )}, {"proxy_address_header", sc( string(), - #{default => "x-forwarded-for"} + #{ + default => "x-forwarded-for", + desc => + "HTTP header used to pass information about the client IP address.\n" + " Relevant when the EMQX cluster is deployed behind a load-balancer." + } )}, {"proxy_port_header", sc( string(), - #{default => "x-forwarded-port"} + #{ + default => "x-forwarded-port", + desc => + "HTTP header used to pass information about the client port.\n" + " Relevant when the EMQX cluster is deployed behind a load-balancer." + } )}, {"deflate_opts", sc( @@ -1004,52 +1056,79 @@ fields("tcp_opts") -> {"active_n", sc( integer(), - #{default => 100} + #{ + default => 100, + desc => + "Specify the {active, N} option for this Socket.
\n" + " See: https://erlang.org/doc/man/inet.html#setopts-2" + } )}, {"backlog", sc( integer(), - #{default => 1024} + #{ + default => 1024, + desc => + "TCP backlog defines the maximum length that the queue of\n" + " pending connections can grow to." + } )}, {"send_timeout", sc( duration(), - #{default => "15s"} + #{ + default => "15s", + desc => "The TCP send timeout for the connections." + } )}, {"send_timeout_close", sc( boolean(), - #{default => true} + #{ + default => true, + desc => "Close the connection if send timeout." + } )}, {"recbuf", sc( bytesize(), - #{} + #{desc => "The TCP receive buffer (OS kernel) for the connections."} )}, {"sndbuf", sc( bytesize(), - #{} + #{desc => "The TCP send buffer (OS kernel) for the connections."} )}, {"buffer", sc( bytesize(), - #{} + #{desc => "The size of the user-space buffer used by the driver."} )}, {"high_watermark", sc( bytesize(), - #{default => "1MB"} + #{ + default => "1MB", + desc => + "The socket is set to a busy state when the amount of data queued internally\n" + " by the VM socket implementation reaches this limit." + } )}, {"nodelay", sc( boolean(), - #{default => false} + #{ + default => false, + desc => "The TCP_NODELAY flag for the connections." + } )}, {"reuseaddr", sc( boolean(), - #{default => true} + #{ + default => true, + desc => "The SO_REUSEADDR flag for the connections." + } )} ]; fields("listener_ssl_opts") -> @@ -1079,37 +1158,56 @@ fields("deflate_opts") -> {"level", sc( hoconsc:enum([none, default, best_compression, best_speed]), - #{} + #{desc => "Compression level."} )}, {"mem_level", sc( range(1, 9), - #{default => 8} + #{ + default => 8, + desc => + "Specifies the size of the compression state.
\n" + " Lower values decrease memory usage per connection." + } )}, {"strategy", sc( hoconsc:enum([default, filtered, huffman_only, rle]), - #{} + #{desc => "Specifies the compression strategy."} )}, {"server_context_takeover", sc( hoconsc:enum([takeover, no_takeover]), - #{} + #{ + desc => + "Takeover means the compression state is retained\n" + " between server messages." + } )}, {"client_context_takeover", sc( hoconsc:enum([takeover, no_takeover]), - #{} + #{ + desc => + "Takeover means the compression state is retained\n" + " between client messages." + } )}, {"server_max_window_bits", sc( range(8, 15), - #{default => 15} + #{ + default => 15, + desc => "Specifies the size of the compression context for the server." + } )}, {"client_max_window_bits", sc( range(8, 15), - #{default => 15} + #{ + default => 15, + desc => "Specifies the size of the compression context for the client." + } )} ]; fields("broker") -> @@ -1117,27 +1215,57 @@ fields("broker") -> {"enable_session_registry", sc( boolean(), - #{default => true} + #{ + default => true, + desc => "Enable session registry" + } )}, {"session_locking_strategy", sc( hoconsc:enum([local, leader, quorum, all]), - #{default => quorum} + #{ + default => quorum, + desc => + "Session locking strategy in a cluster.
\n" + " - `local`: only lock the session on the current node\n" + " - `one`: select only one remove node to lock the session\n" + " - `quorum`: select some nodes to lock the session\n" + " - `all`: lock the session on all the nodes in the cluster" + } )}, {"shared_subscription_strategy", sc( hoconsc:enum([random, round_robin, sticky, hash_topic, hash_clientid]), - #{default => round_robin} + #{ + default => round_robin, + desc => + "Dispatch strategy for shared subscription.
\n" + " - `random`: dispatch the message to a random selected subscriber\n" + " - `round_robin`: select the subscribers in a round-robin manner\n" + " - `sticky`: always use the last selected subscriber to dispatch,\n" + " until the subscriber disconnected.\n" + " - `hash`: select the subscribers by the hash of `clientIds`" + } )}, {"shared_dispatch_ack_enabled", sc( boolean(), - #{default => false} + #{ + default => false, + desc => + "Enable/disable shared dispatch acknowledgement for QoS1 and QoS2 messages.
\n" + " This should allow messages to be dispatched to a different subscriber in\n" + " the group in case the picked (based on `shared_subscription_strategy`) subscriber\n" + " is offline." + } )}, {"route_batch_clean", sc( boolean(), - #{default => true} + #{ + default => true, + desc => "Enable batch clean for deleted routes." + } )}, {"perf", sc( @@ -1248,42 +1376,74 @@ fields("sysmon_vm") -> {"process_check_interval", sc( duration(), - #{default => "30s"} + #{ + default => "30s", + desc => "The time interval for the periodic process limit check." + } )}, {"process_high_watermark", sc( percent(), - #{default => "80%"} + #{ + default => "80%", + desc => + "The threshold, as percentage of processes, for how many\n" + " processes can simultaneously exist at the local node before the corresponding\n" + " alarm is set." + } )}, {"process_low_watermark", sc( percent(), - #{default => "60%"} + #{ + default => "60%", + desc => + "The threshold, as percentage of processes, for how many\n" + " processes can simultaneously exist at the local node before the corresponding\n" + " alarm is cleared." + } )}, {"long_gc", sc( hoconsc:union([disabled, duration()]), - #{} + #{ + desc => + "Enable Long GC monitoring.
\n" + " Notice: don't enable the monitor in production for:
\n" + " https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421" + } )}, {"long_schedule", sc( hoconsc:union([disabled, duration()]), - #{default => "240ms"} + #{ + default => "240ms", + desc => "Enable Long Schedule(ms) monitoring." + } )}, {"large_heap", sc( hoconsc:union([disabled, bytesize()]), - #{default => "32MB"} + #{ + default => "32MB", + desc => "Enable Large Heap monitoring." + } )}, {"busy_dist_port", sc( boolean(), - #{default => true} + #{ + default => true, + desc => "Enable Busy Distribution Port monitoring." + } )}, {"busy_port", sc( boolean(), - #{default => true} + #{ + default => true, + desc => "Enable Busy Port monitoring." + } )} ]; fields("sysmon_os") -> @@ -1291,32 +1451,59 @@ fields("sysmon_os") -> {"cpu_check_interval", sc( duration(), - #{default => "60s"} + #{ + default => "60s", + desc => "The time interval for the periodic CPU check." + } )}, {"cpu_high_watermark", sc( percent(), - #{default => "80%"} + #{ + default => "80%", + desc => + "The threshold, as percentage of system CPU load,\n" + " for how much system cpu can be used before the corresponding alarm is set." + } )}, {"cpu_low_watermark", sc( percent(), - #{default => "60%"} + #{ + default => "60%", + desc => + "The threshold, as percentage of system CPU load,\n" + " for how much system cpu can be used before the corresponding alarm is cleared." + } )}, {"mem_check_interval", sc( hoconsc:union([disabled, duration()]), - #{default => "60s"} + #{ + default => "60s", + desc => "The time interval for the periodic memory check." + } )}, {"sysmem_high_watermark", sc( percent(), - #{default => "70%"} + #{ + default => "70%", + desc => + "The threshold, as percentage of system memory,\n" + " for how much system memory can be allocated before the corresponding alarm is set." + } )}, {"procmem_high_watermark", sc( percent(), - #{default => "5%"} + #{ + default => "5%", + desc => + "The threshold, as percentage of system memory,\n" + " for how much system memory can be allocated by one Erlang process before\n" + " the corresponding alarm is set." + } )} ]; fields("sysmon_top") -> @@ -1488,27 +1675,57 @@ base_listener() -> {"bind", sc( hoconsc:union([ip_port(), integer()]), - #{required => true} + #{ + required => true, + desc => "IP address and port for the listening socket." + } )}, {"acceptors", sc( integer(), - #{default => 16} + #{ + default => 16, + desc => "The size of the listener's receiving pool." + } )}, {"max_connections", sc( hoconsc:union([infinity, integer()]), - #{default => infinity} + #{ + default => infinity, + desc => "The maximum number of concurrent connections allowed by the listener." + } )}, {"mountpoint", sc( binary(), - #{default => <<>>} + #{ + default => <<>>, + desc => + "When publishing or subscribing, prefix all topics with a mountpoint string.\n" + " The prefixed string will be removed from the topic name when the message\n" + " is delivered to the subscriber. The mountpoint is a way that users can use\n" + " to implement isolation of message routing between different listeners.\n" + " For example if a client A subscribes to `t` with `listeners.tcp..mountpoint`\n" + " set to `some_tenant`, then the client actually subscribes to the topic\n" + " `some_tenant/t`. Similarly, if another client B (connected to the same listener\n" + " as the client A) sends a message to topic `t`, the message is routed\n" + " to all the clients subscribed `some_tenant/t`, so client A will receive the\n" + " message, with topic name `t`.
\n" + " Set to `\"\"` to disable the feature.
\n" + "\n" + " Variables in mountpoint string:\n" + " - ${clientid}: clientid\n" + " - ${username}: username" + } )}, {"zone", sc( atom(), - #{default => 'default'} + #{ + default => 'default', + desc => "The configuration zone to which the listener belongs." + } )}, {"limiter", sc(map("ratelimit's type", emqx_limiter_schema:bucket_name()), #{default => #{}})} diff --git a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl index f112fc852..a2c5b3c26 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl @@ -49,22 +49,39 @@ fields("http") -> hoconsc:enum([http, https]), #{ desc => "HTTP/HTTPS protocol." , required => true - , default => http})} + , default => http + })} , {"bind", fun bind/1} , {"num_acceptors", sc( integer(), #{ default => 4 - , desc => "Socket acceptor pool for TCP protocols." + , desc => "Socket acceptor pool size for TCP protocols." })} - , {"max_connections", sc(integer(), #{default => 512})} - , {"backlog", sc( - integer(), - #{ default => 1024 - , desc => "Defines the maximum length that the queue of pending connections can grow to." - })} - , {"send_timeout", sc(emqx_schema:duration(), #{default => "5s"})} - , {"inet6", sc(boolean(), #{default => false})} - , {"ipv6_v6only", sc(boolean(), #{default => false})} + , {"max_connections", + sc(integer(), + #{ default => 512 + , desc => "Maximum number of simultaneous connections." + })} + , {"backlog", + sc(integer(), + #{ default => 1024 + , desc => "Defines the maximum length that the queue of pending connections can grow to." + })} + , {"send_timeout", + sc(emqx_schema:duration(), + #{ default => "5s" + , desc => "Send timeout for the socket." + })} + , {"inet6", + sc(boolean(), + #{ default => false + , desc => "Sets up the listener for IPv6." + })} + , {"ipv6_v6only", + sc(boolean(), + #{ default => false + , desc => "Disable IPv4-to-IPv6 mapping for the listener." + })} ]; fields("https") -> @@ -81,6 +98,7 @@ bind(_) -> undefined. default_username(type) -> string(); default_username(default) -> "admin"; default_username(required) -> true; +default_username(desc) -> "The default username of the automatically created dashboard user."; default_username(_) -> undefined. default_password(type) -> string(); diff --git a/apps/emqx_modules/src/emqx_modules_schema.erl b/apps/emqx_modules/src/emqx_modules_schema.erl index 58272a54a..90dc85088 100644 --- a/apps/emqx_modules/src/emqx_modules_schema.erl +++ b/apps/emqx_modules/src/emqx_modules_schema.erl @@ -123,18 +123,15 @@ fields("event_message") -> } )} ], - #{ - fields => Fields, - desc => - "" - "\n" - "Enable/Disable system event messages.\n" - "The messages are published to '$event' prefixed topics.\n" - "For example, if `client_disconnected` is set to `true`,\n" - "a message is published to `$event/client_connected` topic\n" - "whenever a client is connected.\n" - "" - }; + #{fields => Fields, + desc => """ +Enable/Disable system event messages. +The messages are published to $event prefixed topics. +For example, if `client_disconnected` is set to `true`, +a message is published to $event/client_connected topic +whenever a client is connected. +"""}; + fields("topic_metrics") -> [{topic, sc(binary(), #{})}].