You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让rebar3显示Erlang应用启动时的运行时错误?

Erlang应用切换rebar3构建后,启动运行时错误被隐藏,如何输出到stderr?

此前行为

之前使用原生编译启动方式:

  • 编译:erlc *.erl
  • 启动:erl -noshell -run server start

错误输出清晰,能直接定位关键错误(比如eaddrinuse):

{error,{badmatch,{error,eaddrinuse}},[{server,start,0,[{file,"server.erl"},{line,11}]},{init,start_it,1,[]},{init,start_em,1,[]},{init,do_boot,3,[]}]}
Runtime terminating during boot ({{badmatch,{error,eaddrinuse}},[{server,start,0,[{file,"server.erl"},{line,11}]},{init,start_it,1,[]},{init,start_em,1,[]},{init,do_boot,3,[]}]})

Crash dump is being written to: erl_crash.dump...done

当前行为

现在改用rebar3构建:

  • 编译:rebar3 compile
  • 启动:bin/prod foreground

输出仅显示笼统的终止信息,无法快速定位错误原因:

Exec: /web/erts-15.0/bin/erlexec -noinput +Bd -boot /web/releases/1.0.0/start -mode embedded -boot_var SYSTEM_LIB_DIR /web/lib -config /web/releases/1.0.0/sys.config -args_file /web/releases/1.0.0/vm.args -- foreground
Root: /web
/web
Runtime terminating during boot (terminating)

Crash dump is being written to: erl_crash.dump...done

(注:两种场景均运行在Docker容器中,暂不认为是容器导致的行为差异)

我的rebar.config配置

{erl_opts, [debug_info]}.
{deps,[  
  %% Packages
  {gen_smtp, "1.2.0"},
  {jiffy, "1.1.1"}
]}.

{shell, [
  % {config, "config/sys.config"},
    {apps, [lucos_monitoring]}
]}.

{relx, [{
  release,
  {prod, "1.0.0"},
  [lucos_monitoring,jiffy,gen_smtp,sasl,eunit,inets]
}]}.

{profiles, [
    {prod, [{relx, [{dev_mode, false},
                    {include_erts, true},
                {include_src, false}]} 
     ]}
]}.

已尝试的方法

  • 设置环境变量ERL_CRASH_DUMP=/dev/stderr和ERL_CRASH_DUMP_BYTES=8192:输出大量冗余信息,仍无法快速定位eaddrinuse这类关键错误
  • 设置环境变量DEBUG=1:无任何效果
  • 在rebar.config的prod profile中设置{dev_mode, true}:启动时出现加载失败错误Runtime terminating during boot ({load_failed,[heart,supervisor,lists,logger_simple_h,logger_config,logger_backend,logger_server,logger_filters,logger,kernel,gen_server,gen,file_server,file_io_server,filename,file,proc_lib,ets,error_logger,erl_parse,erl_lint,erl_eval,code,application_master,error_handler,application_controller,application,gen_event,code_server]})
  • 在rebar.config中添加{debug_info, keep}:无任何效果

解决方案

方法1:配置Erlang日志系统输出详细错误

在config/sys.config中添加日志配置,让内核和应用的错误信息直接输出到stderr:

[
 {kernel, [
    {logger, [
      {handler, default, logger_std_h, #{
        formatter => {logger_formatter, #{
          template => "[level] [time] [module]: ~p~n"
        }},
        level => debug,
        config => #{type => standard_error}
      }}
    ]},
    {error_logger, [{logger, true}]}
 ]},
 {lucos_monitoring, []}
]

然后在rebar.config的relx部分添加配置,确保打包时包含该文件:

{relx, [{
  release,
  {prod, "1.0.0"},
  [lucos_monitoring,jiffy,gen_smtp,sasl,eunit,inets]
},
{sys_config, "config/sys.config"}]}.

方法2:添加VM参数强制输出错误

启动时通过vm.args或启动命令追加+W w参数,让VM输出详细的警告和错误:

  • 修改vm.args文件,添加一行:+W w
  • 或者临时启动时执行:bin/prod foreground +W w

方法3:配置SASL输出错误日志

由于release依赖已包含sasl,可在sys.config中配置其错误日志输出到stderr:

[
 {sasl, [
    {sasl_error_logger, {file, "stderr"}}
 ]}
]

注:新版本Erlang中SASL错误日志已整合到logger系统,优先推荐方法1。

内容的提问来源于stack exchange,提问作者lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:12:17