From 4bc8f0d44b460b9e8d9b94a80d546a680fea0fe3 Mon Sep 17 00:00:00 2001 From: "Zaiming (Stone) Shi" Date: Fri, 11 Mar 2022 10:06:15 +0100 Subject: [PATCH 1/3] feat: allow enable/disable an existing logger file handler --- apps/emqx_conf/etc/emqx_conf.conf | 1 + apps/emqx_conf/src/emqx_conf_schema.erl | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/apps/emqx_conf/etc/emqx_conf.conf b/apps/emqx_conf/etc/emqx_conf.conf index b6c2b37ed..9f2f46b5e 100644 --- a/apps/emqx_conf/etc/emqx_conf.conf +++ b/apps/emqx_conf/etc/emqx_conf.conf @@ -544,6 +544,7 @@ log { ##---------------------------------------------------------------- ## file_handlers. file_handlers.default { + enable = true ## The log level filter of this handler ## All the log messages with levels lower than this level will ## be dropped. diff --git a/apps/emqx_conf/src/emqx_conf_schema.erl b/apps/emqx_conf/src/emqx_conf_schema.erl index 1102facf1..aa8c64bf1 100644 --- a/apps/emqx_conf/src/emqx_conf_schema.erl +++ b/apps/emqx_conf/src/emqx_conf_schema.erl @@ -586,11 +586,7 @@ fields("log") -> ]; fields("console_handler") -> - [ {"enable", - sc(boolean(), - #{ default => false - })} - ] ++ log_handler_common_confs(); + log_handler_common_confs(); fields("log_file_handler") -> [ {"file", @@ -704,13 +700,21 @@ tr_cluster_discovery(Conf) -> tr_logger_level(Conf) -> ConsoleLevel = conf_get("log.console_handler.level", Conf, undefined), FileLevels = [conf_get("level", SubConf) || {_, SubConf} - <- maps:to_list(conf_get("log.file_handlers", Conf, #{}))], + <- logger_file_handlers(Conf)], case FileLevels ++ [ConsoleLevel || ConsoleLevel =/= undefined] of [] -> warning; %% warning is the default level we should use Levels -> least_severe_log_level(Levels) end. +logger_file_handlers(Conf) -> + Handlers = maps:to_list(conf_get("log.file_handlers", Conf, #{})), + lists:filter(fun({_Name, Opts}) -> + B = conf_get("enable", Opts), + true = is_boolean(B), + B + end, Handlers). + tr_logger(Conf) -> %% For the default logger that outputs to console ConsoleHandler = @@ -743,12 +747,15 @@ tr_logger(Conf) -> filters => log_filter(SubConf), filesync_repeat_interval => no_repeat }} - end || {HandlerName, SubConf} <- maps:to_list(conf_get("log.file_handlers", Conf, #{}))], - + end || {HandlerName, SubConf} <- logger_file_handlers(Conf)], [{handler, default, undefined}] ++ ConsoleHandler ++ FileHandlers. log_handler_common_confs() -> - [ {"level", + [ {"enable", + sc(boolean(), + #{ default => false + })} + , {"level", sc(log_level(), #{ default => warning , desc => "Global log level. This includes the primary log level " From 122e75c0b47a7573c1845f6b11db561ffa74908d Mon Sep 17 00:00:00 2001 From: "Zaiming (Stone) Shi" Date: Fri, 11 Mar 2022 07:41:21 +0100 Subject: [PATCH 2/3] feat(systemd): start EMQX under systemd in foreground mode --- bin/emqx | 53 ++++++++++++++++++++++++++++++++---- deploy/packages/emqx.service | 29 +++++++++++++++++--- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/bin/emqx b/bin/emqx index 7e1f2dd12..1cfc36481 100755 --- a/bin/emqx +++ b/bin/emqx @@ -540,6 +540,48 @@ latest_vm_args() { fi } +# backward compabible with 4.x +tr_log_to_env() { + local log_to=${EMQX_LOG__TO:-undefined} + # unset because it's unknown to 5.0 + unset EMQX_LOG__TO + case "${log_to}" in + console) + export EMQX_LOG__CONSOLE_HANDLER__ENABLE='true' + export EMQX_LOG__FILE_HANDLERS__DEFAULT__ENABLE='false' + ;; + file) + export EMQX_LOG__CONSOLE_HANDLER__ENABLE='false' + export EMQX_LOG__FILE_HANDLERS__DEFAULT__ENABLE='true' + ;; + both) + export EMQX_LOG__CONSOLE_HANDLER__ENABLE='true' + export EMQX_LOG__FILE_HANDLERS__DEFAULT__ENABLE='true' + ;; + default) + # want to use config file defaults, do nothing + ;; + undefined) + # value not set, do nothing + ;; + *) + echoerr "Unknown environment value for EMQX_LOG__TO=${log_to} discarded" + ;; + esac +} + +maybe_log_to_console() { + if [ "${EMQX_LOG__TO:-}" = 'default' ]; then + # want to use config file defaults, do nothing + unset EMQX_LOG__TO + else + tr_log_to_env + # ensure defaults + export EMQX_LOG__CONSOLE_HANDLER__ENABLE="${EMQX_LOG__CONSOLE_HANDLER__ENABLE:-true}" + export EMQX_LOG__FILE_HANDLERS__DEFAULT__ENABLE="${EMQX_LOG__FILE_HANDLERS__DEFAULT__ENABLE:-false}" + fi +} + ## IS_BOOT_COMMAND is set for later to inspect node name and cookie from hocon config (or env variable) case "${COMMAND}" in start|console|console_clean|foreground) @@ -621,7 +663,7 @@ case "${COMMAND}" in # this flag passes down to console mode # so we know it's intended to be run in daemon mode - export _EMQX_START_MODE="$COMMAND" + export _EMQX_START_DAEMON_MODE=1 case "$COMMAND" in start) @@ -764,8 +806,10 @@ case "${COMMAND}" in esac # set before generate_config - if [ "${_EMQX_START_MODE:-}" = '' ]; then - export EMQX_LOG__CONSOLE_HANDLER__ENABLE="${EMQX_LOG__CONSOLE_HANDLER__ENABLE:-true}" + if [ "${_EMQX_START_DAEMON_MODE:-}" = 1 ]; then + tr_log_to_env + else + maybe_log_to_console fi #generate app.config and vm.args @@ -815,8 +859,7 @@ case "${COMMAND}" in # start up the release in the foreground for use by runit # or other supervision services - # set before generate_config - export EMQX_LOG__CONSOLE_HANDLER__ENABLE="${EMQX_LOG__CONSOLE_HANDLER__ENABLE:-true}" + maybe_log_to_console #generate app.config and vm.args generate_config "$NAME_TYPE" "$NAME" diff --git a/deploy/packages/emqx.service b/deploy/packages/emqx.service index ef9abfb01..29877674e 100644 --- a/deploy/packages/emqx.service +++ b/deploy/packages/emqx.service @@ -5,13 +5,34 @@ After=network.target [Service] User=emqx Group=emqx -Type=forking + +# The ExecStart= is foreground, so 'simple' here +Type=simple Environment=HOME=/var/lib/emqx -ExecStart=/usr/bin/emqx start + +# Enable logging to file +Environment=EMQX_LOG__TO=default + +# Start 'foregroun' but not 'start' (daemon) mode. +# Because systemd monitor/restarts 'simple' services +ExecStart=/usr/bin/emqx foreground + +# Give EMQX enough file descriptors LimitNOFILE=1048576 -ExecStop=/usr/bin/emqx stop + +# ExecStop is commented out so systemd will send a SIGTERM when 'systemctl stop'. +# SIGTERM is handled by EMQX and it then performs a graceful shutdown +# It's better than command 'emqx stop' because it needs to ping the node +# ExecStop=/usr/bin/emqx stop + +# Wait long enough before force kill for graceful shutdown +TimeoutStopSec=120s + Restart=on-failure -RestartSec=5s + +# Do not restart immediately so the peer nodes in the cluster have +# enough time to handle the 'DOWN' events of this node +RestartSec=120s [Install] WantedBy=multi-user.target From a216f1bf18b5a51ed86bdc1822a98f8658b2a49e Mon Sep 17 00:00:00 2001 From: "Zaiming (Stone) Shi" Date: Fri, 11 Mar 2022 12:26:43 +0100 Subject: [PATCH 3/3] chore: emqx.service shard for deb and rpm --- deploy/packages/rpm/emqx.service | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) mode change 100644 => 120000 deploy/packages/rpm/emqx.service diff --git a/deploy/packages/rpm/emqx.service b/deploy/packages/rpm/emqx.service deleted file mode 100644 index ef9abfb01..000000000 --- a/deploy/packages/rpm/emqx.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=emqx daemon -After=network.target - -[Service] -User=emqx -Group=emqx -Type=forking -Environment=HOME=/var/lib/emqx -ExecStart=/usr/bin/emqx start -LimitNOFILE=1048576 -ExecStop=/usr/bin/emqx stop -Restart=on-failure -RestartSec=5s - -[Install] -WantedBy=multi-user.target diff --git a/deploy/packages/rpm/emqx.service b/deploy/packages/rpm/emqx.service new file mode 120000 index 000000000..2fc64d79d --- /dev/null +++ b/deploy/packages/rpm/emqx.service @@ -0,0 +1 @@ +../emqx.service \ No newline at end of file