Просмотр исходного кода

2.0 - erlang.mk to replace rebar

Feng 9 лет назад
Родитель
Сommit
2e200f253f

+ 19 - 45
Makefile

@@ -1,54 +1,28 @@
-.PHONY: rel deps test plugins
+PROJECT = emqttd
+PROJECT_DESCRIPTION = Erlang MQTT Broker
+PROJECT_VERSION = 2.0
 
-APP      = emqttd
-BASE_DIR = $(shell pwd)
-REBAR    = $(BASE_DIR)/rebar
-DIST	 = $(BASE_DIR)/rel/$(APP)
+DEPS = gproc lager gen_logger gen_conf esockd mochiweb
 
-all: compile
+dep_gproc      = git https://github.com/uwiger/gproc.git
+dep_lager      = git https://github.com/basho/lager.git
+dep_gen_conf   = git https://github.com/emqtt/gen_conf.git
+dep_gen_logger = git https://github.com/emqtt/gen_logger.git
+dep_esockd     = git https://github.com/emqtt/esockd.git udp
+dep_mochiweb   = git https://github.com/emqtt/mochiweb.git
 
-# submods:
-#	@git submodule update --init
+ERLC_OPTS += +'{parse_transform, lager_transform}'
 
-compile: deps
-	@$(REBAR) compile
+EUNIT_OPTS = verbose
+EUNIT_ERL_OPTS = -args_file rel/vm.args -config rel/sys.config
 
-deps:
-	@$(REBAR) get-deps
+CT_SUITES = emqttd emqttd_access emqttd_backend emqttd_lib emqttd_mod emqttd_net \
+			emqttd_mqueue emqttd_protocol emqttd_topic emqttd_trie
+CT_OPTS = -cover test/ct.cover.spec -erl_args -name emqttd_ct@127.0.0.1 -config rel/sys.config
 
-update-deps:
-	@$(REBAR) update-deps
+COVER = true
 
-xref:
-	@$(REBAR) xref skip_deps=true
+include erlang.mk
 
-clean:
-	@$(REBAR) clean
-
-test:
-	ERL_FLAGS="-config rel/files/emqttd.test.config" $(REBAR) -v skip_deps=true ct
-	#$(REBAR) skip_deps=true eunit
-
-edoc:
-	@$(REBAR) doc
-
-rel: compile
-	@cd rel && $(REBAR) generate -f
-
-dist: rel
-
-PLT  = $(BASE_DIR)/.emqttd_dialyzer.plt
-APPS = erts kernel stdlib sasl crypto ssl os_mon syntax_tools \
-	   public_key mnesia inets compiler
-
-check_plt: compile
-	dialyzer --check_plt --plt $(PLT) --apps $(APPS) \
-		deps/*/ebin ./ebin plugins/*/ebin
-
-build_plt: compile
-	dialyzer --build_plt --output_plt $(PLT) --apps $(APPS) \
-		deps/*/ebin ./ebin plugins/*/ebin
-
-dialyzer: compile
-	dialyzer -Wno_return --plt $(PLT) deps/*/ebin ./ebin plugins/*/ebin
+app:: rebar.config
 

+ 323 - 0
bin/emqttd

