Explorar el Código

fix(config): set console_handler.enable to turewhen start from console

Shawn hace 4 años
padre
commit
d2c50baf93
Se han modificado 3 ficheros con 372 adiciones y 207 borrados
  1. 303 137
      apps/emqx/etc/emqx.conf
  2. 67 68
      apps/emqx/src/emqx_schema.erl
  3. 2 2
      bin/emqx

+ 303 - 137
apps/emqx/etc/emqx.conf

@@ -344,8 +344,8 @@ log {
   ##
   ##
   ## @doc log.console_handler.level
   ## @doc log.console_handler.level
   ## ValueType: debug | info | notice | warning | error | critical | alert | emergency
   ## ValueType: debug | info | notice | warning | error | critical | alert | emergency
-  ## Default: debug
-  console_handler.level = debug
+  ## Default: warning
+  console_handler.level = warning
 
 
   ##----------------------------------------------------------------
   ##----------------------------------------------------------------
   ## The file log handlers send log messages to files
   ## The file log handlers send log messages to files
@@ -358,8 +358,8 @@ log {
     ##
     ##
     ## @doc log.file_handlers.<name>.level
     ## @doc log.file_handlers.<name>.level
     ## ValueType: debug | info | notice | warning | error | critical | alert | emergency
     ## ValueType: debug | info | notice | warning | error | critical | alert | emergency
-    ## Default: debug
-    level: debug
+    ## Default: warning
+    level: warning
 
 
     ## The log file for specified level.
     ## The log file for specified level.
     ##
     ##
@@ -380,18 +380,18 @@ log {
     ## With this enabled, new log files will be created when the current
     ## With this enabled, new log files will be created when the current
     ## log file is full, max to `rotation_count` files will be created.
     ## log file is full, max to `rotation_count` files will be created.
     ##
     ##
-    ## @doc log.file_handlers.<name>.rotation
+    ## @doc log.file_handlers.<name>.rotation.enable
     ## ValueType: Boolean
     ## ValueType: Boolean
     ## Default: true
     ## Default: true
-    rotation = true
+    rotation.enable = true
 
 
     ## Maximum rotation count of log files.
     ## Maximum rotation count of log files.
     ##
     ##
-    ## @doc log.file_handlers.<name>.rotation_count
+    ## @doc log.file_handlers.<name>.rotation.count
     ## ValueType: Integer
     ## ValueType: Integer
     ## Range: [1, 2048]
     ## Range: [1, 2048]
     ## Default: 10
     ## Default: 10
-    rotation_count: 10
+    rotation.count: 10
 
 
     ## Maximum size of each log file.
     ## Maximum size of each log file.
     ##
     ##
@@ -411,9 +411,19 @@ log {
   ## log level for example:
   ## log level for example:
   file_handlers.emqx_error: {
   file_handlers.emqx_error: {
     level: error
     level: error
-    file: "{{ platform_log_dir }}/emqx.error.log"
+    file: "{{ platform_log_dir }}/error.log"
   }
   }
 
 
+  ## Timezone offset to display in logs
+  ##
+  ## @doc log.time_offset
+  ## ValueType: system | utc | String
+  ##  - "system" use system zone
+  ##  - "utc" for Universal Coordinated Time (UTC)
+  ##  - "+hh:mm" or "-hh:mm" for a specified offset
+  ## Default: system
+  time_offset = system
+
   ## Limits the total number of characters printed for each log event.
   ## Limits the total number of characters printed for each log event.
   ##
   ##
   ## @doc log.chars_limit
   ## @doc log.chars_limit
@@ -421,6 +431,14 @@ log {
   ## Default: infinity
   ## Default: infinity
   chars_limit: 8192
   chars_limit: 8192
 
 
+  ## Maximum depth for Erlang term log formatting
+  ## and Erlang process message queue inspection.
+  ##
+  ## @doc log.max_depth
+  ## ValueType: Integer | infinity
+  ## Default: 80
+  max_depth = 80
+
   ## Log formatter
   ## Log formatter
   ## @doc log.formatter
   ## @doc log.formatter
   ## ValueType: text | json
   ## ValueType: text | json
@@ -477,10 +495,10 @@ log {
   ## We could kill the log handler in these cases and restart it after a
   ## We could kill the log handler in these cases and restart it after a
   ## few seconds.
   ## few seconds.
   ##
   ##
-  ## @doc log.overload_kill
+  ## @doc log.overload_kill.enable
   ## ValueType: Boolean
   ## ValueType: Boolean
   ## Default: true
   ## Default: true
-  overload_kill: true
+  overload_kill.enable: true
 
 
   ## The max allowed queue length before killing the log hanlder.
   ## The max allowed queue length before killing the log hanlder.
   ##
   ##
@@ -488,11 +506,11 @@ log {
   ## length. If the message queue grows larger than this, the handler
   ## length. If the message queue grows larger than this, the handler
   ## process is terminated.
   ## process is terminated.
   ##
   ##
-  ## @doc log.overload_kill_qlen
+  ## @doc log.overload_kill.qlen
   ## ValueType: Integer
   ## ValueType: Integer
   ## Range: [0, 1048576]
   ## Range: [0, 1048576]
   ## Default: 20000
   ## Default: 20000
-  overload_kill_qlen: 20000
+  overload_kill.qlen: 20000
 
 
   ## The max allowed memory size before killing the log hanlder.
   ## The max allowed memory size before killing the log hanlder.
   ##
   ##
@@ -500,20 +518,20 @@ log {
   ## that the handler process is allowed to use. If the handler grows
   ## that the handler process is allowed to use. If the handler grows
   ## larger than this, the process is terminated.
   ## larger than this, the process is terminated.
   ##
   ##
-  ## @doc log.overload_kill_mem_size
+  ## @doc log.overload_kill.mem_size
   ## ValueType: Size
   ## ValueType: Size
   ## Default: 30MB
   ## Default: 30MB
-  overload_kill_mem_size: 30MB
+  overload_kill.mem_size: 30MB
 
 
   ## Restart the log hanlder after some seconds.
   ## Restart the log hanlder after some seconds.
   ##
   ##
   ## Log overload protection parameter. If the handler is terminated,
   ## Log overload protection parameter. If the handler is terminated,
   ## it restarts automatically after a delay specified in seconds.
   ## it restarts automatically after a delay specified in seconds.
   ##
   ##
-  ## @doc log.overload_kill_restart_after
+  ## @doc log.overload_kill.restart_after
   ## ValueType: Duration
   ## ValueType: Duration
   ## Default: 5s
   ## Default: 5s
-  overload_kill_restart_after: 5s
+  overload_kill.restart_after: 5s
 
 
   ## Controlling Bursts of Log Requests.
   ## Controlling Bursts of Log Requests.
   ##
   ##
@@ -526,26 +544,26 @@ log {
   ## Note that there would be no warning if any messages were
   ## Note that there would be no warning if any messages were
   ## dropped because of burst control.
   ## dropped because of burst control.
   ##
   ##
-  ## @doc log.burst_limit
+  ## @doc log.burst_limit.enable
   ## ValueType: Boolean
   ## ValueType: Boolean
   ## Default: false
   ## Default: false
-  burst_limit: false
+  burst_limit.enable: false
 
 
   ## This config controls the maximum number of events to handle within
   ## This config controls the maximum number of events to handle within
   ## a time frame. After the limit is reached, successive events are
   ## a time frame. After the limit is reached, successive events are
   ## dropped until the end of the time frame defined by `window_time`.
   ## dropped until the end of the time frame defined by `window_time`.
   ##
   ##
-  ## @doc log.burst_limit_max_count
+  ## @doc log.burst_limit.max_count
   ## ValueType: Integer
   ## ValueType: Integer
   ## Default: 10000
   ## Default: 10000
-  burst_limit_max_count: 10000
+  burst_limit.max_count: 10000
 
 
   ## See the previous description of burst_limit_max_count.
   ## See the previous description of burst_limit_max_count.
   ##
   ##
-  ## @doc log.burst_limit_window_time
+  ## @doc log.burst_limit.window_time
   ## ValueType: duration
   ## ValueType: duration
   ## Default: 1s
   ## Default: 1s
-  burst_limit_window_time: 1s
+  burst_limit.window_time: 1s
 }
 }
 
 
 ##==================================================================
 ##==================================================================
@@ -577,8 +595,7 @@ rpc {
   ##
   ##
   ## @doc cluster.discovery_strategy
   ## @doc cluster.discovery_strategy
   ## ValueType: manual | stateless
   ## ValueType: manual | stateless
-  ##   - manual: discover ports by `tcp_server_port` and
-  ##     `tcp_client_port`.
+  ##   - manual: discover ports by `tcp_server_port`.
   ##   - stateless: discover ports in a stateless manner.
   ##   - stateless: discover ports in a stateless manner.
   ##     If node name is `emqx<N>@127.0.0.1`, where the `<N>` is
   ##     If node name is `emqx<N>@127.0.0.1`, where the `<N>` is
   ##     an integer, then the listening port will be `5370 + <N>`
   ##     an integer, then the listening port will be `5370 + <N>`
@@ -596,26 +613,15 @@ rpc {
   ## Defaults: 5369
   ## Defaults: 5369
   tcp_server_port: 5369
   tcp_server_port: 5369
 
 
-  ## TCP port for outgoing RPC connections.
-  ##
-  ## Only takes effect when `rpc.port_discovery` = `manual`.
-  ##
-  ## @doc rpc.tcp_client_port
-  ## ValueType: Integer
-  ## Range: [1024-65535]
-  ## Defaults: 5369
-  tcp_client_port: 5369
-
   ## Number of outgoing RPC connections.
   ## Number of outgoing RPC connections.
   ##
   ##
-  ## Defaults to "num_cpu_cores", that is, the number of CPU cores.
   ## Set this to 1 to keep the message order sent from the same
   ## Set this to 1 to keep the message order sent from the same
   ## client.
   ## client.
   ##
   ##
   ## @doc rpc.tcp_client_num
   ## @doc rpc.tcp_client_num
-  ## ValueType: Integer | num_cpu_cores
+  ## ValueType: Integer
   ## Range: [1, 256]
   ## Range: [1, 256]
-  ## Defaults: num_cpu_cores
+  ## Defaults: 1
   tcp_client_num: 1
   tcp_client_num: 1
 
 
   ## RCP Client connect timeout.
   ## RCP Client connect timeout.
@@ -827,6 +833,13 @@ zone.default {
   ## Default: true
   ## Default: true
   stats.enable: true
   stats.enable: true
 
 
+  ## Maximum number of concurrent connections.
+  ##
+  ## @doc zone.<name>.listeners.<name>.overall_max_connections
+  ## ValueType: Number | infinity
+  ## Default: infinity
+  overall_max_connections: infinity
+
   mqtt {
   mqtt {
     ## When publishing or subscribing, prefix all topics with a mountpoint string.
     ## When publishing or subscribing, prefix all topics with a mountpoint string.
     ## The prefixed string will be removed from the topic name when the message
     ## The prefixed string will be removed from the topic name when the message
@@ -870,7 +883,7 @@ zone.default {
     ## Maximum length of MQTT clientId allowed.
     ## Maximum length of MQTT clientId allowed.
     ##
     ##
     ## @doc zone.<name>.mqtt.max_clientid_len
     ## @doc zone.<name>.mqtt.max_clientid_len
-    ## ValueType: Integer | infinity
+    ## ValueType: Integer
     ## Range: [23, 65535]
     ## Range: [23, 65535]
     ## Default: 65535
     ## Default: 65535
     max_clientid_len: 65535
     max_clientid_len: 65535
@@ -878,10 +891,10 @@ zone.default {
     ## Maximum topic levels allowed.
     ## Maximum topic levels allowed.
     ##
     ##
     ## @doc zone.<name>.mqtt.max_topic_levels
     ## @doc zone.<name>.mqtt.max_topic_levels
-    ## ValueType: Integer | infinity
+    ## ValueType: Integer
     ## Range: [1, 65535]
     ## Range: [1, 65535]
-    ## Default: infinity
-    max_topic_levels: infinity
+    ## Default: 65535
+    max_topic_levels: 65535
 
 
     ## Maximum QoS allowed.
     ## Maximum QoS allowed.
     ##
     ##
@@ -893,7 +906,7 @@ zone.default {
     ## Maximum Topic Alias, 0 means no topic alias supported.
     ## Maximum Topic Alias, 0 means no topic alias supported.
     ##
     ##
     ## @doc zone.<name>.mqtt.max_topic_alias
     ## @doc zone.<name>.mqtt.max_topic_alias
-    ## ValueType: Integer | infinity
+    ## ValueType: Integer
     ## Range: [0, 65535]
     ## Range: [0, 65535]
     ## Default: 65535
     ## Default: 65535
     max_topic_alias: 65535
     max_topic_alias: 65535
@@ -958,11 +971,11 @@ zone.default {
     ## Default: 0.75
     ## Default: 0.75
     keepalive_backoff: 0.75
     keepalive_backoff: 0.75
 
 
-    ## Maximum number of subscriptions allowed, 0 means no limit.
+    ## Maximum number of subscriptions allowed.
     ##
     ##
     ## @doc zone.<name>.mqtt.max_subscriptions
     ## @doc zone.<name>.mqtt.max_subscriptions
     ## ValueType: Integer | infinity
     ## ValueType: Integer | infinity
-    ## Range: [0, )
+    ## Range: [1, )
     ## Default: infinity
     ## Default: infinity
     max_subscriptions: infinity
     max_subscriptions: infinity
 
 
@@ -976,8 +989,8 @@ zone.default {
     ## Maximum size of the Inflight Window storing QoS1/2 messages delivered but unacked.
     ## Maximum size of the Inflight Window storing QoS1/2 messages delivered but unacked.
     ##
     ##
     ## @doc zone.<name>.mqtt.max_inflight
     ## @doc zone.<name>.mqtt.max_inflight
-    ## ValueType: Integer | infinity
-    ## Range: [0, )
+    ## ValueType: Integer
+    ## Range: [1, 65535]
     ## Default: 32
     ## Default: 32
     max_inflight: 32
     max_inflight: 32
 
 
@@ -988,11 +1001,11 @@ zone.default {
     ## Default: 30s
     ## Default: 30s
     retry_interval: 30s
     retry_interval: 30s
 
 
-    ## Maximum QoS2 packets (Client -> Broker) awaiting PUBREL, 0 means no limit.
+    ## Maximum QoS2 packets (Client -> Broker) awaiting PUBREL.
     ##
     ##
     ## @doc zone.<name>.mqtt.max_awaiting_rel
     ## @doc zone.<name>.mqtt.max_awaiting_rel
     ## ValueType: Integer | infinity
     ## ValueType: Integer | infinity
-    ## Range: [0, )
+    ## Range: [1, )
     ## Default: 100
     ## Default: 100
     max_awaiting_rel: 100
     max_awaiting_rel: 100
 
 
@@ -1011,7 +1024,7 @@ zone.default {
     session_expiry_interval: 2h
     session_expiry_interval: 2h
 
 
     ## Maximum queue length. Enqueued messages when persistent client disconnected,
     ## Maximum queue length. Enqueued messages when persistent client disconnected,
-    ## or inflight window is full. 0 means no limit.
+    ## or inflight window is full.
     ##
     ##
     ## @doc zone.<name>.mqtt.max_mqueue_len
     ## @doc zone.<name>.mqtt.max_mqueue_len
     ## ValueType: Integer | infinity
     ## ValueType: Integer | infinity
@@ -1117,61 +1130,6 @@ zone.default {
     cache.ttl: 1m
     cache.ttl: 1m
   }
   }
 
 
-  rate_limit {
-    ## Maximum connections per second.
-    ##
-    ## @doc zone.<name>.max_conn_rate
-    ## ValueType: Number | infinity
-    ## Default: 1000
-    ## Examples:
-    ##   max_conn_rate: 1000
-    max_conn_rate: 1000
-
-    ## Message limit for the a external MQTT connection.
-    ##
-    ## @doc zone.<name>.rate_limit.conn_messages_in
-    ## ValueType: String | infinity
-    ## Default: infinity
-    ## Examples: 100 messages per 10 seconds.
-    ##   conn_messages_in: "100,10s"
-    conn_messages_in: "100,10s"
-
-    ## Limit the rate of receiving packets for a MQTT connection.
-    ## The rate is counted by bytes of packets per second.
-    ##
-    ## The connection won't accept more messages if the messages come
-    ## faster than the limit.
-    ##
-    ## @doc zone.<name>.rate_limit.conn_bytes_in
-    ## ValueType: String | infinity
-    ## Default: infinity
-    ## Examples: 100KB incoming per 10 seconds.
-    ##   conn_bytes_in: "100KB,10s"
-    ##
-    conn_bytes_in: "100KB,10s"
-
-    ## Messages quota for the each of external MQTT connection.
-    ## This value consumed by the number of recipient on a message.
-    ##
-    ## @doc zone.<name>.rate_limit.quota.conn_messages_routing
-    ## ValueType: String | infinity
-    ## Default: infinity
-    ## Examples: 100 messaegs per 1s:
-    ##   quota.conn_messages_routing: "100,1s"
-    quota.conn_messages_routing: "100,1s"
-
-    ## Messages quota for the all of external MQTT connections.
-    ## This value consumed by the number of recipient on a message.
-    ##
-    ## @doc zone.<name>.rate_limit.quota.overall_messages_routing
-    ## ValueType: String | infinity
-    ## Default: infinity
-    ## Examples: 200000 messages per 1s:
-    ##    quota.overall_messages_routing: "200000,1s"
-    ##
-    quota.overall_messages_routing: "200000,1s"
-  }
-
   flapping_detect {
   flapping_detect {
     ## Enable Flapping Detection.
     ## Enable Flapping Detection.
     ##
     ##
@@ -1299,11 +1257,9 @@ zone.default {
     ## The type of the listener.
     ## The type of the listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.type
     ## @doc zone.<name>.listeners.<name>.type
-    ## ValueType: tcp | ssl | ws | wss
+    ## ValueType: tcp | ws
     ##   - tcp: MQTT over TCP
     ##   - tcp: MQTT over TCP
-    ##   - ssl: MQTT over TLS
     ##   - ws:  MQTT over Websocket
     ##   - ws:  MQTT over Websocket
-    ##   - wss: MQTT over WebSocket Secure
     ## Required: true
     ## Required: true
     type: tcp
     type: tcp
 
 
@@ -1318,9 +1274,9 @@ zone.default {
     ## The size of the acceptor pool for this listener.
     ## The size of the acceptor pool for this listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.acceptors
     ## @doc zone.<name>.listeners.<name>.acceptors
-    ## ValueType: Number | num_cpu_cores
-    ## Default: num_cpu_cores
-    acceptors: num_cpu_cores
+    ## ValueType: Number
+    ## Default: 16
+    acceptors: 16
 
 
     ## Maximum number of concurrent connections.
     ## Maximum number of concurrent connections.
     ##
     ##
@@ -1363,6 +1319,61 @@ zone.default {
     ## Default: 3s
     ## Default: 3s
     proxy_protocol_timeout: 3s
     proxy_protocol_timeout: 3s
 
 
+    rate_limit {
+      ## Maximum connections per second.
+      ##
+      ## @doc zone.<name>.max_conn_rate
+      ## ValueType: Number | infinity
+      ## Default: 1000
+      ## Examples:
+      ##   max_conn_rate: 1000
+      max_conn_rate: 1000
+
+      ## Message limit for the a external MQTT connection.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_messages_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messages per 10 seconds.
+      ##   conn_messages_in: "100,10s"
+      conn_messages_in: "100,10s"
+
+      ## Limit the rate of receiving packets for a MQTT connection.
+      ## The rate is counted by bytes of packets per second.
+      ##
+      ## The connection won't accept more messages if the messages come
+      ## faster than the limit.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_bytes_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100KB incoming per 10 seconds.
+      ##   conn_bytes_in: "100KB,10s"
+      ##
+      conn_bytes_in: "100KB,10s"
+
+      ## Messages quota for the each of external MQTT connection.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.conn_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messaegs per 1s:
+      ##   quota.conn_messages_routing: "100,1s"
+      quota.conn_messages_routing: "100,1s"
+
+      ## Messages quota for the all of external MQTT connections.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.overall_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 200000 messages per 1s:
+      ##    quota.overall_messages_routing: "200000,1s"
+      ##
+      quota.overall_messages_routing: "200000,1s"
+    }
+
     ## TCP options
     ## TCP options
     ## See ${example_common_tcp_options} for more information
     ## See ${example_common_tcp_options} for more information
     tcp.backlog: 1024
     tcp.backlog: 1024
@@ -1377,13 +1388,11 @@ zone.default {
     ## The type of the listener.
     ## The type of the listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.type
     ## @doc zone.<name>.listeners.<name>.type
-    ## ValueType: tcp | ssl | ws | wss
+    ## ValueType: tcp | ws
     ##   - tcp: MQTT over TCP
     ##   - tcp: MQTT over TCP
-    ##   - ssl: MQTT over TLS
     ##   - ws:  MQTT over Websocket
     ##   - ws:  MQTT over Websocket
-    ##   - wss: MQTT over WebSocket Secure
     ## Required: true
     ## Required: true
-    type: ssl
+    type: tcp
 
 
     ## The IP address and port that the listener will bind.
     ## The IP address and port that the listener will bind.
     ##
     ##
@@ -1396,9 +1405,9 @@ zone.default {
     ## The size of the acceptor pool for this listener.
     ## The size of the acceptor pool for this listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.acceptors
     ## @doc zone.<name>.listeners.<name>.acceptors
-    ## ValueType: Number | num_cpu_cores
-    ## Default: num_cpu_cores
-    acceptors: num_cpu_cores
+    ## ValueType: Number
+    ## Default: 16
+    acceptors: 16
 
 
     ## Maximum number of concurrent connections.
     ## Maximum number of concurrent connections.
     ##
     ##
@@ -1441,8 +1450,64 @@ zone.default {
     ## Default: 3s
     ## Default: 3s
     proxy_protocol_timeout: 3s
     proxy_protocol_timeout: 3s
 
 
+    rate_limit {
+      ## Maximum connections per second.
+      ##
+      ## @doc zone.<name>.max_conn_rate
+      ## ValueType: Number | infinity
+      ## Default: 1000
+      ## Examples:
+      ##   max_conn_rate: 1000
+      max_conn_rate: 1000
+
+      ## Message limit for the a external MQTT connection.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_messages_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messages per 10 seconds.
+      ##   conn_messages_in: "100,10s"
+      conn_messages_in: "100,10s"
+
+      ## Limit the rate of receiving packets for a MQTT connection.
+      ## The rate is counted by bytes of packets per second.
+      ##
+      ## The connection won't accept more messages if the messages come
+      ## faster than the limit.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_bytes_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100KB incoming per 10 seconds.
+      ##   conn_bytes_in: "100KB,10s"
+      ##
+      conn_bytes_in: "100KB,10s"
+
+      ## Messages quota for the each of external MQTT connection.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.conn_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messaegs per 1s:
+      ##   quota.conn_messages_routing: "100,1s"
+      quota.conn_messages_routing: "100,1s"
+
+      ## Messages quota for the all of external MQTT connections.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.overall_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 200000 messages per 1s:
+      ##    quota.overall_messages_routing: "200000,1s"
+      ##
+      quota.overall_messages_routing: "200000,1s"
+    }
+
     ## SSL options
     ## SSL options
     ## See ${example_common_ssl_options} for more information
     ## See ${example_common_ssl_options} for more information
+    ssl.enable: true
     ssl.keyfile: "{{ platform_etc_dir }}/certs/key.pem"
     ssl.keyfile: "{{ platform_etc_dir }}/certs/key.pem"
     ssl.certfile: "{{ platform_etc_dir }}/certs/cert.pem"
     ssl.certfile: "{{ platform_etc_dir }}/certs/cert.pem"
     ssl.cacertfile: "{{ platform_etc_dir }}/certs/cacert.pem"
     ssl.cacertfile: "{{ platform_etc_dir }}/certs/cacert.pem"
@@ -1460,11 +1525,9 @@ zone.default {
     ## The type of the listener.
     ## The type of the listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.type
     ## @doc zone.<name>.listeners.<name>.type
-    ## ValueType: tcp | ssl | ws | wss
+    ## ValueType: tcp | ws
     ##   - tcp: MQTT over TCP
     ##   - tcp: MQTT over TCP
-    ##   - ssl: MQTT over TLS
     ##   - ws:  MQTT over Websocket
     ##   - ws:  MQTT over Websocket
-    ##   - wss: MQTT over WebSocket Secure
     ## Required: true
     ## Required: true
     type: ws
     type: ws
 
 
@@ -1479,9 +1542,9 @@ zone.default {
     ## The size of the acceptor pool for this listener.
     ## The size of the acceptor pool for this listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.acceptors
     ## @doc zone.<name>.listeners.<name>.acceptors
-    ## ValueType: Number | num_cpu_cores
-    ## Default: num_cpu_cores
-    acceptors: num_cpu_cores
+    ## ValueType: Number
+    ## Default: 16
+    acceptors: 16
 
 
     ## Maximum number of concurrent connections.
     ## Maximum number of concurrent connections.
     ##
     ##
@@ -1524,6 +1587,61 @@ zone.default {
     ## Default: 3s
     ## Default: 3s
     proxy_protocol_timeout: 3s
     proxy_protocol_timeout: 3s
 
 
+    rate_limit {
+      ## Maximum connections per second.
+      ##
+      ## @doc zone.<name>.max_conn_rate
+      ## ValueType: Number | infinity
+      ## Default: 1000
+      ## Examples:
+      ##   max_conn_rate: 1000
+      max_conn_rate: 1000
+
+      ## Message limit for the a external MQTT connection.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_messages_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messages per 10 seconds.
+      ##   conn_messages_in: "100,10s"
+      conn_messages_in: "100,10s"
+
+      ## Limit the rate of receiving packets for a MQTT connection.
+      ## The rate is counted by bytes of packets per second.
+      ##
+      ## The connection won't accept more messages if the messages come
+      ## faster than the limit.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_bytes_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100KB incoming per 10 seconds.
+      ##   conn_bytes_in: "100KB,10s"
+      ##
+      conn_bytes_in: "100KB,10s"
+
+      ## Messages quota for the each of external MQTT connection.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.conn_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messaegs per 1s:
+      ##   quota.conn_messages_routing: "100,1s"
+      quota.conn_messages_routing: "100,1s"
+
+      ## Messages quota for the all of external MQTT connections.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.overall_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 200000 messages per 1s:
+      ##    quota.overall_messages_routing: "200000,1s"
+      ##
+      quota.overall_messages_routing: "200000,1s"
+    }
+
     ## TCP options
     ## TCP options
     ## See ${example_common_tcp_options} for more information
     ## See ${example_common_tcp_options} for more information
     tcp.backlog: 1024
     tcp.backlog: 1024
@@ -1537,23 +1655,15 @@ zone.default {
   listeners.mqtt_wss:
   listeners.mqtt_wss:
   #${example_common_tcp_options} ${example_common_ssl_options} ${example_common_websocket_options} # common options can be written in a separate config entry and reference it from here.
   #${example_common_tcp_options} ${example_common_ssl_options} ${example_common_websocket_options} # common options can be written in a separate config entry and reference it from here.
   {
   {
-    ## The name of the listener.
-    ##
-    ## @doc zone.<name>.listeners.<name>.name
-    ## ValueType: String
-    ## Required: true
-    name: mqtt_over_wss
 
 
     ## The type of the listener.
     ## The type of the listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.type
     ## @doc zone.<name>.listeners.<name>.type
-    ## ValueType: tcp | ssl | ws | wss
+    ## ValueType: tcp | ws
     ##   - tcp: MQTT over TCP
     ##   - tcp: MQTT over TCP
-    ##   - ssl: MQTT over TLS
     ##   - ws:  MQTT over Websocket
     ##   - ws:  MQTT over Websocket
-    ##   - wss: MQTT over WebSocket Secure
     ## Required: true
     ## Required: true
-    type: wss
+    type: ws
 
 
     ## The IP address and port that the listener will bind.
     ## The IP address and port that the listener will bind.
     ##
     ##
@@ -1566,9 +1676,9 @@ zone.default {
     ## The size of the acceptor pool for this listener.
     ## The size of the acceptor pool for this listener.
     ##
     ##
     ## @doc zone.<name>.listeners.<name>.acceptors
     ## @doc zone.<name>.listeners.<name>.acceptors
-    ## ValueType: Number | num_cpu_cores
-    ## Default: num_cpu_cores
-    acceptors: num_cpu_cores
+    ## ValueType: Number
+    ## Default: 16
+    acceptors: 16
 
 
     ## Maximum number of concurrent connections.
     ## Maximum number of concurrent connections.
     ##
     ##
@@ -1611,8 +1721,64 @@ zone.default {
     ## Default: 3s
     ## Default: 3s
     proxy_protocol_timeout: 3s
     proxy_protocol_timeout: 3s
 
 
+    rate_limit {
+      ## Maximum connections per second.
+      ##
+      ## @doc zone.<name>.max_conn_rate
+      ## ValueType: Number | infinity
+      ## Default: 1000
+      ## Examples:
+      ##   max_conn_rate: 1000
+      max_conn_rate: 1000
+
+      ## Message limit for the a external MQTT connection.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_messages_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messages per 10 seconds.
+      ##   conn_messages_in: "100,10s"
+      conn_messages_in: "100,10s"
+
+      ## Limit the rate of receiving packets for a MQTT connection.
+      ## The rate is counted by bytes of packets per second.
+      ##
+      ## The connection won't accept more messages if the messages come
+      ## faster than the limit.
+      ##
+      ## @doc zone.<name>.rate_limit.conn_bytes_in
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100KB incoming per 10 seconds.
+      ##   conn_bytes_in: "100KB,10s"
+      ##
+      conn_bytes_in: "100KB,10s"
+
+      ## Messages quota for the each of external MQTT connection.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.conn_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 100 messaegs per 1s:
+      ##   quota.conn_messages_routing: "100,1s"
+      quota.conn_messages_routing: "100,1s"
+
+      ## Messages quota for the all of external MQTT connections.
+      ## This value consumed by the number of recipient on a message.
+      ##
+      ## @doc zone.<name>.rate_limit.quota.overall_messages_routing
+      ## ValueType: String | infinity
+      ## Default: infinity
+      ## Examples: 200000 messages per 1s:
+      ##    quota.overall_messages_routing: "200000,1s"
+      ##
+      quota.overall_messages_routing: "200000,1s"
+    }
+
     ## SSL options
     ## SSL options
     ## See ${example_common_ssl_options} for more information
     ## See ${example_common_ssl_options} for more information
+    ssl.enable: true
     ssl.keyfile: "{{ platform_etc_dir }}/certs/key.pem"
     ssl.keyfile: "{{ platform_etc_dir }}/certs/key.pem"
     ssl.certfile: "{{ platform_etc_dir }}/certs/cert.pem"
     ssl.certfile: "{{ platform_etc_dir }}/certs/cert.pem"
     ssl.cacertfile: "{{ platform_etc_dir }}/certs/cacert.pem"
     ssl.cacertfile: "{{ platform_etc_dir }}/certs/cacert.pem"

+ 67 - 68
apps/emqx/src/emqx_schema.erl

@@ -87,7 +87,7 @@ fields("cluster") ->
     ];
     ];
 
 
 fields("static") ->
 fields("static") ->
-    [ {"seeds", t(list(string()))}];
+    [ {"seeds", t(hoconsc:array(string()))}];
 
 
 fields("mcast") ->
 fields("mcast") ->
     [ {"addr", t(string(), undefined, "239.192.0.1")}
     [ {"addr", t(string(), undefined, "239.192.0.1")}
@@ -164,46 +164,56 @@ fields("rpc") ->
     ];
     ];
 
 
 fields("log") ->
 fields("log") ->
-    [ {"to", t(union([file, console, both]), undefined, file)}
-    , {"level", t(log_level(), undefined, warning)}
+    [ {"primary_level", t(log_level(), undefined, warning)}
+    , {"console_handler", ref("console_handler")}
+    , {"file_handlers", ref("file_handlers")}
     , {"time_offset", t(string(), undefined, "system")}
     , {"time_offset", t(string(), undefined, "system")}
-    , {"primary_log_level", t(log_level(), undefined, warning)}
-    , {"dir", t(string(), undefined, "log")}
-    , {"file", t(file(), undefined, "emqx.log")}
-    , {"chars_limit", t(integer(), undefined, -1)}
+    , {"chars_limit", maybe_infinity(integer())}
     , {"supervisor_reports", t(union([error, progress]), undefined, error)}
     , {"supervisor_reports", t(union([error, progress]), undefined, error)}
     , {"max_depth", t(union([infinity, integer()]),
     , {"max_depth", t(union([infinity, integer()]),
                       "kernel.error_logger_format_depth", 80)}
                       "kernel.error_logger_format_depth", 80)}
     , {"formatter", t(union([text, json]), undefined, text)}
     , {"formatter", t(union([text, json]), undefined, text)}
     , {"single_line", t(boolean(), undefined, true)}
     , {"single_line", t(boolean(), undefined, true)}
-    , {"rotation", ref("rotation")}
-    , {"size", t(union(bytesize(), infinity), undefined, infinity)}
     , {"sync_mode_qlen", t(integer(), undefined, 100)}
     , {"sync_mode_qlen", t(integer(), undefined, 100)}
     , {"drop_mode_qlen", t(integer(), undefined, 3000)}
     , {"drop_mode_qlen", t(integer(), undefined, 3000)}
     , {"flush_qlen", t(integer(), undefined, 8000)}
     , {"flush_qlen", t(integer(), undefined, 8000)}
-    , {"overload_kill", t(flag(), undefined, true)}
-    , {"overload_kill_mem_size", t(bytesize(), undefined, "30MB")}
-    , {"overload_kill_qlen", t(integer(), undefined, 20000)}
-    , {"overload_kill_restart_after", t(union(duration(), infinity), undefined, "5s")}
-    , {"burst_limit", t(comma_separated_list(), undefined, "disabled")}
+    , {"overload_kill", ref("log_overload_kill")}
+    , {"burst_limit", ref("log_burst_limit")}
     , {"error_logger", t(atom(), "kernel.error_logger", silent)}
     , {"error_logger", t(atom(), "kernel.error_logger", silent)}
-    , {"debug", ref("additional_log_file")}
-    , {"info", ref("additional_log_file")}
-    , {"notice", ref("additional_log_file")}
-    , {"warning", ref("additional_log_file")}
-    , {"error", ref("additional_log_file")}
-    , {"critical", ref("additional_log_file")}
-    , {"alert", ref("additional_log_file")}
-    , {"emergency", ref("additional_log_file")}
     ];
     ];
 
 
-fields("additional_log_file") ->
-    [ {"file", t(string())}];
+fields("console_handler") ->
+    [ {"enable", t(flag(), undefined, false)}
+    , {"level", t(log_level(), undefined, warning)}
+    ];
+
+fields("file_handlers") ->
+    [ {"$name", ref("log_file_handler")}
+    ];
+
+fields("log_file_handler") ->
+    [ {"level", t(log_level(), undefined, warning)}
+    , {"file", t(file(), undefined, undefined)}
+    , {"rotation", ref("log_rotation")}
+    , {"max_size", maybe_infinity(bytesize(), "10MB")}
+    ];
+
+fields("log_rotation") ->
+    [ {"enable", t(flag(), undefined, true)}
+    , {"count", t(range(1, 2048), undefined, 10)}
+    ];
+
+fields("log_overload_kill") ->
+    [ {"enable", t(flag(), undefined, true)}
+    , {"mem_size", t(bytesize(), undefined, "30MB")}
+    , {"qlen", t(integer(), undefined, 20000)}
+    , {"restart_after", t(union(duration(), infinity), undefined, "5s")}
+    ];
 
 
-fields("rotation") ->
+fields("log_burst_limit") ->
     [ {"enable", t(flag(), undefined, true)}
     [ {"enable", t(flag(), undefined, true)}
-    , {"size", t(bytesize(), undefined, "10MB")}
-    , {"count", t(integer(), undefined, 5)}
+    , {"max_count", t(integer(), undefined, 10000)}
+    , {"window_time", t(duration(), undefined, "1s")}
     ];
     ];
 
 
 fields("lager") ->
 fields("lager") ->
@@ -227,16 +237,16 @@ fields("acl") ->
 
 
 fields("acl_cache") ->
 fields("acl_cache") ->
     [ {"enable", t(boolean(), undefined, true)}
     [ {"enable", t(boolean(), undefined, true)}
-    , {"max_size", t(range(1, 1048576), undefined, 32)}
+    , {"max_size", maybe_infinity(range(1, 1048576), 32)}
     , {"ttl", t(duration(), undefined, "1m")}
     , {"ttl", t(duration(), undefined, "1m")}
     ];
     ];
 
 
 fields("mqtt") ->
 fields("mqtt") ->
     [ {"mountpoint", t(binary(), undefined, <<"">>)}
     [ {"mountpoint", t(binary(), undefined, <<"">>)}
-    , {"idle_timeout", t(duration(), undefined, "15s")}
-    , {"max_packet_size", t(bytesize(), undefined, "1MB")}
+    , {"idle_timeout", maybe_infinity(duration(), "15s")}
+    , {"max_packet_size", maybe_infinity(bytesize(), "1MB")}
     , {"max_clientid_len", t(integer(), undefined, 65535)}
     , {"max_clientid_len", t(integer(), undefined, 65535)}
-    , {"max_topic_levels", t(integer(), undefined, 0)}
+    , {"max_topic_levels", t(integer(), undefined, 65535)}
     , {"max_qos_allowed", t(range(0, 2), undefined, 2)}
     , {"max_qos_allowed", t(range(0, 2), undefined, 2)}
     , {"max_topic_alias", t(integer(), undefined, 65535)}
     , {"max_topic_alias", t(integer(), undefined, 65535)}
     , {"retain_available", t(boolean(), undefined, true)}
     , {"retain_available", t(boolean(), undefined, true)}
@@ -245,16 +255,16 @@ fields("mqtt") ->
     , {"ignore_loop_deliver", t(boolean())}
     , {"ignore_loop_deliver", t(boolean())}
     , {"strict_mode", t(boolean(), undefined, false)}
     , {"strict_mode", t(boolean(), undefined, false)}
     , {"response_information", t(string(), undefined, undefined)}
     , {"response_information", t(string(), undefined, undefined)}
-    , {"server_keepalive", t(integer())}
+    , {"server_keepalive", maybe_disabled(integer())}
     , {"keepalive_backoff", t(float(), undefined, 0.75)}
     , {"keepalive_backoff", t(float(), undefined, 0.75)}
-    , {"max_subscriptions", t(integer(), undefined, 0)}
+    , {"max_subscriptions", maybe_infinity(integer())}
     , {"upgrade_qos", t(flag(), undefined, false)}
     , {"upgrade_qos", t(flag(), undefined, false)}
-    , {"max_inflight", t(range(0, 65535))}
+    , {"max_inflight", t(range(1, 65535))}
     , {"retry_interval", t(duration_s(), undefined, "30s")}
     , {"retry_interval", t(duration_s(), undefined, "30s")}
-    , {"max_awaiting_rel", t(duration(), undefined, 0)}
+    , {"max_awaiting_rel", maybe_infinity(duration())}
     , {"await_rel_timeout", t(duration_s(), undefined, "300s")}
     , {"await_rel_timeout", t(duration_s(), undefined, "300s")}
     , {"session_expiry_interval", t(duration_s(), undefined, "2h")}
     , {"session_expiry_interval", t(duration_s(), undefined, "2h")}
-    , {"max_mqueue_len", t(integer(), undefined, 1000)}
+    , {"max_mqueue_len", maybe_infinity(integer(), 1000)}
     , {"mqueue_priorities", t(comma_separated_list(), undefined, "none")}
     , {"mqueue_priorities", t(comma_separated_list(), undefined, "none")}
     , {"mqueue_default_priority", t(union(highest, lowest), undefined, lowest)}
     , {"mqueue_default_priority", t(union(highest, lowest), undefined, lowest)}
     , {"mqueue_store_qos0", t(boolean(), undefined, true)}
     , {"mqueue_store_qos0", t(boolean(), undefined, true)}
@@ -275,20 +285,20 @@ fields("zone_settings") ->
     , {"force_shutdown", ref("force_shutdown")}
     , {"force_shutdown", ref("force_shutdown")}
     , {"conn_congestion", ref("conn_congestion")}
     , {"conn_congestion", ref("conn_congestion")}
     , {"force_gc", ref("force_gc")}
     , {"force_gc", ref("force_gc")}
-    , {"overall_max_connections", t(integer(), undefined, 2048000)}
+    , {"overall_max_connections", maybe_infinity(integer())}
     , {"listeners", t("listeners")}
     , {"listeners", t("listeners")}
     ];
     ];
 
 
 fields("rate_limit") ->
 fields("rate_limit") ->
     [ {"max_conn_rate", maybe_infinity(integer(), 1000)}
     [ {"max_conn_rate", maybe_infinity(integer(), 1000)}
-    , {"conn_messages_in", t(comma_separated_list())}
-    , {"conn_bytes_in", t(comma_separated_list())}
+    , {"conn_messages_in", maybe_infinity(comma_separated_list())}
+    , {"conn_bytes_in", maybe_infinity(comma_separated_list())}
     , {"quota", ref("rate_limit_quota")}
     , {"quota", ref("rate_limit_quota")}
     ];
     ];
 
 
 fields("rate_limit_quota") ->
 fields("rate_limit_quota") ->
-    [ {"conn_messages_routing", t(comma_separated_list())}
-    , {"overall_messages_routing", t(comma_separated_list())}
+    [ {"conn_messages_routing", maybe_infinity(comma_separated_list())}
+    , {"overall_messages_routing", maybe_infinity(comma_separated_list())}
     ];
     ];
 
 
 fields("flapping_detect") ->
 fields("flapping_detect") ->
@@ -331,32 +341,19 @@ fields("force_gc") ->
 
 
 fields("listeners") ->
 fields("listeners") ->
     [ {"$name", hoconsc:union(
     [ {"$name", hoconsc:union(
-        [ ref("mqtt_tcp_listener")
-        , ref("mqtt_ssl_listener")
-        , ref("mqtt_ws_listener")
-        , ref("mqtt_wss_listener")
+        [ hoconsc:ref("mqtt_tcp_listener")
+        , hoconsc:ref("mqtt_ws_listener")
         ])}
         ])}
     ];
     ];
 
 
 fields("mqtt_tcp_listener") ->
 fields("mqtt_tcp_listener") ->
-    [ {"type", t(typerefl:atom(tcp))}
+    [ {"type", t(tcp)}
     , {"tcp", ref("tcp_opts")}
     , {"tcp", ref("tcp_opts")}
-    ] ++ mqtt_listener();
-
-fields("mqtt_ssl_listener") ->
-    [ {"type", t(typerefl:atom(ssl))}
     , {"ssl", ref("ssl_opts")}
     , {"ssl", ref("ssl_opts")}
-    , {"tcp", ref("tcp_opts")}
     ] ++ mqtt_listener();
     ] ++ mqtt_listener();
 
 
 fields("mqtt_ws_listener") ->
 fields("mqtt_ws_listener") ->
-    [ {"type", t(typerefl:atom(ws))}
-    , {"tcp", ref("tcp_opts")}
-    , {"websocket", ref("ws_opts")}
-    ] ++ mqtt_listener();
-
-fields("mqtt_wss_listener") ->
-    [ {"type", t(typerefl:atom(ws))}
+    [ {"type", t(ws)}
     , {"tcp", ref("tcp_opts")}
     , {"tcp", ref("tcp_opts")}
     , {"ssl", ref("ssl_opts")}
     , {"ssl", ref("ssl_opts")}
     , {"websocket", ref("ws_opts")}
     , {"websocket", ref("ws_opts")}
@@ -366,8 +363,8 @@ fields("ws_opts") ->
     [ {"mqtt_path", t(string(), undefined, "/mqtt")}
     [ {"mqtt_path", t(string(), undefined, "/mqtt")}
     , {"mqtt_piggyback", t(union(single, multiple), undefined, multiple)}
     , {"mqtt_piggyback", t(union(single, multiple), undefined, multiple)}
     , {"compress", t(boolean())}
     , {"compress", t(boolean())}
-    , {"idle_timeout", t(duration())}
-    , {"max_frame_size", t(integer())}
+    , {"idle_timeout", maybe_infinity(duration())}
+    , {"max_frame_size", maybe_infinity(integer())}
     , {"fail_if_no_subprotocol", t(boolean(), undefined, true)}
     , {"fail_if_no_subprotocol", t(boolean(), undefined, true)}
     , {"supported_subprotocols", t(string(), undefined,
     , {"supported_subprotocols", t(string(), undefined,
         "mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5")}
         "mqtt, mqtt-v3, mqtt-v3.1.1, mqtt-v5")}
@@ -480,7 +477,7 @@ fields("sysmon_os") ->
     [ {"cpu_check_interval", t(duration_s(), undefined, 60)}
     [ {"cpu_check_interval", t(duration_s(), undefined, 60)}
     , {"cpu_high_watermark", t(percent(), undefined, "80%")}
     , {"cpu_high_watermark", t(percent(), undefined, "80%")}
     , {"cpu_low_watermark", t(percent(), undefined, "60%")}
     , {"cpu_low_watermark", t(percent(), undefined, "60%")}
-    , {"mem_check_interval", t(duration_s(), undefined, 60)}
+    , {"mem_check_interval", maybe_disabled(duration_s(), 60)}
     , {"sysmem_high_watermark", t(percent(), undefined, "70%")}
     , {"sysmem_high_watermark", t(percent(), undefined, "70%")}
     , {"procmem_high_watermark", t(percent(), undefined, "5%")}
     , {"procmem_high_watermark", t(percent(), undefined, "5%")}
     ];
     ];
@@ -503,9 +500,10 @@ fields(ExtraField) ->
 
 
 mqtt_listener() ->
 mqtt_listener() ->
     [ {"bind", t(union(ip_port(), integer()))}
     [ {"bind", t(union(ip_port(), integer()))}
-    , {"acceptors", t(integer(), undefined, 8)}
-    , {"max_connections", t(integer(), undefined, 1024000)}
-    , {"access", t(list(string()))}
+    , {"acceptors", t(integer(), undefined, 16)}
+    , {"max_connections", maybe_infinity(integer(), infinity)}
+    , {"rate_limit", ref("rate_limit")}
+    , {"access_rules", t(hoconsc:array(string()))}
     , {"proxy_protocol", t(flag())}
     , {"proxy_protocol", t(flag())}
     , {"proxy_protocol_timeout", t(duration())}
     , {"proxy_protocol_timeout", t(duration())}
     ].
     ].
@@ -1050,7 +1048,8 @@ filter(Opts) ->
 %%  ...]
 %%  ...]
 ssl(Defaults) ->
 ssl(Defaults) ->
     D = fun (Field) -> maps:get(list_to_atom(Field), Defaults, undefined) end,
     D = fun (Field) -> maps:get(list_to_atom(Field), Defaults, undefined) end,
-    [ {"cacertfile", t(string(), undefined, D("cacertfile"))}
+    [ {"enable", t(flag(), undefined, D("enable"))}
+    , {"cacertfile", t(string(), undefined, D("cacertfile"))}
     , {"certfile", t(string(), undefined, D("certfile"))}
     , {"certfile", t(string(), undefined, D("certfile"))}
     , {"keyfile", t(string(), undefined, D("keyfile"))}
     , {"keyfile", t(string(), undefined, D("keyfile"))}
     , {"verify", t(union(verify_peer, verify_none), undefined, D("verify"))}
     , {"verify", t(union(verify_peer, verify_none), undefined, D("verify"))}
@@ -1176,8 +1175,8 @@ maybe_disabled(T) ->
 maybe_disabled(T, Default) ->
 maybe_disabled(T, Default) ->
     maybe_sth(disabled, T, Default).
     maybe_sth(disabled, T, Default).
 
 
-% maybe_infinity(T) ->
-%     maybe_sth(infinity, T, infinity).
+maybe_infinity(T) ->
+    maybe_sth(infinity, T, infinity).
 
 
 maybe_infinity(T, Default) ->
 maybe_infinity(T, Default) ->
     maybe_sth(infinity, T, Default).
     maybe_sth(infinity, T, Default).
@@ -1215,7 +1214,7 @@ to_bytesize(Str) ->
 to_wordsize(Str) ->
 to_wordsize(Str) ->
     WordSize = erlang:system_info(wordsize),
     WordSize = erlang:system_info(wordsize),
     case to_bytesize(Str) of
     case to_bytesize(Str) of
-        {ok, Bytes} -> Bytes div WordSize;
+        {ok, Bytes} -> {ok, Bytes div WordSize};
         Error -> Error
         Error -> Error
     end.
     end.
 
 

+ 2 - 2
bin/emqx

@@ -582,7 +582,7 @@ case "$1" in
 
 
         # set before generate_config
         # set before generate_config
         if [ "${_EMQX_START_MODE:-}" = '' ]; then
         if [ "${_EMQX_START_MODE:-}" = '' ]; then
-            export EMQX_LOG__TO="${EMQX_LOG__TO:-console}"
+            export EMQX_CONSOLE_HANDLER__ENABLE="${EMQX_CONSOLE_HANDLER__ENABLE:-true}"
         fi
         fi
 
 
         #generate app.config and vm.args
         #generate app.config and vm.args
@@ -626,7 +626,7 @@ case "$1" in
         # or other supervision services
         # or other supervision services
 
 
         # set before generate_config
         # set before generate_config
-        export EMQX_LOG__TO="${EMQX_LOG__TO:-console}"
+        export EMQX_CONSOLE_HANDLER__ENABLE="${EMQX_CONSOLE_HANDLER__ENABLE:-true}"
 
 
         #generate app.config and vm.args
         #generate app.config and vm.args
         generate_config
         generate_config