zoukankan      html  css  js  c++  java
  • erlang 错误日志

    错误日志

    OTP系统已经内置了一个可定制的错误日志模块。我们可以从三种不同的视角来看错误日志。程序员的视角关注代码中要记录一个错误日志的函数调用?配置的视角关注错误日志如何存储以及保存在哪里?报告的视角则关心错误发生之后,如何进行分析。我们将逐条讲述这些内容。

    记录一个错误日志

    在程序员的视角,错误日志的API很简单,下面是这些API的一部分:

    @spec error_logger:error_msg(String) -> ok

    向错误日志发送一个错误消息

    1> error_logger:error_msg("An error has occurred ").

    =ERROR REPORT==== 28-Mar-2007::10:46:28 === An error has occurred

    ok

    @spec error_logger:error_msg(Format, Data) -> ok

    向错误日志发送一个错误消息。它的参数与io:format(Format, Data)函数的参数一样。

    2> error_logger:error_msg("~s, an error has occurred ", ["Joe"]).

    =ERROR REPORT==== 28-Mar-2007::10:47:09 === Joe, an error has occurred

    ok

    @spec error_logger:error_report(Report) -> ok

    向错误日志发送一个标准错误报告。

    @type Report = [{Tag, Data} | term()] | string() | term()]

    @type Tag = term()

    @type Data = term()

    3> error_logger:error_report([{tag1,data1},a_term,{tag2,data}]).

    =ERROR REPORT==== 28-Mar-2007::10:51:51 ===

    tag1: data1

    a_term tag2: data

    需要说明的是,这只是可用错误日志API中的一小部分。详细讨论这些API没啥意思。下面的例子中,我们也只会用到error_msg。完整的细节可以参考手册中error_logger的部分。

    配置错误日志

    可以对错误日志进行多种配置。在Erlangshell中我们可以看到所有的错误信息(如果我们什么都不配,这就是默认的配置)。我们可以把报告给shell中的错误写到一个格式化的文本文件中。此外,我们还能创建一个循环日志。你可以把循环日志想像成一个由错误日志产生的巨大环形缓存区域。新的消息进来时,会把它加到日志的尾部,如果日志被装满了,最早的条目就会被清除。

    循环日志是一个极有用的特性。你可以决定总共有多少个日志文件,以及单个日志文件的大小。系统负责帮你删除旧文件以及创建新文件,以维持整个巨大的环形数据区域。你可以调整日志大小,以用来记录最近几天的操作,这在大多数情况下都是绰绰有余的了。

    标准错误日志

    启动Erlang的时候,我们可以给系统设置一些启动参数:

    $ erl -boot start_clean

    这会创建一个适合程序开发的环境。只会提供错误日志的简单形式(不带boot参数的erl启动命令其效果等同于erl –boot start_clean)。

    $erl –boot start_sasl

    这会创建一个适合产品化系统的环境。SASLSystem Architecture Support Libraries的缩写,它负责错误日志,过载保护等等。

    谁也没法记住日志记录器的所有配置(也没这个必要),所以,最好还是把错误日志文件的配置信息记到一个配置文件中。 下面的小节,我们会考察默认配置下系统中的错误日志是如何工作的。然后会了解四种典型的配置方式下,错误日志不同的工作方式。

    不进行配置的SASL

    这是在SASL下启动,不进行配置的情况:

    $ erl -boot start_sasl

    Erlang (BEAM) emulator version 5.5.3 [async-threads:0] ...

    =PROGRESS REPORT==== 27-Mar-2007::11:49:12 ===

    supervisor: {local,sasl_safe_sup}

    started: [{pid,<0.32.0>},

    {name,alarm_handler},

    {mfa,{alarm_handler,start_link,[]}},

    {restart_type,permanent},

    {shutdown,2000},

    {child_type,worker}]

    ... many lines removed ...

    Eshell V5.5.3 (abort with ^G)

    现在我们调用error_logger的方法来报告错误:

    1> error_logger:error_msg("This is an error ").

    =ERROR REPORT==== 27-Mar-2007::11:53:08 === This is an error

    ok

    注意,错误是在Erlangshell中报告出来的。错误报告取决于错误日志记录器的配置。

    控制记录何种日志

    错误日志记录器会产生几种类型的报告:

    Supervisor报告

    Supervisor启动或者停止被监管的进程时,会产生这个报告(我们在18.5节监管树“第345页”中会讨论它)。

    Progress报告

    每次OTP监管进程启动或者停止的时候会产生这个报告。

    Crash报告

    当被监管的进程退出时,如果它的退出原因不是normal或者shutdown,就会产生这个报告。

    这三种报告是自动产生的,程序员无需关心。除此之外,当程序显式调用error_handler的方法时,也会产生三种日志报告。通过这三种报告,程序可以记录错误,警报以及提示信息。在这里,这三个术语并没有什么特别的语意,仅仅是程序员可以使用的三种标签,用来标明错误日志条目的自然属性(也就是说,想怎么用,随你)。

    在日后对错误日志进行分析的时候,我们可以用这三种标签协助我们来检查问题,过滤日志条目。在对日志进行配置的时候,我们也可以指定,比如,只保存错误,其他的信息不予保存。下面我们就来写一个这样的配置文件。

    elog1.config

    %% no tty

    [{sasl, [

    {sasl_error_logger, false}

    ]}].

    如果用这个配置文件启动系统,只有错误报告会被记录,progress报告之类的全部被忽略掉。而且,所有的错误都报告在shell当中。

    $ erl -boot start_sasl -config elog1

    1> error_logger:error_msg("This is an error ").

    =ERROR REPORT==== 27-Mar-2007::11:53:08 === This is an error

    Ok

    文本文件和shell

    无配置方法:

    erl -boot start_sasl -sasl sasl_error_logger {file,"path/to/logfile.log"} 

    %%有些{}不需转义.

    下一个配置文件,错误信息会同时出现在shell和一个文本文件之中:

    elog2.config

    %% single text file - minimal tty

    [{sasl, [

    %% All reports go to this file

    {sasl_error_logger, {file, "/home/joe/error_logs/THELOG" }}

    ]}].

    我们启动Erlang,生成一些错误信息,然后看看日志文件,以检查这个配置文件的效果。

    $ erl -boot start_sasl -config elog2

    1> error_logger:error_msg("This is an error ").

    =ERROR REPORT==== 27-Mar-2007::11:53:08 === This is an error ok

    我们可以查看/home/joe/error_logs/THELOG文件的内容,应该是这样的:

    =PROGRESS REPORT==== 28-Mar-2007::11:30:55 ===

    supervisor: {local,sasl_safe_sup}

    started: [{pid,<0.34.0>},

    {name,alarm_handler},

    {mfa,{alarm_handler,start_link,[]}},

    {restart_type,permanent},

    {shutdown,2000},

    {child_type,worker}]

    ...

    循环日志和Shell

    这个配置下,日志会在Shell以及一个循环日志中同时输出。这是一个很有用的配置。

    elog3.config

    %% rotating log and minimal tty

    [{sasl, [

    {sasl_error_logger, false},

    %% define the parameters of the rotating log

    %% the log file directory

    {error_logger_mf_dir,"/home/joe/error_logs" },

    %% # bytes per logfile

    {error_logger_mf_maxbytes,10485760}, % 10 MB

    %% maximum number of logfiles

    {error_logger_mf_maxfiles, 10}

    ]}].

    $erl -boot start_sasl -config elog3

    1> error_logger:error_msg("This is an error ").

    =ERROR REPORT==== 28-Mar-2007::11:36:19 === This is an error

    False

    当用这个配置运行系统的时候,所有的错误也会输出到这个循环日志中。本章后面的章节,我们会看到从日志中提取错误信息的方法。

    产品化环境

    在产品化环境中,我们只关注错误,而对progressinformation日志不感兴趣。所有我们在配置中让日志记录器仅仅记录错误。以免这些信息淹没在大量的progressinformation日志中。

    elog4.config

    %% rotating log and errors

    [{sasl, [

    %% minimise shell error logging

    {sasl_error_logger, false},

    %% only report errors

    {errlog_type, error},

    %% define the parameters of the rotating log

    %% the log file directory

    {error_logger_mf_dir,"/home/joe/error_logs" },

    %% # bytes per logfile

    {error_logger_mf_maxbytes,10485760}, % 10 MB

    %% maximum number of

    {error_logger_mf_maxfiles, 10}

    ]}].

    运行的时候,这个配置与前一个配置的效果看起来很相似,唯一的区别在于,只有错误会被记录到日志中。

    分析错误日志

    读取错误日志是rb模块的职责。它的接口相当简单。

    1> rb:help().

    Report Browser Tool - usage

    ===========================

    rb:start()  - start the rb_server with default options rb:start(Options) - where Options is a list of:

    {start_log, FileName}

    - default: standard_io

    {max, MaxNoOfReports}

    - MaxNoOfReports should be an integer or 'all'

    - default: all

    ...

    ... 此处省略很多行 ...

    ...

    我们启动report browser的时候可以指定它需要读取多少行(这个例子中,是最后的20行)

    2> rb:start([{max,20}]).

    rb: reading report...done.

    3> rb:list().

    No   Type       Process Date  Time

    ==   ====      ======= ====     ====

    11    progress <0.29.0> 2007-03-28 11:34:31

    10    progress <0.29.0> 2007-03-28 11:34:31

    9     progress <0.29.0> 2007-03-28 11:34:31

    8     progress <0.29.0> 2007-03-28 11:34:31

    7     progress <0.22.0> 2007-03-28 11:34:31

    6     progress <0.29.0> 2007-03-28 11:35:53

    5     progress <0.29.0> 2007-03-28 11:35:53

    4     progress <0.29.0> 2007-03-28 11:35:53

    3     progress <0.29.0> 2007-03-28 11:35:53

    2     progress <0.22.0> 2007-03-28 11:35:53

    1     error       <0.23.0> 2007-03-28 11:36:19

    ok

    > rb:show(1).

    ERROR REPORT <0.40.0>   2007-03-28 11:36:19

    ===========================================================

    This is an error ok

    要隔离一个特定的错误,我们可以使用rb:grep(RegExp)命令。它会找出所有匹配这个正则表达式的记录。我这里就不深入分析错误日志的细节问题了,学习它的最好方法是花一点时间,自己来和rb进行一些交互,看看都能做点什么。注意,你根本不需要自己来删日志,循环机制会删除旧的日志。

    如果你想要保留所有的日志,那么你就需要每隔一段特定的时间过来抓取,并自己进行清理。

  • 相关阅读:
    Atitit 人脸识别 眼睛形态 attilax总结
    Atitit 手机号码选号 规范 流程 attilax总结 v2 r99.docx
    atitit 板块分类 上市公司 龙头企业公司 列表 attilax总结.docx
    Atititi atiitt eam pam资产管理 购物表去年.xlsx
    使用cmd查看电脑连接过的wifi密码(一)
    常见十大web攻击手段 悟寰轩
    常见web攻击方式 悟寰轩
    【MYSQL数据库】MYSQL学习笔记mysql分区基本操作 悟寰轩
    Filter及FilterChain的使用详解 悟寰轩
    启动tomcat spring初始化两次问题(eg:@PostConstruct) 悟寰轩
  • 原文地址:https://www.cnblogs.com/xiao0913/p/3597121.html
Copyright © 2011-2022 走看看