@@ -0,0 +1,323 @@
+#!/bin/sh
+# -*- tab-width:4;indent-tabs-mode:nil -*-
+# ex: ts=4 sw=4 et
+
+# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
+if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
+    POSIX_SHELL="true"
+    export POSIX_SHELL
+    # To support 'whoami' add /usr/ucb to path
+    PATH=/usr/ucb:$PATH
+    export PATH
+    exec /usr/bin/ksh $0 "$@"
+fi
+unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well
+
+RUNNER_SCRIPT_DIR={{runner_script_dir}}
+RUNNER_SCRIPT=${0##*/}
+
+RUNNER_BASE_DIR={{runner_base_dir}}
+RUNNER_ETC_DIR={{runner_etc_dir}}
+RUNNER_LIB_DIR={{platform_lib_dir}}
+RUNNER_LOG_DIR={{runner_log_dir}}
+RUNNER_DATA_DIR=$RUNNER_BASE_DIR/data
+RUNNER_PLUGINS_DIR=$RUNNER_BASE_DIR/plugins
+
+# Note the trailing slash on $PIPE_DIR/
+PIPE_DIR={{pipe_dir}}
+RUNNER_USER={{runner_user}}
+PLATFORM_DATA_DIR={{platform_data_dir}}
+SSL_DIST_CONFIG=$PLATFORM_DATA_DIR/ssl_distribution.args_file
+RIAK_VERSION="git"
+
+WHOAMI=$(whoami)
+
+# Make sure this script is running as the appropriate user
+if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
+    type sudo > /dev/null 2>&1
+    if [ $? -ne 0 ]; then
+        echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
+        exit 1
+    fi
+    echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2
+    exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
+fi
+
+# Warn the user if ulimit -n is less than 1024
+ULIMIT_F=`ulimit -n`
+if [ "$ULIMIT_F" -lt 1024 ]; then
+    echo "!!!!"
+    echo "!!!! WARNING: ulimit -n is ${ULIMIT_F}; 1024 is the recommended minimum."
+    echo "!!!!"
+fi
+
+# Make sure CWD is set to runner base dir
+cd $RUNNER_BASE_DIR
+
+# Make sure log directory exists
+mkdir -p $RUNNER_LOG_DIR
+
+# Make sure the data directory exists
+mkdir -p $PLATFORM_DATA_DIR
+
+# Warn the user if they don't have write permissions on the log dir
+if [ ! -w $RUNNER_LOG_DIR ]; then
+    echo "!!!!"
+    echo "!!!! WARNING: $RUNNER_LOG_DIR not writable; logs and crash dumps unavailable."
+    echo "!!!!"
+fi
+
+# Extract the target node name from node.args
+NAME_ARG=`egrep '^\-s?name' $RUNNER_ETC_DIR/vm.args`
+if [ -z "$NAME_ARG" ]; then
+    echo "vm.args needs to have either -name or -sname parameter."
+    exit 1
+fi
+NODE_NAME=${NAME_ARG##* }
+
+# Extract the target cookie
+COOKIE_ARG=`grep '^\-setcookie' $RUNNER_ETC_DIR/vm.args`
+if [ -z "$COOKIE_ARG" ]; then
+    echo "vm.args needs to have a -setcookie parameter."
+    exit 1
+fi
+
+# Identify the script name
+SCRIPT=`basename $0`
+
+# Parse out release and erts info
+START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
+ERTS_VSN=${START_ERL% *}
+APP_VSN=${START_ERL#* }
+
+# Add ERTS bin dir to our path
+ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
+
+# Setup command to control the node
+NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
+NODETOOL_LITE="$ERTS_PATH/escript $ERTS_PATH/nodetool"
+
+# Common functions
+
+# Ping node without allowing nodetool to take stdin
+ping_node() {
+    $NODETOOL ping < /dev/null
+}
+
+# Set the PID global variable, return 1 on error
+get_pid() {
+    PID=`$NODETOOL getpid < /dev/null`
+    ES=$?
+    if [ "$ES" -ne 0 ]; then
+        echo "Node is not running!"
+        return 1
+    fi
+
+    # don't allow empty or init pid's
+    if [ -z $PID ] || [ "$PID" -le 1 ]; then
+        return 1
+    fi
+
+    return 0
+}
+
+
+# Scrape out SSL distribution config info from vm.args into $SSL_DIST_CONFIG
+rm -f $SSL_DIST_CONFIG
+sed -n '/Begin SSL distribution items/,/End SSL distribution items/p' \
+    $RUNNER_ETC_DIR/vm.args > $SSL_DIST_CONFIG
+
+# Check the first argument for instructions
+case "$1" in
+    start)
+        # Make sure there is not already a node running
+        RES=`ping_node`
+        if [ "$RES" = "pong" ]; then
+            echo "Node is already running!"
+            exit 1
+        fi
+        # Sanity check the emqttd.config file
+        RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
+        if [ $? != 0 ]; then
+            echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
+            echo $RES
+            exit 1
+        fi
+        HEART_COMMAND="$RUNNER_SCRIPT_DIR/$SCRIPT start"
+        export HEART_COMMAND
+        mkdir -p $PIPE_DIR
+        $ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR \
+            "exec $RUNNER_SCRIPT_DIR/$SCRIPT console" 2>&1
+
+        # Wait for the node to come up. We can't just ping it because
+        # distributed erlang comes up for a second before emqttd crashes
+        # (eg. in the case of an unwriteable disk). Once the node comes
+        # up we check for the node watcher process. If that's running
+        # then we assume things are good enough. This will at least let
+        # the user know when emqttd is crashing right after startup.
+        WAIT=${WAIT_FOR_ERLANG:-15}
+        while [ $WAIT -gt 0 ]; do
+            WAIT=`expr $WAIT - 1`
+            sleep 1
+            RES=`ping_node`
+            if [ "$?" -ne 0 ]; then
+                continue
+            fi
+	    echo "emqttd is started successfully!"
+            exit 0
+        done
+        echo "emqttd failed to start within ${WAIT_FOR_ERLANG:-15} seconds,"
+        echo "see the output of 'emqttd console' for more information."
+        echo "If you want to wait longer, set the environment variable"
+        echo "WAIT_FOR_ERLANG to the number of seconds to wait."
+        exit 1
+        ;;
+
+    stop)
+        UNAME_S=`uname -s`
+        case $UNAME_S in
+            Darwin)
+                # Make sure we explicitly set this because iTerm.app doesn't for
+                # some reason.
+                COMMAND_MODE=unix2003
+        esac
+
+        # Get the PID from nodetool
+        get_pid
+        GPR=$?
+        if [ "$GPR" -ne 0 ] || [ -z $PID ]; then
+            exit $GPR
+        fi
+
+        # Tell nodetool to initiate a stop
+        $NODETOOL stop
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+
+        # Wait for the node to completely stop...
+        while `kill -s 0 $PID 2>/dev/null`;
+        do
+            sleep 1
+        done
+        ;;
+
+    restart)
+        ## Restart the VM without exiting the process
+        $NODETOOL restart
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+        ;;
+
+    reboot)
+        ## Restart the VM completely (uses heart to restart it)
+        $NODETOOL reboot
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+        ;;
+
+    ping)
+        ## See if the VM is alive
+        ping_node
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+        ;;
+
+    attach)
+        if [ "$2" = "-f" ]; then
+          echo "Forcing connection..."
+        else
+          # Make sure a node is running
+          RES=`ping_node`
+          ES=$?
+          if [ "$ES" -ne 0 ]; then
+              echo "Node is not running!"
+              exit $ES
+          fi
+        fi
+
+        shift
+        exec $ERTS_PATH/to_erl $PIPE_DIR
+        ;;
+
+    console)
+        RES=`ping_node`
+        if [ "$RES" = "pong" ]; then
+            echo "Node is already running - use '$SCRIPT attach' instead"
+            exit 1
+        fi
+        # Sanity check the emqttd.config file
+        RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
+        if [ $? != 0 ]; then
+            echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
+            echo $RES
+            exit 1
+        fi
+        # Setup beam-required vars
+        ROOTDIR=$RUNNER_BASE_DIR
+        ERL_LIBS=$ROOTDIR/plugins
+        BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
+        EMU=beam
+        PROGNAME=`echo $0 | sed 's/.*\///'`
+        # Setup Mnesia Dir
+        MNESIA_DIR="$RUNNER_DATA_DIR/mnesia/$NODE_NAME"
+        CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$SCRIPT \
+            -embedded -config $RUNNER_ETC_DIR/emqttd.config \
+            -pa $RUNNER_LIB_DIR/basho-patches \
+            -mnesia dir "\"${MNESIA_DIR}\"" \
+            -args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"
+        export EMU
+        export ROOTDIR
+        export ERL_LIBS
+        export BINDIR
+        export PROGNAME
+
+        # Dump environment info for logging purposes
+        echo "Exec: $CMD"
+        echo "Root: $ROOTDIR"
+
+        # Log the startup
+        logger -t "$SCRIPT[$$]" "Starting up"
+
+        # Start the VM
+        exec $CMD
+        ;;
+    chkconfig)
+        RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
+        if [ $? != 0 ]; then
+            echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
+            echo $RES
+            exit 1
+        fi
+        echo "config is OK"
+        ;;
+    escript)
+        shift
+        $ERTS_PATH/escript "$@"
+        ;;
+    version)
+        echo $RIAK_VERSION
+        ;;
+    getpid)
+        # Get the PID from nodetool
+        get_pid
+        ES=$?
+        if [ "$ES" -ne 0 ] || [ -z $PID ]; then
+            exit $ES
+        fi
+        echo $PID
+        ;;
+    *)
+        echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach|chkconfig|escript|version|getpid}"
+        exit 1
+        ;;
+esac
+
+exit 0

