Merge pull request #7382 from ieQu1/doc-schema-2
docs: Add definitions to the schema
This commit is contained in:
commit
b163fce35b
|
@ -218,7 +218,7 @@ jobs:
|
||||||
- emqx
|
- emqx
|
||||||
- emqx-enterprise
|
- emqx-enterprise
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container: "ghcr.io/iequ1/emqx-schema-validate:0.2.2"
|
container: "ghcr.io/iequ1/emqx-schema-validate:0.2.3"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v2
|
- uses: actions/download-artifact@v2
|
||||||
name: Download schema dump
|
name: Download schema dump
|
||||||
|
|
|
@ -659,22 +659,40 @@ fields("flapping_detect") ->
|
||||||
{"enable",
|
{"enable",
|
||||||
sc(
|
sc(
|
||||||
boolean(),
|
boolean(),
|
||||||
#{default => false}
|
#{
|
||||||
|
default => false,
|
||||||
|
desc =>
|
||||||
|
"Enable flapping connection detection feature.<br/>\n"
|
||||||
|
"This config controls the allowed maximum number of `CONNECT` packets received\n"
|
||||||
|
"from the same clientid in a time frame defined by `window_time`.\n"
|
||||||
|
"After the limit is reached, successive `CONNECT` requests are forbidden\n"
|
||||||
|
"(banned) until the end of the time period defined by `ban_time`."
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"max_count",
|
{"max_count",
|
||||||
sc(
|
sc(
|
||||||
integer(),
|
integer(),
|
||||||
#{default => 15}
|
#{
|
||||||
|
default => 15,
|
||||||
|
desc =>
|
||||||
|
"The maximum number of disconnects allowed for a MQTT Client in `window_time`"
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"window_time",
|
{"window_time",
|
||||||
sc(
|
sc(
|
||||||
duration(),
|
duration(),
|
||||||
#{default => "1m"}
|
#{
|
||||||
|
default => "1m",
|
||||||
|
desc => "The time window for flapping detection."
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"ban_time",
|
{"ban_time",
|
||||||
sc(
|
sc(
|
||||||
duration(),
|
duration(),
|
||||||
#{default => "5m"}
|
#{
|
||||||
|
default => "5m",
|
||||||
|
desc => "How long the flapping clientid will be banned."
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
fields("force_shutdown") ->
|
fields("force_shutdown") ->
|
||||||
|
@ -682,18 +700,25 @@ fields("force_shutdown") ->
|
||||||
{"enable",
|
{"enable",
|
||||||
sc(
|
sc(
|
||||||
boolean(),
|
boolean(),
|
||||||
#{default => true}
|
#{
|
||||||
|
default => true,
|
||||||
|
desc => "Enable `force_shutdown` feature."
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"max_message_queue_len",
|
{"max_message_queue_len",
|
||||||
sc(
|
sc(
|
||||||
range(0, inf),
|
range(0, inf),
|
||||||
#{default => 1000}
|
#{
|
||||||
|
default => 1000,
|
||||||
|
desc => "Maximum message queue length."
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"max_heap_size",
|
{"max_heap_size",
|
||||||
sc(
|
sc(
|
||||||
wordsize(),
|
wordsize(),
|
||||||
#{
|
#{
|
||||||
default => "32MB",
|
default => "32MB",
|
||||||
|
desc => "Total heap size",
|
||||||
validator => fun ?MODULE:validate_heap_size/1
|
validator => fun ?MODULE:validate_heap_size/1
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
|
@ -1288,22 +1313,34 @@ fields("event_names") ->
|
||||||
{"client_connected",
|
{"client_connected",
|
||||||
sc(
|
sc(
|
||||||
boolean(),
|
boolean(),
|
||||||
#{default => true}
|
#{
|
||||||
|
default => true,
|
||||||
|
desc => "Connection complete"
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"client_disconnected",
|
{"client_disconnected",
|
||||||
sc(
|
sc(
|
||||||
boolean(),
|
boolean(),
|
||||||
#{default => true}
|
#{
|
||||||
|
default => true,
|
||||||
|
desc => "Disconnect"
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"client_subscribed",
|
{"client_subscribed",
|
||||||
sc(
|
sc(
|
||||||
boolean(),
|
boolean(),
|
||||||
#{default => false}
|
#{
|
||||||
|
default => false,
|
||||||
|
desc => "Subscribe"
|
||||||
|
}
|
||||||
)},
|
)},
|
||||||
{"client_unsubscribed",
|
{"client_unsubscribed",
|
||||||
sc(
|
sc(
|
||||||
boolean(),
|
boolean(),
|
||||||
#{default => false}
|
#{
|
||||||
|
default => false,
|
||||||
|
desc => "Unsubscribe"
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
fields("sysmon") ->
|
fields("sysmon") ->
|
||||||
|
@ -1589,10 +1626,8 @@ fields("alarm") ->
|
||||||
default => "24h",
|
default => "24h",
|
||||||
example => "24h",
|
example => "24h",
|
||||||
desc =>
|
desc =>
|
||||||
""
|
|
||||||
"Retention time of deactivated alarms. Alarms are not deleted immediately\n"
|
"Retention time of deactivated alarms. Alarms are not deleted immediately\n"
|
||||||
"when deactivated, but after the retention time.\n"
|
"when deactivated, but after the retention time.\n"
|
||||||
""
|
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
|
@ -1757,7 +1792,7 @@ common_ssl_opts_schema(Defaults) ->
|
||||||
"issue chain. That is, the host's certificate should be placed in the beginning\n"
|
"issue chain. That is, the host's certificate should be placed in the beginning\n"
|
||||||
"of the file, followed by the immediate issuer certificate and so on.\n"
|
"of the file, followed by the immediate issuer certificate and so on.\n"
|
||||||
"Although the root CA certificate is optional, it should be placed at the end of\n"
|
"Although the root CA certificate is optional, it should be placed at the end of\n"
|
||||||
"the file if it is to be added.\n"
|
"the file if it is to be added."
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
{"keyfile",
|
{"keyfile",
|
||||||
|
@ -1767,7 +1802,7 @@ common_ssl_opts_schema(Defaults) ->
|
||||||
default => D("keyfile"),
|
default => D("keyfile"),
|
||||||
required => false,
|
required => false,
|
||||||
desc =>
|
desc =>
|
||||||
"PEM format private key file.<br>\n"
|
"PEM format private key file."
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
{"verify",
|
{"verify",
|
||||||
|
@ -1805,7 +1840,7 @@ common_ssl_opts_schema(Defaults) ->
|
||||||
"All TLS/DTLS versions to be supported.<br>\n"
|
"All TLS/DTLS versions to be supported.<br>\n"
|
||||||
"NOTE: PSK ciphers are suppressed by 'tlsv1.3' version config<br>\n"
|
"NOTE: PSK ciphers are suppressed by 'tlsv1.3' version config<br>\n"
|
||||||
"In case PSK cipher suites are intended, make sure to configured\n"
|
"In case PSK cipher suites are intended, make sure to configured\n"
|
||||||
"<code>['tlsv1.2', 'tlsv1.1']</code> here.\n",
|
"<code>['tlsv1.2', 'tlsv1.1']</code> here.",
|
||||||
validator => fun validate_tls_versions/1
|
validator => fun validate_tls_versions/1
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
|
@ -1827,7 +1862,7 @@ common_ssl_opts_schema(Defaults) ->
|
||||||
"SSL parameter renegotiation is a feature that allows a client and a server\n"
|
"SSL parameter renegotiation is a feature that allows a client and a server\n"
|
||||||
"to renegotiate the parameters of the SSL connection on the fly.\n"
|
"to renegotiate the parameters of the SSL connection on the fly.\n"
|
||||||
"RFC 5746 defines a more secure way of doing this. By enabling secure renegotiation,\n"
|
"RFC 5746 defines a more secure way of doing this. By enabling secure renegotiation,\n"
|
||||||
"you drop support for the insecure renegotiation, prone to MitM attacks.\n"
|
"you drop support for the insecure renegotiation, prone to MitM attacks."
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
].
|
].
|
||||||
|
@ -1864,7 +1899,7 @@ server_ssl_opts_schema(Defaults, IsRanchListener) ->
|
||||||
"If set to true, the server fails if the client does not have a\n"
|
"If set to true, the server fails if the client does not have a\n"
|
||||||
"certificate to send, that is, sends an empty certificate.\n"
|
"certificate to send, that is, sends an empty certificate.\n"
|
||||||
"If set to false, it fails only if the client sends an invalid\n"
|
"If set to false, it fails only if the client sends an invalid\n"
|
||||||
"certificate (an empty certificate is considered valid).\n"
|
"certificate (an empty certificate is considered valid)."
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
{"honor_cipher_order",
|
{"honor_cipher_order",
|
||||||
|
@ -1887,7 +1922,7 @@ server_ssl_opts_schema(Defaults, IsRanchListener) ->
|
||||||
"this option to false.\n"
|
"this option to false.\n"
|
||||||
"The default value is true. Note that disabling renegotiation can result in\n"
|
"The default value is true. Note that disabling renegotiation can result in\n"
|
||||||
"long-lived connections becoming unusable due to limits on\n"
|
"long-lived connections becoming unusable due to limits on\n"
|
||||||
"the number of messages the underlying cipher suite can encipher.\n"
|
"the number of messages the underlying cipher suite can encipher."
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
| [
|
| [
|
||||||
|
@ -1980,8 +2015,7 @@ ciphers_schema(Default) ->
|
||||||
"PSK cipher suites: <code>\"RSA-PSK-AES256-GCM-SHA384,RSA-PSK-AES256-CBC-SHA384,\n"
|
"PSK cipher suites: <code>\"RSA-PSK-AES256-GCM-SHA384,RSA-PSK-AES256-CBC-SHA384,\n"
|
||||||
"RSA-PSK-AES128-GCM-SHA256,RSA-PSK-AES128-CBC-SHA256,\n"
|
"RSA-PSK-AES128-GCM-SHA256,RSA-PSK-AES128-CBC-SHA256,\n"
|
||||||
"RSA-PSK-AES256-CBC-SHA,RSA-PSK-AES128-CBC-SHA,\n"
|
"RSA-PSK-AES256-CBC-SHA,RSA-PSK-AES128-CBC-SHA,\n"
|
||||||
"RSA-PSK-DES-CBC3-SHA,RSA-PSK-RC4-SHA\"</code><br>\n"
|
"RSA-PSK-DES-CBC3-SHA,RSA-PSK-RC4-SHA\"</code><br>\n" ++
|
||||||
"" ++
|
|
||||||
case Default of
|
case Default of
|
||||||
quic -> "NOTE: QUIC listener supports only 'tlsv1.3' ciphers<br>";
|
quic -> "NOTE: QUIC listener supports only 'tlsv1.3' ciphers<br>";
|
||||||
_ -> ""
|
_ -> ""
|
||||||
|
|
|
@ -637,13 +637,17 @@ fields("console_handler") ->
|
||||||
fields("log_file_handler") ->
|
fields("log_file_handler") ->
|
||||||
[ {"file",
|
[ {"file",
|
||||||
sc(file(),
|
sc(file(),
|
||||||
#{})}
|
#{ desc => "Name the log file."
|
||||||
|
})}
|
||||||
, {"rotation",
|
, {"rotation",
|
||||||
sc(ref("log_rotation"),
|
sc(ref("log_rotation"),
|
||||||
#{})}
|
#{})}
|
||||||
, {"max_size",
|
, {"max_size",
|
||||||
sc(hoconsc:union([infinity, emqx_schema:bytesize()]),
|
sc(hoconsc:union([infinity, emqx_schema:bytesize()]),
|
||||||
#{ default => "10MB"
|
#{ default => "10MB"
|
||||||
|
, desc => "This parameter controls log file rotation. "
|
||||||
|
"The value `infinity` means the log file will grow indefinitely, "
|
||||||
|
"otherwise the log file will be rotated once it reaches `max_size` in bytes."
|
||||||
})}
|
})}
|
||||||
] ++ log_handler_common_confs();
|
] ++ log_handler_common_confs();
|
||||||
|
|
||||||
|
@ -651,10 +655,12 @@ fields("log_rotation") ->
|
||||||
[ {"enable",
|
[ {"enable",
|
||||||
sc(boolean(),
|
sc(boolean(),
|
||||||
#{ default => true
|
#{ default => true
|
||||||
|
, desc => "Enable log rotation feature."
|
||||||
})}
|
})}
|
||||||
, {"count",
|
, {"count",
|
||||||
sc(range(1, 2048),
|
sc(range(1, 2048),
|
||||||
#{ default => 10
|
#{ default => 10
|
||||||
|
, desc => "Maximum number of log files."
|
||||||
})}
|
})}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -662,18 +668,23 @@ fields("log_overload_kill") ->
|
||||||
[ {"enable",
|
[ {"enable",
|
||||||
sc(boolean(),
|
sc(boolean(),
|
||||||
#{ default => true
|
#{ default => true
|
||||||
|
, desc => "Enable log handler overload kill feature."
|
||||||
})}
|
})}
|
||||||
, {"mem_size",
|
, {"mem_size",
|
||||||
sc(emqx_schema:bytesize(),
|
sc(emqx_schema:bytesize(),
|
||||||
#{ default => "30MB"
|
#{ default => "30MB"
|
||||||
|
, desc => "Maximum memory size that the handler process is allowed to use."
|
||||||
})}
|
})}
|
||||||
, {"qlen",
|
, {"qlen",
|
||||||
sc(integer(),
|
sc(integer(),
|
||||||
#{ default => 20000
|
#{ default => 20000
|
||||||
|
, desc => "Maximum allowed queue length."
|
||||||
})}
|
})}
|
||||||
, {"restart_after",
|
, {"restart_after",
|
||||||
sc(hoconsc:union([emqx_schema:duration(), infinity]),
|
sc(hoconsc:union([emqx_schema:duration(), infinity]),
|
||||||
#{ default => "5s"
|
#{ default => "5s"
|
||||||
|
, desc => "If the handler is terminated, it restarts automatically after a "
|
||||||
|
"delay specified in milliseconds. The value `infinity` prevents restarts."
|
||||||
})}
|
})}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -681,14 +692,20 @@ fields("log_burst_limit") ->
|
||||||
[ {"enable",
|
[ {"enable",
|
||||||
sc(boolean(),
|
sc(boolean(),
|
||||||
#{ default => true
|
#{ default => true
|
||||||
|
, desc => "Enable log burst control feature."
|
||||||
})}
|
})}
|
||||||
, {"max_count",
|
, {"max_count",
|
||||||
sc(integer(),
|
sc(integer(),
|
||||||
#{ default => 10000
|
#{ default => 10000
|
||||||
|
, desc => "Maximum number of log events to handle within a `window_time` interval. "
|
||||||
|
"After the limit is reached, successive events are dropped "
|
||||||
|
"until the end of the `window_time`."
|
||||||
})}
|
})}
|
||||||
, {"window_time",
|
, {"window_time",
|
||||||
sc(emqx_schema:duration(),
|
sc(emqx_schema:duration(),
|
||||||
#{default => "1s"})}
|
#{ default => "1s"
|
||||||
|
, desc => "See `max_count`."
|
||||||
|
})}
|
||||||
];
|
];
|
||||||
|
|
||||||
fields("authorization") ->
|
fields("authorization") ->
|
||||||
|
@ -801,6 +818,7 @@ log_handler_common_confs() ->
|
||||||
[ {"enable",
|
[ {"enable",
|
||||||
sc(boolean(),
|
sc(boolean(),
|
||||||
#{ default => false
|
#{ default => false
|
||||||
|
, desc => "Enable this log handler."
|
||||||
})}
|
})}
|
||||||
, {"level",
|
, {"level",
|
||||||
sc(log_level(),
|
sc(log_level(),
|
||||||
|
@ -811,6 +829,7 @@ log_handler_common_confs() ->
|
||||||
, {"time_offset",
|
, {"time_offset",
|
||||||
sc(string(),
|
sc(string(),
|
||||||
#{ default => "system"
|
#{ default => "system"
|
||||||
|
, desc => "The time offset to be used when formatting the timestamp."
|
||||||
})}
|
})}
|
||||||
, {"chars_limit",
|
, {"chars_limit",
|
||||||
sc(hoconsc:union([unlimited, range(1, inf)]),
|
sc(hoconsc:union([unlimited, range(1, inf)]),
|
||||||
|
@ -833,24 +852,34 @@ log_handler_common_confs() ->
|
||||||
, {"sync_mode_qlen",
|
, {"sync_mode_qlen",
|
||||||
sc(integer(),
|
sc(integer(),
|
||||||
#{ default => 100
|
#{ default => 100
|
||||||
|
, desc => "As long as the number of buffered log events is lower than this value, "
|
||||||
|
"all log events are handled asynchronously."
|
||||||
})}
|
})}
|
||||||
, {"drop_mode_qlen",
|
, {"drop_mode_qlen",
|
||||||
sc(integer(),
|
sc(integer(),
|
||||||
#{ default => 3000
|
#{ default => 3000
|
||||||
|
, desc => "When the number of buffered log events is larger than this value, "
|
||||||
|
"the new log events are dropped.<br/>"
|
||||||
|
"When drop mode is activated or deactivated, a message is printed in "
|
||||||
|
"the logs."
|
||||||
})}
|
})}
|
||||||
, {"flush_qlen",
|
, {"flush_qlen",
|
||||||
sc(integer(),
|
sc(integer(),
|
||||||
#{ default => 8000
|
#{ default => 8000
|
||||||
|
, desc => "If the number of buffered log events grows larger than this threshold, "
|
||||||
|
"a flush (delete) operation takes place. "
|
||||||
|
"To flush events, the handler discards the buffered log messages without logging."
|
||||||
})}
|
})}
|
||||||
, {"overload_kill",
|
, {"overload_kill",
|
||||||
sc(ref("log_overload_kill"),
|
sc(ref("log_overload_kill"), #{})}
|
||||||
#{})}
|
|
||||||
, {"burst_limit",
|
, {"burst_limit",
|
||||||
sc(ref("log_burst_limit"),
|
sc(ref("log_burst_limit"), #{})}
|
||||||
#{})}
|
|
||||||
, {"supervisor_reports",
|
, {"supervisor_reports",
|
||||||
sc(hoconsc:enum([error, progress]),
|
sc(hoconsc:enum([error, progress]),
|
||||||
#{ default => error
|
#{ default => error
|
||||||
|
, desc => "Type of supervisor reports that are logged.\n"
|
||||||
|
" - `error`: only log errors in the Erlang processes.\n"
|
||||||
|
" - `progress`: log process startup."
|
||||||
})}
|
})}
|
||||||
, {"max_depth",
|
, {"max_depth",
|
||||||
sc(hoconsc:union([unlimited, non_neg_integer()]),
|
sc(hoconsc:union([unlimited, non_neg_integer()]),
|
||||||
|
|
|
@ -29,14 +29,13 @@ fields("dashboard") ->
|
||||||
sc(hoconsc:array(hoconsc:union([hoconsc:ref(?MODULE, "http"),
|
sc(hoconsc:array(hoconsc:union([hoconsc:ref(?MODULE, "http"),
|
||||||
hoconsc:ref(?MODULE, "https")])),
|
hoconsc:ref(?MODULE, "https")])),
|
||||||
#{ desc =>
|
#{ desc =>
|
||||||
"""HTTP(s) listeners are identified by their protocol type and are
|
"HTTP(s) listeners are identified by their protocol type and are
|
||||||
used to serve dashboard UI and restful HTTP API.<br>
|
used to serve dashboard UI and restful HTTP API.<br>
|
||||||
Listeners must have a unique combination of port number and IP address.<br>
|
Listeners must have a unique combination of port number and IP address.<br>
|
||||||
For example, an HTTP listener can listen on all configured IP addresses
|
For example, an HTTP listener can listen on all configured IP addresses
|
||||||
on a given port for a machine by specifying the IP address 0.0.0.0.<br>
|
on a given port for a machine by specifying the IP address 0.0.0.0.<br>
|
||||||
Alternatively, the HTTP listener can specify a unique IP address for each listener,
|
Alternatively, the HTTP listener can specify a unique IP address for each listener,
|
||||||
but use the same port.
|
but use the same port."})}
|
||||||
""" })}
|
|
||||||
, {default_username, fun default_username/1}
|
, {default_username, fun default_username/1}
|
||||||
, {default_password, fun default_password/1}
|
, {default_password, fun default_password/1}
|
||||||
, {sample_interval, sc(emqx_schema:duration_s(), #{default => "10s"})}
|
, {sample_interval, sc(emqx_schema:duration_s(), #{default => "10s"})}
|
||||||
|
|
|
@ -45,19 +45,36 @@ fields(exhook) ->
|
||||||
];
|
];
|
||||||
|
|
||||||
fields(server) ->
|
fields(server) ->
|
||||||
[ {name, sc(binary(), #{})}
|
[ {name, sc(binary(),
|
||||||
, {enable, sc(boolean(), #{default => true})}
|
#{ desc => "Name of the exhook server."
|
||||||
, {url, sc(binary(), #{})}
|
})}
|
||||||
, {request_timeout,
|
, {enable, sc(boolean(),
|
||||||
sc(duration(), #{default => "5s"})}
|
#{ default => true
|
||||||
|
, desc => "Enable the exhook server."
|
||||||
|
})}
|
||||||
|
, {url, sc(binary(),
|
||||||
|
#{ desc => "URL of the gRPC server."
|
||||||
|
})}
|
||||||
|
, {request_timeout, sc(duration(),
|
||||||
|
#{ default => "5s"
|
||||||
|
, desc => "The timeout to request gRPC server."
|
||||||
|
})}
|
||||||
, {failed_action, failed_action()}
|
, {failed_action, failed_action()}
|
||||||
, {ssl,
|
, {ssl,
|
||||||
sc(ref(ssl_conf), #{})}
|
sc(ref(ssl_conf), #{})}
|
||||||
, {auto_reconnect,
|
, {auto_reconnect,
|
||||||
sc(hoconsc:union([false, duration()]),
|
sc(hoconsc:union([false, duration()]),
|
||||||
#{default => "60s"})}
|
#{ default => "60s"
|
||||||
|
, desc => "Whether to automatically reconnect (initialize) the gRPC server.<br/>"
|
||||||
|
"When gRPC is not available, exhook tries to request the gRPC service at "
|
||||||
|
"that interval and reinitialize the list of mounted hooks."
|
||||||
|
})}
|
||||||
, {pool_size,
|
, {pool_size,
|
||||||
sc(integer(), #{default => 8, example => 8})}
|
sc(integer(),
|
||||||
|
#{ default => 8
|
||||||
|
, example => 8
|
||||||
|
, desc => "The process pool size for gRPC client."
|
||||||
|
})}
|
||||||
];
|
];
|
||||||
|
|
||||||
fields(ssl_conf) ->
|
fields(ssl_conf) ->
|
||||||
|
|
|
@ -473,26 +473,48 @@ common_listener_opts() ->
|
||||||
[ {enable,
|
[ {enable,
|
||||||
sc(boolean(),
|
sc(boolean(),
|
||||||
#{ default => true
|
#{ default => true
|
||||||
|
, desc => "Enable the listener."
|
||||||
})}
|
})}
|
||||||
, {bind,
|
, {bind,
|
||||||
sc(hoconsc:union([ip_port(), integer()]),
|
sc(hoconsc:union([ip_port(), integer()]),
|
||||||
#{})}
|
#{ desc => "The IP address and port that the listener will bind."
|
||||||
|
})}
|
||||||
, {max_connections,
|
, {max_connections,
|
||||||
sc(integer(),
|
sc(integer(),
|
||||||
#{ default => 1024
|
#{ default => 1024
|
||||||
|
, desc => "Maximum number of concurrent connections."
|
||||||
})}
|
})}
|
||||||
, {max_conn_rate,
|
, {max_conn_rate,
|
||||||
sc(integer(),
|
sc(integer(),
|
||||||
#{ default => 1000
|
#{ default => 1000
|
||||||
|
, desc => "Maximum connections per second."
|
||||||
})}
|
})}
|
||||||
, {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_ATOM, authentication_schema()}
|
, {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_ATOM, authentication_schema()}
|
||||||
, {mountpoint,
|
, {mountpoint,
|
||||||
sc(binary(),
|
sc(binary(),
|
||||||
#{ default => undefined
|
#{ default => undefined
|
||||||
|
, 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.<name>.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`.<br/>\n"
|
||||||
|
" Set to `\"\"` to disable the feature.<br/>\n"
|
||||||
|
"\n"
|
||||||
|
" Variables in mountpoint string:\n"
|
||||||
|
" - <code>${clientid}</code>: clientid\n"
|
||||||
|
" - <code>${username}</code>: username"
|
||||||
})}
|
})}
|
||||||
, {access_rules,
|
, {access_rules,
|
||||||
sc(hoconsc:array(string()),
|
sc(hoconsc:array(string()),
|
||||||
#{ default => []
|
#{ default => []
|
||||||
|
, desc => "The access control rules for this listener.<br/>"
|
||||||
|
"See: https://github.com/emqtt/esockd#allowdeny"
|
||||||
})}
|
})}
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,21 @@ namespace() -> "prometheus".
|
||||||
roots() -> ["prometheus"].
|
roots() -> ["prometheus"].
|
||||||
|
|
||||||
fields("prometheus") ->
|
fields("prometheus") ->
|
||||||
[ {push_gateway_server, sc(string(), #{default => "http://127.0.0.1:9091", required => true})}
|
[ {push_gateway_server, sc(string(),
|
||||||
, {interval, sc(emqx_schema:duration_ms(), #{default => "15s", required => true})}
|
#{ default => "http://127.0.0.1:9091"
|
||||||
, {enable, sc(boolean(), #{default => false, required => true})}
|
, required => true
|
||||||
|
, desc => "URL of Prometheus pushgateway."
|
||||||
|
})}
|
||||||
|
, {interval, sc(emqx_schema:duration_ms(),
|
||||||
|
#{ default => "15s"
|
||||||
|
, required => true
|
||||||
|
, desc => "Data reporting interval in milliseconds."
|
||||||
|
})}
|
||||||
|
, {enable, sc(boolean(),
|
||||||
|
#{ default => false
|
||||||
|
, required => true
|
||||||
|
, desc => "Enable reporting of metrics via Prometheus Pushgateway."
|
||||||
|
})}
|
||||||
].
|
].
|
||||||
|
|
||||||
sc(Type, Meta) -> hoconsc:mk(Type, Meta).
|
sc(Type, Meta) -> hoconsc:mk(Type, Meta).
|
||||||
|
|
|
@ -11,35 +11,63 @@ namespace() -> "retainer".
|
||||||
roots() -> ["retainer"].
|
roots() -> ["retainer"].
|
||||||
|
|
||||||
fields("retainer") ->
|
fields("retainer") ->
|
||||||
[ {enable, sc(boolean(), false)}
|
[ {enable, sc(boolean(), "Enable retainer feature.", false)}
|
||||||
, {msg_expiry_interval, sc(emqx_schema:duration_ms(), "0s")}
|
, {msg_expiry_interval, sc(emqx_schema:duration_ms(),
|
||||||
, {msg_clear_interval, sc(emqx_schema:duration_ms(), "0s")}
|
"Message retention time. 0 means message will never be expired.",
|
||||||
|
"0s")}
|
||||||
|
, {msg_clear_interval, sc(emqx_schema:duration_ms(),
|
||||||
|
"Periodic interval for cleaning up expired messages. "
|
||||||
|
"Never clear if the value is 0.",
|
||||||
|
"0s")}
|
||||||
, {flow_control, ?TYPE(hoconsc:ref(?MODULE, flow_control))}
|
, {flow_control, ?TYPE(hoconsc:ref(?MODULE, flow_control))}
|
||||||
, {max_payload_size, sc(emqx_schema:bytesize(), "1MB")}
|
, {max_payload_size, sc(emqx_schema:bytesize(),
|
||||||
, {stop_publish_clear_msg, sc(boolean(), false)}
|
"Maximum retained message size.",
|
||||||
|
"1MB")}
|
||||||
|
, {stop_publish_clear_msg, sc(boolean(),
|
||||||
|
"When the retained flag of the `PUBLISH` message is set and Payload is empty, "
|
||||||
|
"whether to continue to publish the message.<br/>"
|
||||||
|
"See: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718038",
|
||||||
|
false)}
|
||||||
, {backend, backend_config()}
|
, {backend, backend_config()}
|
||||||
];
|
];
|
||||||
|
|
||||||
fields(mnesia_config) ->
|
fields(mnesia_config) ->
|
||||||
[ {type, ?TYPE(hoconsc:union([built_in_database]))}
|
[ {type, ?TYPE(hoconsc:union([built_in_database]))}
|
||||||
, {storage_type, sc(hoconsc:union([ram, disc]), ram)}
|
, {storage_type, sc(hoconsc:union([ram, disc]),
|
||||||
, {max_retained_messages, sc(integer(), 0, fun is_pos_integer/1)}
|
"Specifies whether the messages are stored in RAM or persisted on disc.",
|
||||||
|
ram)}
|
||||||
|
, {max_retained_messages, sc(integer(),
|
||||||
|
"Maximum number of retained messages. 0 means no limit.",
|
||||||
|
0,
|
||||||
|
fun is_pos_integer/1)}
|
||||||
];
|
];
|
||||||
|
|
||||||
fields(flow_control) ->
|
fields(flow_control) ->
|
||||||
[ {batch_read_number, sc(integer(), 0, fun is_pos_integer/1)}
|
[ {batch_read_number, sc(integer(),
|
||||||
, {batch_deliver_number, sc(range(0, 1000), 0)}
|
"Size of the batch when reading messages from storage. 0 means no limit.",
|
||||||
, {batch_deliver_limiter, sc(emqx_limiter_schema:bucket_name(), undefined)}
|
0,
|
||||||
|
fun is_pos_integer/1)}
|
||||||
|
, {batch_deliver_number, sc(range(0, 1000),
|
||||||
|
"The number of retained messages can be delivered per batch.",
|
||||||
|
0)}
|
||||||
|
, {batch_deliver_limiter, sc(emqx_limiter_schema:bucket_name(),
|
||||||
|
"The rate limiter name for retained messages' delivery.<br/>"
|
||||||
|
"Limiter helps to avoid delivering too many messages to the client at once, which may cause the client "
|
||||||
|
"to block or crash, or drop messages due to exceeding the size of the message queue.<br/>"
|
||||||
|
"The names of the available rate limiters are taken from the existing rate limiters under `limiter.batch`.<br/>"
|
||||||
|
"If this field is empty, limiter is not used.",
|
||||||
|
undefined)}
|
||||||
].
|
].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
sc(Type, Default) ->
|
sc(Type, Desc, Default) ->
|
||||||
hoconsc:mk(Type, #{default => Default}).
|
hoconsc:mk(Type, #{default => Default, desc => Desc}).
|
||||||
|
|
||||||
sc(Type, Default, Validator) ->
|
sc(Type, Desc, Default, Validator) ->
|
||||||
hoconsc:mk(Type, #{default => Default,
|
hoconsc:mk(Type, #{default => Default,
|
||||||
|
desc => Desc,
|
||||||
validator => Validator}).
|
validator => Validator}).
|
||||||
|
|
||||||
is_pos_integer(V) ->
|
is_pos_integer(V) ->
|
||||||
|
|
|
@ -33,21 +33,33 @@ namespace() -> "statsd".
|
||||||
roots() -> ["statsd"].
|
roots() -> ["statsd"].
|
||||||
|
|
||||||
fields("statsd") ->
|
fields("statsd") ->
|
||||||
[ {enable, hoconsc:mk(boolean(), #{default => false, required => true})}
|
[ {enable, hoconsc:mk(boolean(),
|
||||||
|
#{ default => false
|
||||||
|
, required => true
|
||||||
|
, desc => "Enable statsd"
|
||||||
|
})}
|
||||||
, {server, fun server/1}
|
, {server, fun server/1}
|
||||||
, {sample_time_interval, fun duration_ms/1}
|
, {sample_time_interval, fun sample_interval/1}
|
||||||
, {flush_time_interval, fun duration_ms/1}
|
, {flush_time_interval, fun flush_interval/1}
|
||||||
].
|
].
|
||||||
|
|
||||||
server(type) -> emqx_schema:ip_port();
|
server(type) -> emqx_schema:ip_port();
|
||||||
server(required) -> true;
|
server(required) -> true;
|
||||||
server(default) -> "127.0.0.1:8125";
|
server(default) -> "127.0.0.1:8125";
|
||||||
|
server(desc) -> "URL of the statsd gateway.";
|
||||||
server(_) -> undefined.
|
server(_) -> undefined.
|
||||||
|
|
||||||
duration_ms(type) -> emqx_schema:duration_ms();
|
sample_interval(type) -> emqx_schema:duration_ms();
|
||||||
duration_ms(required) -> true;
|
sample_interval(required) -> true;
|
||||||
duration_ms(default) -> "10s";
|
sample_interval(default) -> "10s";
|
||||||
duration_ms(_) -> undefined.
|
sample_interval(desc) -> "Data collection interval in milliseconds.";
|
||||||
|
sample_interval(_) -> undefined.
|
||||||
|
|
||||||
|
flush_interval(type) -> emqx_schema:duration_ms();
|
||||||
|
flush_interval(required) -> true;
|
||||||
|
flush_interval(default) -> "10s";
|
||||||
|
flush_interval(desc) -> "Flush interval in milliseconds.";
|
||||||
|
flush_interval(_) -> undefined.
|
||||||
|
|
||||||
to_ip_port(Str) ->
|
to_ip_port(Str) ->
|
||||||
case string:tokens(Str, ":") of
|
case string:tokens(Str, ":") of
|
||||||
|
|
Loading…
Reference in New Issue