【问题标题】:Why is erlang io:format output being lost and what do I need to do to restore it?为什么 erlang io:format 输出丢失,我需要做什么来恢复它?
【发布时间】:2012-04-27 23:50:59
【问题描述】:

我正在编写一个 gen_server,我们称之为 gen_server_db,它并没有什么特别之处。它使用的库(emysql)有可能在尝试查找数据库服务器(在 gen_server_db:init() 中)时遇到连接失败。当我捕捉到异常并尝试将某些内容打印到控制台时,我得到了 zip。在下面的代码示例中,两个 io:format 消息都无法到达控制台。我似乎记得很久以前听过这个原因,但我不记得为什么了。

init(Args) ->
    % I've condensed the way I actually get this stuff to one line, but if I have a
    % database online I connect properly, so I know that I'm getting the Host, User, etc.  
    {Host, User, Password, DB, PoolSize} = application:get_env(gen_server_db, config),

    init_mysql_connection(gen_server_db_pool, PoolSize, User, Password, Host, DB),

    % When the net connection to the db is down, I never get here.
    ok.

init_mysql_connection(bgo_db_pool, PoolSize, User, Password, Host, DB) ->
    try
        emysql:add_pool(bgo_db_pool, PoolSize, User, Password, Host, 3306, DB, utf8)
    catch
        exit:failed_to_connect_to_database ->
            io:format("Cannot connect to the mysql database server.  Retrying in 1 sec.~n"),
            timer:sleep(1000),
            init_mysql_connection(bgo_db_pool, PoolSize, User, Password, Host, DB);
        Error:Reason ->
            io:format("Database connection error: ~p:~p~n", [Error, Reason]),
            1/0
    end.

【问题讨论】:

  • 看起来组长重定向并没有发生,所以没有看到任何输出的一个可能原因是代码实际上并没有做到那么远。您是否尝试过调用 io:format() 作为 init(Args) 中的第一件事来说服自己您的 init 代码完全可以运行?此外,尝试启动 SASL 以在 gen_server 死亡时获取崩溃报告。

标签: erlang format gen-server


【解决方案1】:

通过 io:format 发送的所有 I/O 都发送到正在运行的进程的当前group_leader。然后这个进程负责使用 io:fwrite 打印消息。

如果你只是想在编码时转储一些调试信息,你可以使用 erlang:display/1

【讨论】:

  • 最后我在控制台上使用了global:register_name(io_format_target, group_leader()),和io:format(global:whereis_name(io_format_target), "foo~p~n", [bar ])。
【解决方案2】:

我建议您使用 error_logger 模块而不是 io:format。 io:format 将消息输出到 tty 控制台,一个标准输出。如果您的 gen_server 由控制台启动,您将看到这些消息,但是,如果您的服务器以分离模式启动,您将永远不会看到这些消息。

这是一本手册,您需要启动 SASL。

http://www.erlang.org/doc/man/error_logger.html

在您的配置文件中,您需要为此日志定义输出文件。

....
{sasl, [{sasl_error_logger, {file,"/tmp/sasl_error.log"}},{errlog_type, all}]}
....

【讨论】:

    猜你喜欢
    • 2013-07-22
    • 1970-01-01
    • 2018-01-07
    • 2019-08-22
    • 2010-12-08
    • 2021-01-03
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多