网站地图
首页
新闻
电影新闻
电视新闻
人物新闻
专题策划
影评
最新影评
新片热评
经典赏析
媒体评论
电影院
北京影讯
上海影讯
广州影讯
深圳影讯
成都影讯
电影库
典藏佳片
全球新片
即将上映
票房榜
社区
日志
相册
电影
好友
专辑
收藏
影视杂谈
明星时尚
文化休闲
群组
话题
达人
排行榜
电影榜
电视榜
人物榜
日志榜
话题榜

变奏曲,十一月……

永远不要说永远……

http://i.mtime.com/844165/

您当前的位置: 社区>> 博客>>

编辑 | 删除 erlang large日志系统代码阅读(四):lager_handler_watcher_sup & lager_handler_watcher

GOK358405961 发布于:

-module(lager_handler_watcher_sup).


-behaviour(supervisor).


%% API

-export([start_link/0]).


%% Callbacks

-export([init/1]).


start_link() ->

    supervisor:start_link({local, ?MODULE}, ?MODULE, []).


%启动lager_event handler 的监控进程,子进程的start strategy是simple_one_for_one,在调用

%supervisor:start_child(SupRef, List))后会把ChildSpec中的Args++List传给子进程init函数


init([]) ->

    {ok, {{simple_one_for_one, 10, 60},

            [

                {lager_handler_watcher, {lager_handler_watcher, start_link, []},

                        transient, 5000, worker, [lager_handler_watcher]}

                ]}}.


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


-module(lager_handler_watcher).


-behaviour(gen_server).


%% callbacks

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,

        code_change/3]).


-export([start_link/3, start/3]).


-record(state, {

        module,

        config,

        event

    }).


start_link(Event, Module, Config) ->

    gen_server:start_link(?MODULE, [Event, Module, Config], []).


start(Event, Module, Config) ->

    gen_server:start(?MODULE, [Event, Module, Config], []).


init([Event, Module, Config]) ->

    install_handler(Event, Module, Config),

    {ok, #state{event=Event, module=Module, config=Config}}.


handle_call(_Call, _From, State) ->

    {reply, ok, State}.


handle_cast(_Request, State) ->

    {noreply, State}.


handle_info({gen_event_EXIT, Module, normal}, #state{module=Module} = State) ->%handler正常结束,进程关闭

    {stop, normal, State};

handle_info({gen_event_EXIT, Module, shutdown}, #state{module=Module} = State) ->%handler正常结束,进程关闭

    {stop, normal, State};

handle_info({gen_event_EXIT, Module, Reason}, #state{module=Module,%handler异常结束,尝试重新注册handler

        config=Config, event=Event} = State) ->

    case lager:log(error, self(), "Lager event handler ~p exited with reason ~s",

        [Module, error_logger_lager_h:format_reason(Reason)]) of

      ok ->

        install_handler(Event, Module, Config);

      {error, _} ->

        %% lager is not working, so installing a handler won't work

        ok

    end,

    {noreply, State};

handle_info(reinstall_handler, #state{module=Module, config=Config, event=Event} = State) ->

    install_handler(Event, Module, Config),%上次注册失败后5s再次尝试注册handler

    {noreply, State};

handle_info(_Info, State) ->

    {noreply, State}.


terminate(_Reason, _State) ->

    ok.


code_change(_OldVsn, State, _Extra) ->

    {ok, State}.


%% internal


%注册handler Module到gen_event进程Event


install_handler(Event, Module, Config) ->

    case gen_event:add_sup_handler(Event, Module, Config) of

        ok ->

            _ = lager:log(debug, self(), "Lager installed handler ~p into ~p", [Module, Event]),

            ok;

        Error ->

            %% try to reinstall it later

            _ = lager:log(error, self(), "Lager failed to install handler ~p into"

               " ~p, retrying later : ~p", [Module, Event, Error]),

            erlang:send_after(5000, self(), reinstall_handler),%注册失败5s后发送reinstall_handler给自己

            ok

    end.

回复 (0) | 收藏 (0) | 2746 次阅读 |

日志分类