+ 108 - 0
bin/emqttd.cmd

@@ -0,0 +1,108 @@
+@echo off
+@setlocal
+@setlocal enabledelayedexpansion
+
+@set node_name=emqttd
+
+@rem Get the absolute path to the parent directory,
+@rem which is assumed to be the node root.
+@for /F "delims=" %%I in ("%~dp0..") do @set node_root=%%~fI
+
+@set releases_dir=%node_root%\releases
+@set runner_etc_dir=%node_root%\etc
+
+@rem Parse ERTS version and release version from start_erl.data
+@for /F "usebackq tokens=1,2" %%I in ("%releases_dir%\start_erl.data") do @(
+    @call :set_trim erts_version %%I
+    @call :set_trim release_version %%J
+)
+
+@set vm_args=%runner_etc_dir%\vm.args
+@set sys_config=%runner_etc_dir%\emqttd.config
+@set node_boot_script=%releases_dir%\%release_version%\%node_name%
+@set clean_boot_script=%releases_dir%\%release_version%\start_clean
+
+@rem extract erlang cookie from vm.args
+@for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do @set erlang_cookie=%%J
+
+@set erts_bin=%node_root%\erts-%erts_version%\bin
+
+@set service_name=%node_name%_%release_version%
+
+@set erlsrv="%erts_bin%\erlsrv.exe"
+@set epmd="%erts_bin%\epmd.exe"
+@set escript="%erts_bin%\escript.exe"
+@set werl="%erts_bin%\werl.exe"
+
+@if "%1"=="usage" @goto usage
+@if "%1"=="install" @goto install
+@if "%1"=="uninstall" @goto uninstall
+@if "%1"=="start" @goto start
+@if "%1"=="stop" @goto stop
+@if "%1"=="restart" @call :stop && @goto start
+@if "%1"=="console" @goto console
+@if "%1"=="query" @goto query
+@if "%1"=="attach" @goto attach
+@if "%1"=="upgrade" @goto upgrade
+@echo Unknown command: "%1"
+
+:usage
+@echo Usage: %~n0 [install^|uninstall^|start^|stop^|restart^|console^|query^|attach^|upgrade]
+@goto :EOF
+
+:install
+@set description=Erlang node %node_name% in %node_root%
+@set start_erl=%node_root%\bin\start_erl.cmd
+@set args= ++ %node_name% ++ %node_root%
+@%erlsrv% add %service_name% -c "%description%" -sname %node_name% -w "%node_root%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()."
+@goto :EOF
+
+:uninstall
+@%erlsrv% remove %service_name%
+@%epmd% -kill
+@goto :EOF
+
+:start
+@%erlsrv% start %service_name%
+@goto :EOF
+
+:stop
+@%erlsrv% stop %service_name%
+@goto :EOF
+
+:console
+set dest_path=%~dp0
+cd /d !dest_path!..\plugins
+set current_path=%cd%
+set plugins=
+for /d %%P in (*) do (
+set "plugins=!plugins!"!current_path!\%%P\ebin" "
+)
+cd /d %node_root%
+
+@start "%node_name% console" %werl% -boot "%node_boot_script%" -config "%sys_config%" -args_file "%vm_args%" -sname %node_name% -pa %plugins%
+@goto :EOF
+
+:query
+@%erlsrv% list %service_name%
+@exit %ERRORLEVEL%
+@goto :EOF
+
+:attach
+@for /f "usebackq" %%I in (`hostname`) do @set hostname=%%I
+start "%node_name% attach" %werl% -boot "%clean_boot_script%" -remsh %node_name%@%hostname% -sname console -setcookie %erlang_cookie%
+@goto :EOF
+
+:upgrade
+@if "%2"=="" (
+    @echo Missing upgrade package argument
+    @echo Usage: %~n0 upgrade {package base name}
+    @echo NOTE {package base name} MUST NOT include the .tar.gz suffix
+    @goto :EOF
+)
+@%escript% %node_root%\bin\install_upgrade.escript %node_name% %erlang_cookie% %2
+@goto :EOF
+
+:set_trim
+@set %1=%2
+@goto :EOF

