论坛首页 综合技术论坛

给sasl日志增加过滤功能

浏览 2450 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-09-16  

    sasl中的error_logger_mf日志处理器,是基于log_mf_h的。其有一个日志信息的过滤接口,但在sasl中并没有实现。也就是说,理论上重新定义sasl中的这个过滤函数sasl:pred(),就可以在sasl日志中实现按日志类型进行过滤的功能。

    在发现这个问题后,本想暂时放弃,继续项目的推进,等有空闲的时候再进行尝试。但心痒难耐,还是对sasl进行了改造,重新定义了过滤函数sasl:pred(),实现了对日志的过滤功能。

    首先,参照error_logger文档中对Event的说明,将日志信息分为了五类,如下:
        system:  包括监管(supervisor_report)、崩溃(crash_report)、
                 进程(progress)三种信息;
        info:    由error_logger:info_XXXX()产生的日志信息;
        warning: 由error_logger:warning_XXXX()产生的日志信息;
        error:   由error_logger:error_XXXX()产生的日志信息;
        other:   由于error_logger支持自定义日志信息类型,
                 不在上述标准类型内的日志信息,均归为other;

    这五类日志信息,没有优先级别上的划分。需要记录哪一类日志信息,要在配置文件中,明确声明。否则将不会被记录在日志文件中。

    在配置文件中,需要增加一个参数{error_logger_mf_ftype, [XXXX,XXXX,...]}。这个参数对应的是一个list,其中包含需要写入日志文件的日志信息分类。既上述五种类型中的一种或几种。示例如下:

        [{sasl, [
            %% sasl_error_logger config
            {sasl_error_logger, false},

            %% error_logger_mf config
            {error_logger_mf_dir,"./logs"},
            {error_logger_mf_maxbytes,10485760}, % 10 MB
            {error_logger_mf_maxfiles, 10},
             %% system|info|warning|error|other
            {error_logger_mf_ftype, [system, error]}
        ]}].

 

    对sasl.erl的修改,主要是增加一个配置读取函数get_mf_ftype(),重新定义了过滤还是pred(),并对pred()调用方式进行了调整。

    get_mf_ftype()负责读取{error_logger_mf_ftype, [XXXX,XXXX,...]}中的配置信息,没什么新意,参看附件中的实现即可。

    原有的pred()仅有一个参数Event,既pred(Event)。为了实现对日志信息的过滤,新的pred()函数有两个参数,pred(Event, Ftypes)。基本思路是,先解析Event的类型,并归类。然后判断该类型信息,是在许可列表中。

        pred({_Type, GL, _Msg}, _FTypes) when node(GL) /= node() -> false;
        pred(Event, FTypes) ->
            EventType =
                case Event of
                    {error, _GL, _Msg}->                           error;
                    {error_report, _GL, {_Pid, std_error, _Rep}}-> error;
                    {error_report, _GL, {_Pid, Type, _Rep}}->
                        case Type of
                            supervisor_report-> system;
                            crash_report->      system;
                            _->                 other
                        end;

                    {info_msg, _GL, _Msg}->                       info;
                    {info_report, _GL, {_Pid, std_info, _Ret}}->  info;
                    {info_report, _GL, {_Pid, Type, _Ret}}->
                        case Type of
                            progress->  system;
                            _->         other
                        end;

                    {warning_msg, _GL, _Msg}->                         warning;
                    {warning_report, _GL, {_Pid, std_warning, _Rep}}-> warning;
                    {warning_report, _GL, {_Pid, Type, _Rep}}->        other
                end,
            lists:member(EventType, FTypes).
 



    至此,sasl中的日志过滤功能,基本实现了。用rb参看日志信息时,可以看到,只有指定类型的信息才能被记录在日志文件中。
   
    附言:
        1、sasl.erl中还有一些小的修改,将附件中修改后的sasl.erl与标准的sasl.erl对比,即可看到。
        2、对sasl.erl的修改,仅实现功能。因运行环境、时间等方面的原因,在性能方面没有测试过。
        3、在标准的sasl.erl中对pred()的调用是这种方式log_mf_h:init(Dir, MaxB, MaxF, {sasl, pred})。看了一下log_mf_h:init()的实现,第四个参数是一个fun()类型的参数。也就是说{sasl, pred}是一个erlang支持fun()类型。在erlang.spawn()中更有类似如下的定义:
                spawn({M,F}=MF) when is_atom(M), is_atom(F) ->
                               spawn(erlang, apply, [MF, []]);
            这是我头一次看到这种方式。《Programming Erlang》中好像也没有相关的说明。有哪位仁兄了解,能对此详细给说明一下吗?
            谢了!!

   发表时间:2009-09-17  
在erlang.spawn()中更有类似如下的定义:
                spawn({M,F}=MF) when is_atom(M), is_atom(F) ->
                               spawn(erlang, apply, [MF, []]);
            这是我头一次看到这种方式。《Programming Erlang》中好像也没有相关的说明。有哪位仁兄了解,能对此详细给说明一下吗?

这种方式是个erlang支持的函数方式 但是快要过时了 下个版本应该要移除了。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics