Sfoglia il codice sorgente

Merge pull request #7282 from zmstone/build-refine-systemd-service-unit

Start EMQX in foreground mode in systemd
Zaiming (Stone) Shi 3 anni fa
parent
commit
acd9aaff4d

+ 1 - 0
apps/emqx_conf/etc/emqx_conf.conf

@@ -544,6 +544,7 @@ log {
   ##----------------------------------------------------------------
   ## file_handlers.<name>
   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.

+ 16 - 9
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 "

+ 48 - 5
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"

+ 25 - 4
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

+ 0 - 17
deploy/packages/rpm/emqx.service

@@ -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

+ 1 - 0
deploy/packages/rpm/emqx.service

@@ -0,0 +1 @@
+../emqx.service