rel/files/emqttd_ctl → bin/emqttd_ctl


rel/files/emqttd_top → bin/emqttd_top


rel/files/install_upgrade.escript → bin/install_upgrade.escript


rel/files/nodetool → bin/nodetool


rel/files/start_erl.cmd → bin/start_erl.cmd


Разница между файлами не показана из-за своего большого размера
+ 2741 - 0
erlang.mk


+ 2 - 2
etc/emqttd.conf

@@ -190,7 +190,7 @@
 {bridge_max_queue_len, 10000}.
 
 %% Ping Interval of bridge node
-{bridge_ping_down_interval, 1} %seconds
+{bridge_ping_down_interval, 1}. % second
 
 %%-------------------------------------------------------------------
 %% Plugins
@@ -233,7 +233,7 @@
 %% Long GC, don't monitor in production mode for:
 %% https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421
 
-{sysmon_long_gc, false}. 
+{sysmon_long_gc, false}.
 
 %% Long Schedule(ms)
 {sysmon_long_schedule, 240}.


+ 0 - 49
rebar.config

@@ -1,49 +0,0 @@
-%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 ft=erlang et
-
-{require_min_otp_vsn, "R17"}.
-
-%% fail_on_warning,
-{erl_opts, [debug_info, {parse_transform, lager_transform}]}.
-
-{erl_opts, [warn_export_all,
-            warn_unused_import,
-            {i, "include"},
-			{src_dirs, ["src"]}]}.
-
-{validate_app_modules, true}.
-
-{erl_first_files, ["src/gen_server2.erl",
-                   "src/emqttd_auth_mod.erl",
-                   "src/emqttd_acl_mod.erl"]}.
-
-{eunit_opts, []}. %%verbose
-
-{ct_dir, "test"}.
-
-{ct_log_dir, "logs"}.
-
-{ct_extra_params, "-name ct_emqttd@127.0.0.1 -config rel/files/emqttd.test.config"}.
-
-{ct_use_short_names, false}.
-
-{xref_checks, [undefined_function_calls]}.
-
-{cover_enabled, true}.
-
-%% plugins cannot find emqttd.hrl without ".." lib dirs:(
-%% but this setting will make deps apps collision
-%% comment in 0.13.0 release
-%% {lib_dirs, ["../"]}.
-
-{sub_dirs, ["rel", "plugins/*/"]}.
-
-{deps, [
-	{gproc, ".*", {git, "git://github.com/uwiger/gproc.git", {branch, "master"}}},
-	{lager, ".*", {git, "git://github.com/basho/lager.git", {branch, "master"}}},
-	{gen_logger, ".*", {git, "git://github.com/emqtt/gen_logger.git", {branch, "master"}}},
-	{esockd, ".*", {git, "git://github.com/emqtt/esockd.git", {branch, "master"}}},
-	{mochiweb, "4.*", {git, "git://github.com/emqtt/mochiweb.git", {branch, "master"}}}
-]}.
-
-{recursive_cmds, [ct, eunit, clean]}.

+ 0 - 28
rel/files/acl.config

@@ -1,28 +0,0 @@
-%%%-----------------------------------------------------------------------------
-%%%
-%%% [ACL](https://github.com/emqtt/emqttd/wiki/ACL)
-%%%
-%%% -type who() :: all | binary() |
-%%%                {ipaddr, esockd_access:cidr()} |
-%%%                {client, binary()} |
-%%%                {user, binary()}.
-%%%
-%%% -type access() :: subscribe | publish | pubsub.
-%%%
-%%% -type topic() :: binary().
-%%%
-%%% -type rule() :: {allow, all} |
-%%%                 {allow, who(), access(), list(topic())} |
-%%%                 {deny, all} |
-%%%                 {deny, who(), access(), list(topic())}.
-%%%
-%%%-----------------------------------------------------------------------------
-
-{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
-
-{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
-
-{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
-
-{allow, all}.
-

+ 0 - 3
rel/files/clients.config

@@ -1,3 +0,0 @@
-testclientid0
-testclientid1 127.0.0.1
-testclientid2 192.168.0.1/24

+ 0 - 303
rel/files/emqttd.config.development

@@ -1,303 +0,0 @@
-% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ft=erlang ts=4 sw=4 et
-[{kernel, [
-    {start_timer, true},
-    {start_pg2, true}
- ]},
- {sasl, [
-    {sasl_error_logger, {file, "log/emqttd_sasl.log"}}
- ]},
- {ssl, [
-    %{versions, ['tlsv1.2', 'tlsv1.1']}
- ]},
- {lager, [
-    {colored, true},
-    {async_threshold, 1000},
-    {error_logger_redirect, false},
-    {crash_log, "log/emqttd_crash.log"},
-    {handlers, [
-        {lager_console_backend, info},
-        %%NOTICE: Level >= error
-        %%{lager_emqtt_backend, error},
-        {lager_file_backend, [
-            {formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]},
-            {file, "log/emqttd_info.log"},
-            {level, info},
-            {size, 104857600},
-            {date, "$D0"},
-            {count, 30}
-        ]},
-        {lager_file_backend, [
-            {formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]},
-            {file, "log/emqttd_error.log"},
-            {level, error},
-            {size, 104857600},
-            {date, "$D0"},
-            {count, 30}
-        ]}
-    ]}
- ]},
- {esockd, [
-    {logger, {lager, info}}
- ]},
- {emqttd, [
-    %% Authentication and Authorization
-    {access, [
-        %% Authetication. Anonymous Default
-        {auth, [
-            %% Authentication with username, password
-            %{username, []},
-            
-            %% Authentication with clientid
-            %{clientid, [{password, no}, {file, "etc/clients.config"}]},
-
-            %% Authentication with LDAP
-            % {ldap, [
-            %    {servers, ["localhost"]},
-            %    {port, 389},
-            %    {timeout, 30},
-            %    {user_dn, "uid=$u,ou=People,dc=example,dc=com"},
-            %    {ssl, fasle},
-            %    {sslopts, [
-            %        {certfile, "ssl.crt"},
-            %        {keyfile, "ssl.key"}]}
-            % ]},
-
-            %% Allow all
-            {anonymous, []}
-        ]},
-        %% ACL config
-        {acl, [
-            %% Internal ACL module
-            {internal,  [{file, "etc/acl.config"}, {nomatch, allow}]}
-        ]}
-    ]},
-    %% MQTT Protocol Options
-    {mqtt, [
-        %% Packet
-        {packet, [
-            %% Max ClientId Length Allowed
-            {max_clientid_len, 1024},
-            %% Max Packet Size Allowed, 64K default
-            {max_packet_size, 65536}
-        ]},
-        %% Client
-        {client, [
-            %% Socket is connected, but no 'CONNECT' packet received
-            {idle_timeout, 10} %% seconds
-        ]},
-        %% Session
-        {session, [
-            %% Max number of QoS 1 and 2 messages that can be “in flight” at one time.
-            %% 0 means no limit
-            {max_inflight, 100},
-
-            %% Retry interval for redelivering QoS1/2 messages.
-            {unack_retry_interval, 20},
-
-            %% Awaiting PUBREL Timeout
-            {await_rel_timeout, 20},
-
-            %% Max Packets that Awaiting PUBREL, 0 means no limit
-            {max_awaiting_rel, 0},
-
-            %% Statistics Collection Interval(seconds)
-            {collect_interval, 20},
-
-            %% Expired after 2 day (unit: minute)
-            {expired_after, 2880}
-
-        ]},
-        %% Queue
-        {queue, [
-            %% simple | priority
-            {type, simple},
-
-            %% Topic Priority: 0~255, Default is 0
-            %% {priority, [{"topic/1", 10}, {"topic/2", 8}]},
-
-            %% Max queue length. Enqueued messages when persistent client disconnected,
-            %% or inflight window is full.
-            {max_length, infinity},
-
-            %% Low-water mark of queued messages
-            {low_watermark, 0.2},
-
-            %% High-water mark of queued messages
-            {high_watermark, 0.6},
-
-            %% Queue Qos0 messages?
-            {queue_qos0, true}
-        ]}
-    ]},
-    %% Broker Options
-    {broker, [
-        %% System interval of publishing broker $SYS messages
-        {sys_interval, 60},
-
-        %% Retained messages
-        {retained, [
-            %% Expired after seconds, never expired if 0
-            {expired_after, 0},
-
-            %% Max number of retained messages
-            {max_message_num, 100000},
-
-            %% Max Payload Size of retained message
-            {max_playload_size, 65536}
-        ]},
-
-        %% PubSub and Router
-        {pubsub, [
-            %% Default should be scheduler numbers
-            {pool_size, 8},
-
-            %% Store Subscription: true | false
-            {subscription, true},
-
-            %% Route aging time(seconds)
-            {route_aging, 5}
-        ]},
-
-        %% Bridge
-        {bridge, [
-            %%TODO: bridge queue size
-            {max_queue_len, 10000},
-
-            %% Ping Interval of bridge node
-            {ping_down_interval, 1} %seconds
-        ]}
-    ]},
-    %% Modules
-    {modules, [
-        %% Client presence management module.
-        %% Publish messages when client connected or disconnected
-        {presence, [{qos, 0}]},
-
-        %% Subscribe topics automatically when client connected
-        {subscription, [
-
-            %% $c will be replaced by clientid
-            %% {"$queue/clients/$c", 1},
-
-            %% Static subscriptions from backend
-            backend
-        ]}
-
-        %% Rewrite rules
-        %% {rewrite, [{file, "etc/rewrite.config"}]}
-    ]},
-    %% Plugins
-    {plugins, [
-        %% Plugin App Library Dir
-        {plugins_dir, "./plugins"},
-
-        %% File to store loaded plugin names.
-        {loaded_file, "./data/loaded_plugins"}
-    ]},
-
-    %% Listeners
-    {listeners, [
-        {mqtt, 1883, [
-            %% Size of acceptor pool
-            {acceptors, 16},
-
-            %% Maximum number of concurrent clients
-            {max_clients, 512},
-
-            %% Socket Access Control
-            {access, [{allow, all}]},
-
-            %% Connection Options
-            {connopts, [
-                %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec
-                %% {rate_limit, "100,10"} %% 100K burst, 10K rate
-            ]},
-
-            %% Socket Options
-            {sockopts, [
-                %Set buffer if hight thoughtput
-                %{recbuf, 4096},
-                %{sndbuf, 4096},
-                %{buffer, 4096},
-                %{nodelay, true},
-                {backlog, 512}
-            ]}
-        ]},
-
-        {mqtts, 8883, [
-            %% Size of acceptor pool
-            {acceptors, 4},
-
-            %% Maximum number of concurrent clients
-            {max_clients, 512},
-
-            %% Socket Access Control
-            {access, [{allow, all}]},
-
-            %% SSL certificate and key files
-            {ssl, [{certfile, "etc/ssl/ssl.crt"},
-                   {keyfile,  "etc/ssl/ssl.key"}]},
-
-            %% Socket Options
-            {sockopts, [
-                {backlog, 1024}
-                %{buffer, 4096},
-            ]}
-        ]},
-        %% WebSocket over HTTPS Listener
-        %% {https, 8083, [
-        %%  %% Size of acceptor pool
-        %%  {acceptors, 4},
-        %%  %% Maximum number of concurrent clients
-        %%  {max_clients, 512},
-        %%  %% Socket Access Control
-        %%  {access, [{allow, all}]},
-        %%  %% SSL certificate and key files
-        %%  {ssl, [{certfile, "etc/ssl/ssl.crt"},
-        %%         {keyfile,  "etc/ssl/ssl.key"}]},
-        %%  %% Socket Options
-        %%  {sockopts, [
-        %%      %{buffer, 4096},
-        %%      {backlog, 1024}
-        %%  ]}
-        %%]},
-
-        %% HTTP and WebSocket Listener
-        {http, 8083, [
-            %% Size of acceptor pool
-            {acceptors, 4},
-            %% Maximum number of concurrent clients
-            {max_clients, 64},
-            %% Socket Access Control
-            {access, [{allow, all}]},
-            %% Socket Options
-            {sockopts, [
-                {backlog, 1024}
-                %{buffer, 4096},
-            ]}
-        ]}
-    ]},
-
-    %% Erlang System Monitor
-    {sysmon, [
-        %% Long GC
-        {long_gc, 100},
-
-        %% Long Schedule(ms)
-        {long_schedule, 100},
-
-        %% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM.
-        %% 8 * 1024 * 1024
-        {large_heap, 8388608},
-
-        %% Busy Port
-        {busy_port, true},
-
-        %% Busy Dist Port
-        {busy_dist_port, true}
-
-    ]}
- ]}
-].
-

+ 0 - 296
rel/files/emqttd.config.production

@@ -1,296 +0,0 @@
-% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ft=erlang ts=4 sw=4 et
-[{kernel, [
-    {start_timer, true},
-    {start_pg2, true}
- ]},
- {sasl, [
-    {sasl_error_logger, {file, "log/emqttd_sasl.log"}}
- ]},
- {ssl, [
-    %{versions, ['tlsv1.2', 'tlsv1.1']}
- ]},
- {lager, [
-    {colored, true},
-    {async_threshold, 5000},
-    {error_logger_redirect, false},
-    {crash_log, "log/emqttd_crash.log"},
-    {handlers, [
-        {lager_console_backend, error},
-        %%NOTICE: Level >= error
-        %%{lager_emqtt_backend, error},
-        {lager_file_backend, [
-            {formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]},
-            {file, "log/emqttd_error.log"},
-            {level, error},
-            {size, 104857600},
-            {date, "$D0"},
-            {count, 30}
-        ]}
-    ]}
- ]},
- {esockd, [
-    {logger, {lager, error}}
- ]},
- {emqttd, [
-    %% Authentication and Authorization
-    {access, [
-        %% Authetication. Anonymous Default
-        {auth, [
-            %% Authentication with username, password
-            %{username, []},
-            
-            %% Authentication with clientid
-            %{clientid, [{password, no}, {file, "etc/clients.config"}]},
-
-            %% Authentication with LDAP
-            % {ldap, [
-            %    {servers, ["localhost"]},
-            %    {port, 389},
-            %    {timeout, 30},
-            %    {user_dn, "uid=$u,ou=People,dc=example,dc=com"},
-            %    {ssl, fasle},
-            %    {sslopts, [
-            %        {certfile, "ssl.crt"},
-            %        {keyfile, "ssl.key"}]}
-            % ]},
-
-            %% Allow all
-            {anonymous, []}
-        ]},
-        %% ACL config
-        {acl, [
-            %% Internal ACL module
-            {internal,  [{file, "etc/acl.config"}, {nomatch, allow}]}
-        ]}
-    ]},
-    %% MQTT Protocol Options
-    {mqtt, [
-        %% Packet
-        {packet, [
-            %% Max ClientId Length Allowed
-            {max_clientid_len, 512},
-            %% Max Packet Size Allowed, 64K default
-            {max_packet_size, 65536}
-        ]},
-        %% Client
-        {client, [
-            %% Socket is connected, but no 'CONNECT' packet received
-            {idle_timeout, 30} %% seconds
-        ]},
-        %% Session
-        {session, [
-            %% Max number of QoS 1 and 2 messages that can be “in flight” at one time.
-            %% 0 means no limit
-            {max_inflight, 100},
-
-            %% Retry interval for redelivering QoS1/2 messages.
-            {unack_retry_interval, 60},
-
-            %% Awaiting PUBREL Timeout
-            {await_rel_timeout, 20},
-
-            %% Max Packets that Awaiting PUBREL, 0 means no limit
-            {max_awaiting_rel, 0},
-
-            %% Statistics Collection Interval(seconds)
-            {collect_interval, 0},
-
-            %% Expired after 2 day (unit: minute)
-            {expired_after, 2880}
-
-        ]},
-        %% Queue
-        {queue, [
-            %% simple | priority
-            {type, simple},
-
-            %% Topic Priority: 0~255, Default is 0
-            %% {priority, [{"topic/1", 10}, {"topic/2", 8}]},
-
-            %% Max queue length. Enqueued messages when persistent client disconnected,
-            %% or inflight window is full.
-            {max_length, infinity},
-
-            %% Low-water mark of queued messages
-            {low_watermark, 0.2},
-
-            %% High-water mark of queued messages
-            {high_watermark, 0.6},
-
-            %% Queue Qos0 messages?
-            {queue_qos0, true}
-        ]}
-    ]},
-    %% Broker Options
-    {broker, [
-        %% System interval of publishing broker $SYS messages
-        {sys_interval, 60},
-
-        %% Retained messages
-        {retained, [
-            %% Expired after seconds, never expired if 0
-            {expired_after, 0},
-
-            %% Max number of retained messages
-            {max_message_num, 100000},
-
-            %% Max Payload Size of retained message
-            {max_playload_size, 65536}
-        ]},
-
-        %% PubSub and Router
-        {pubsub, [
-            %% Default should be scheduler numbers
-            {pool_size, 8},
-
-            %% Store Subscription: true | false
-            {subscription, true},
-
-            %% Route aging time(seconds)
-            {route_aging, 5}
-        ]},
-
-        %% Bridge
-        {bridge, [
-            %%TODO: bridge queue size
-            {max_queue_len, 10000},
-
-            %% Ping Interval of bridge node
-            {ping_down_interval, 1} %seconds
-        ]}
-    ]},
-    %% Modules
-    {modules, [
-        %% Client presence management module.
-        %% Publish messages when client connected or disconnected
-        {presence, [{qos, 0}]},
-
-        %% Subscribe topics automatically when client connected
-        {subscription, [
-
-            %% $c will be replaced by clientid
-            %% {"$queue/clients/$c", 1},
-
-            %% Static subscriptions from backend
-            backend
-        ]}
-
-        %% Rewrite rules
-        %% {rewrite, [{file, "etc/rewrite.config"}]}
-    ]},
-    %% Plugins
-    {plugins, [
-        %% Plugin App Library Dir
-        {plugins_dir, "./plugins"},
-
-        %% File to store loaded plugin names.
-        {loaded_file, "./data/loaded_plugins"}
-    ]},
-
-    %% Listeners
-    {listeners, [
-        {mqtt, 1883, [
-            %% Size of acceptor pool
-            {acceptors, 16},
-
-            %% Maximum number of concurrent clients
-            {max_clients, 512},
-
-            %% Socket Access Control
-            {access, [{allow, all}]},
-
-            %% Connection Options
-            {connopts, [
-                %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec
-                %% {rate_limit, "100,10"} %% 100K burst, 10K rate
-            ]},
-
-            %% Socket Options
-            {sockopts, [
-                %Set buffer if hight thoughtput
-                %{recbuf, 4096},
-                %{sndbuf, 4096},
-                %{buffer, 4096},
-                %{nodelay, true},
-                {backlog, 1024}
-            ]}
-        ]},
-
-        {mqtts, 8883, [
-            %% Size of acceptor pool
-            {acceptors, 4},
-
-            %% Maximum number of concurrent clients
-            {max_clients, 512},
-
-            %% Socket Access Control
-            {access, [{allow, all}]},
-
-            %% SSL certificate and key files
-            {ssl, [{certfile, "etc/ssl/ssl.crt"},
-                   {keyfile,  "etc/ssl/ssl.key"}]},
-
-            %% Socket Options
-            {sockopts, [
-                {backlog, 1024}
-                %{buffer, 4096},
-            ]}
-        ]},
-        %% WebSocket over HTTPS Listener
-        %% {https, 8083, [
-        %%  %% Size of acceptor pool
-        %%  {acceptors, 4},
-        %%  %% Maximum number of concurrent clients
-        %%  {max_clients, 512},
-        %%  %% Socket Access Control
-        %%  {access, [{allow, all}]},
-        %%  %% SSL certificate and key files
-        %%  {ssl, [{certfile, "etc/ssl/ssl.crt"},
-        %%         {keyfile,  "etc/ssl/ssl.key"}]},
-        %%  %% Socket Options
-        %%  {sockopts, [
-        %%      %{buffer, 4096},
-        %%      {backlog, 1024}
-        %%  ]}
-        %%]},
-
-        %% HTTP and WebSocket Listener
-        {http, 8083, [
-            %% Size of acceptor pool
-            {acceptors, 4},
-            %% Maximum number of concurrent clients
-            {max_clients, 64},
-            %% Socket Access Control
-            {access, [{allow, all}]},
-            %% Socket Options
-            {sockopts, [
-                {backlog, 1024}
-                %{buffer, 4096},
-            ]}
-        ]}
-    ]},
-
-    %% Erlang System Monitor
-    {sysmon, [
-        %% Long GC, don't monitor in production mode for:
-        %% https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421
-        {long_gc, false},
-
-        %% Long Schedule(ms)
-        {long_schedule, 240},
-
-        %% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM.
-        %% 8 * 1024 * 1024
-        {large_heap, 8388608},
-
-        %% Busy Port
-        {busy_port, false},
-
-        %% Busy Dist Port
-        {busy_dist_port, true}
-
-    ]}
- ]}
-].
-

+ 0 - 34
rel/files/erl

@@ -1,34 +0,0 @@
-#!/bin/sh
-
-## This script replaces the default "erl" in erts-VSN/bin. This is necessary
-## as escript depends on erl and in turn, erl depends on having access to a
-## bootscript (start.boot). Note that this script is ONLY invoked as a side-effect
-## of running escript -- the embedded node bypasses erl and uses erlexec directly
-## (as it should).
-##
-## Note that this script makes the assumption that there is a start_clean.boot
-## file available in $ROOTDIR/release/VSN.
-
-# Determine the abspath of where this script is executing from.
-ERTS_BIN_DIR=$(cd ${0%/*} && pwd)
-
-# Now determine the root directory -- this script runs from erts-VSN/bin,
-# so we simply need to strip off two dirs from the end of the ERTS_BIN_DIR
-# path.
-ROOTDIR=${ERTS_BIN_DIR%/*/*}
-
-# Parse out release and erts info
-START_ERL=`cat $ROOTDIR/releases/start_erl.data`
-ERTS_VSN=${START_ERL% *}
-APP_VSN=${START_ERL#* }
-
-BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
-EMU=beam
-PROGNAME=`echo $0 | sed 's/.*\\///'`
-CMD="$BINDIR/erlexec"
-export EMU
-export ROOTDIR
-export BINDIR
-export PROGNAME
-
-exec $CMD -boot $ROOTDIR/releases/$APP_VSN/start_clean ${1+"$@"}

+ 0 - 0
rel/files/loaded_plugins


+ 38 - 0
rel/sys.config

@@ -0,0 +1,38 @@
+% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ft=erlang ts=4 sw=4 et
+[{kernel, [
+    {start_timer, true},
+    {start_pg2, true}
+ ]},
+ {sasl, [
+    {sasl_error_logger, {file, "log/emqttd_sasl.log"}}
+ ]},
+ {ssl, [
+    %{versions, ['tlsv1.2', 'tlsv1.1']}
+ ]},
+ {esockd, [
+    {logger, {lager, error}}
+ ]},
+ {lager, [
+    {colored, true},
+    {async_threshold, 5000},
+    {error_logger_redirect, false},
+    {crash_log, "log/emqttd_crash.log"},
+    {handlers, [
+        {lager_console_backend, error},
+        %%NOTICE: Level >= error
+        %%{lager_emqtt_backend, error},
+        {lager_file_backend, [
+            {formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]},
+            {file, "log/emqttd_error.log"},
+            {level, error},
+            {size, 104857600},
+            {date, "$D0"},
+            {count, 30}
+        ]}
+    ]}
+ ]},
+ {emqttd, [
+    {gen_conf, "etc/emqttd.conf"}
+ ]}
+].

rel/files/vm.args → rel/vm.args


+ 1 - 0
src/emqttd_app.erl

@@ -46,6 +46,7 @@
       Reason    :: term()).
 start(_StartType, _StartArgs) ->
     print_banner(),
+    gen_conf:init(emqttd),
     emqttd_mnesia:start(),
     {ok, Sup} = emqttd_sup:start_link(),
     start_servers(Sup),

+ 12 - 2
src/emqttd_sysmon_sup.erl

@@ -28,7 +28,17 @@ start_link() ->
     supervisor:start_link({local, ?MODULE}, ?MODULE, []).
 
 init([]) ->
-    Sysmon = {sysmon, {emqttd_sysmon, start_link, [emqttd:env(sysmon)]},
-                permanent, 5000, worker, [emqttd_sysmon]} ,
+    Sysmon = {sysmon, {emqttd_sysmon, start_link, [opts()]},
+                permanent, 5000, worker, [emqttd_sysmon]},
     {ok, {{one_for_one, 10, 100}, [Sysmon]}}.
 
+opts() ->
+    Opts = [{long_gc,        config(sysmon_long_gc)},
+            {long_schedule,  config(sysmon_long_schedule)},
+            {large_heap,     config(sysmon_large_heap)},
+            {busy_port,      config(busy_port)},
+            {busy_dist_port, config(sysmon_busy_dist_port)}],
+    [{Key, Val} || {Key, {ok, Val}} <- Opts].
+
+config(Key) -> gen_conf:value(emqttd, Key).
+