From a625c82cc2adb53e9aa70291445ed5a2a95a4f84 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 1 Feb 2012 18:27:17 +0100 Subject: [snmp/manager] Reworked the ATL mechanism for the net-if-mt Removed the separate logger process. Instead open the log from each worker process and log from them directly. OTP-9876 --- lib/snmp/src/manager/snmpm_net_if_mt.erl | 125 +++++++++++++------------------ lib/snmp/src/misc/snmp_log.erl | 38 +++++++--- lib/snmp/test/snmp_log_test.erl | 27 ++++--- 3 files changed, 100 insertions(+), 90 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl index 753626be72..3e87f6a7fb 100644 --- a/lib/snmp/src/manager/snmpm_net_if_mt.erl +++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl @@ -46,8 +46,6 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). --export([logger_init/2]). - -define(SNMP_USE_V3, true). -include("snmp_types.hrl"). -include("snmpm_internal.hrl"). @@ -69,13 +67,6 @@ filter }). -%% State record of the logger process --record(logger, - { - parent, - log - }). - -define(DEFAULT_FILTER_MODULE, snmpm_net_if_filter). -define(DEFAULT_FILTER_OPTS, [{module, ?DEFAULT_FILTER_MODULE}]). @@ -189,13 +180,14 @@ do_init(Server, NoteStore) -> %% -- Verbosity -- {ok, Verbosity} = snmpm_config:system_info(net_if_verbosity), - put(sname,mnif), - put(verbosity,Verbosity), + put(sname, mnif), + put(verbosity, Verbosity), ?vlog("starting", []), %% -- MPD -- {ok, Vsns} = snmpm_config:system_info(versions), MpdState = snmpm_mpd:init(Vsns), + ?vdebug("MpdState: ~w", [MpdState]), %% -- Module dependent options -- {ok, Opts} = snmpm_config:system_info(net_if_options), @@ -220,6 +212,7 @@ do_init(Server, NoteStore) -> %% -- Audit trail log --- {ok, ATL} = snmpm_config:system_info(audit_trail_log), Log = do_init_log(ATL), + ?vdebug("Log: ~w", [Log]), %% -- Initiate counters --- init_counters(), @@ -315,44 +308,12 @@ do_init_log(false) -> undefined; do_init_log(true) -> ?vtrace("do_init_log(true) -> entry", []), - logger_start(). - -logger_start() -> - {Pid, _} = Logger = - erlang:spawn_opt(?MODULE, logger_init, [self(), get(verbosity)], - [monitor]), - receive - {logger_started, Pid} -> - {ok, Type} = snmpm_config:system_info(audit_trail_log_type), - {Logger, Type}; - {'DOWN', _MonitorRef, process, Pid, Reason} -> - throw({error, {failed_starting_logger, Logger, Reason}}) - after 5000 -> - %% This should really not take any time at all, - %% so 5 secs is plenty of time. - throw({error, {failed_starting_logger, Logger, timeout}}) - end. - -logger_init(Parent, Verbosity) -> - put(sname, mnifl), - put(verbosity, Verbosity), - case (catch do_logger_init()) of - {ok, Log} -> - Parent ! {logger_started, self()}, - logger_loop(#logger{parent = Parent, - log = Log}); - {error, Reason} -> - exit({logger, failed_init, Reason}) - end. - -%% Open log -do_logger_init() -> - ?vtrace("do_logger_init() -> entry", []), + {ok, Type} = snmpm_config:system_info(audit_trail_log_type), {ok, Dir} = snmpm_config:system_info(audit_trail_log_dir), {ok, Size} = snmpm_config:system_info(audit_trail_log_size), {ok, Repair} = snmpm_config:system_info(audit_trail_log_repair), - Name = ?audit_trail_log_name, - File = filename:absname(?audit_trail_log_file, Dir), + Name = ?audit_trail_log_name, + File = filename:absname(?audit_trail_log_file, Dir), case snmpm_config:system_info(audit_trail_log_seqno) of {ok, true} -> Initial = ?ATL_SEQNO_INITIAL, @@ -364,33 +325,22 @@ do_logger_init() -> case snmp_log:create(Name, File, SeqNoGen, Size, Repair, true) of {ok, Log} -> ?vdebug("log created: ~w", [Log]), - {ok, Log}; + {Name, Log, Type}; {error, Reason} -> - {error, {failed_create_audit_log, Reason}} + throw({error, {failed_create_audit_log, Reason}}) end; _ -> case snmp_log:create(Name, File, Size, Repair, true) of {ok, Log} -> ?vdebug("log created: ~w", [Log]), - {ok, Log}; + {Name, Log, Type}; {error, Reason} -> - {error, {failed_create_audit_log, Reason}} + throw({error, {failed_create_audit_log, Reason}}) end end. -logger_loop(Logger) -> - receive - {log, Msg, Addr, Port} -> - snmp_log:log(Logger#logger.log, Msg, Addr, Port); - {stop, Pid} when Pid =:= Logger#logger.parent -> - exit(normal) - end, - logger_loop(Logger). - - %% ---------------------------------------------------------------------- - %%-------------------------------------------------------------------- %% Func: handle_call/3 @@ -551,9 +501,12 @@ code_change(_Vsn, State, _Extra) -> %%%------------------------------------------------------------------- handle_udp(Addr, Port, Bytes, State) -> + Verbosity = get(verbosity), spawn_opt(fun() -> - Res = (catch maybe_handle_recv_msg(Addr, Port, - Bytes, State)), + Log = worker_init(State, Verbosity), + Res = (catch maybe_handle_recv_msg( + Addr, Port, Bytes, + State#state{log = Log})), worker_exit(udp, {Addr, Port}, Res) end, [monitor]). @@ -713,10 +666,13 @@ handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, ok. handle_inform_response(Ref, Addr, Port, State) -> + Verbosity = get(verbosity), spawn_opt(fun() -> - Res = (catch do_handle_inform_response(Ref, - Addr, Port, - State)), + Log = worker_init(State, Verbosity), + Res = (catch do_handle_inform_response( + Ref, + Addr, Port, + State#state{log = Log})), worker_exit(inform_reponse, {Addr, Port}, Res) end, [monitor]). @@ -790,10 +746,13 @@ irgc_stop(Ref) -> handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) -> + Verbosity = get(verbosity), spawn_opt(fun() -> - Res = (catch maybe_handle_send_pdu(Pdu, Vsn, MsgData, - Domain, Addr, Port, - State)), + Log = worker_init(State, Verbosity), + Res = (catch maybe_handle_send_pdu( + Pdu, Vsn, MsgData, + Domain, Addr, Port, + State#state{log = Log})), worker_exit(send_pdu, {Domain, Addr, Port}, Res) end, [monitor]). @@ -1048,6 +1007,30 @@ handle_set_log_type(State, _NewType) -> %% ------------------------------------------------------------------- +worker_init(#state{log = undefined = Log}, Verbosity) -> + worker_init2(Log, Verbosity); +worker_init(#state{log = {Name, Log, Type}}, Verbosity) -> + case snmp_log:open(Name, Log) of + {ok, NewLog} -> + worker_init2({Name, NewLog, Type}, Verbosity); + {error, Reason} -> + warning_msg("NetIf worker ~p failed opening ATL: " + "~n ~p", [self(), Reason]), + NewLog = undefined, + worker_init2({Name, NewLog, Type}, Verbosity) + end; +worker_init(State, Verbosity) -> + ?vinfo("worker_init -> entry with invalid data: " + "~n State: ~p" + "~n Verbosity: ~p", [State, Verbosity]), + exit({worker_init, State, Verbosity}). + +worker_init2(Log, Verbosity) -> + put(sname, mnifw), + put(verbosity, Verbosity), + Log. + + worker_exit(Tag, Info, Result) -> exit({net_if_worker, {Tag, Info, Result}}). @@ -1116,11 +1099,11 @@ logger(undefined, _Type, _Addr, _Port) -> fun(_) -> ok end; -logger({{Pid, _}, Types}, Type, Addr, Port) -> +logger({_Name, Log, Types}, Type, Addr, Port) -> case lists:member(Type, Types) of true -> fun(Msg) -> - Pid ! {log, Msg, Addr, Port} + snmp_log:log(Log, Msg, Addr, Port) end; false -> fun(_) -> diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index 2c781810ef..7f7030c9bf 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -21,7 +21,7 @@ -export([ - create/4, create/5, create/6, + create/4, create/5, create/6, open/1, open/2, change_size/2, close/1, sync/1, info/1, log/4, log_to_txt/5, log_to_txt/6, log_to_txt/7, @@ -109,6 +109,24 @@ create(Name, File, SeqNoGen, Size, Repair, Notify) -> {error, {bad_args, Name, File, SeqNoGen, Size, Repair, Notify}}. +%% -- open --- + +%% Open an already existing ( = open ) log + +open(Name) -> + open(Name, #snmp_log{seqno = disabled}). +open(Name, #snmp_log{seqno = SeqNoGen} = _OldLog) -> + %% We include mode in the opts just to be on the safe side + case disk_log:open([{name, Name}, {mode, read_write}]) of + {ok, Log} -> + %% SeqNo must be proprly initiated also + {ok, #snmp_log{id = Log, seqno = SeqNoGen}}; + {repaired, Log, _RecBytes, _BadBytes} -> + {ok, #snmp_log{id = Log, seqno = SeqNoGen}}; + ERROR -> + ERROR + end. + %% -- close --- @@ -705,21 +723,21 @@ tsf_ge(_Local,Universal,{universal_time,DateTime}) -> tsf_ge(Local,_Universal,DateTime) -> tsf_ge(Local,DateTime). -tsf_ge(TimeStamp,DateTime) -> +tsf_ge(TimeStamp, DateTime) -> T1 = calendar:datetime_to_gregorian_seconds(TimeStamp), T2 = calendar:datetime_to_gregorian_seconds(DateTime), T1 >= T2. -tsf_le(_Local,_Universal,null) -> +tsf_le(_Local, _Universal, null) -> true; -tsf_le(Local,_Universal,{local_time,DateTime}) -> - tsf_le(Local,DateTime); -tsf_le(_Local,Universal,{universal_time,DateTime}) -> - tsf_le(Universal,DateTime); -tsf_le(Local,_Universal,DateTime) -> +tsf_le(Local, _Universal, {local_time, DateTime}) -> + tsf_le(Local, DateTime); +tsf_le(_Local, Universal, {universal_time, DateTime}) -> + tsf_le(Universal, DateTime); +tsf_le(Local, _Universal, DateTime) -> tsf_le(Local,DateTime). -tsf_le(TimeStamp,DateTime) -> +tsf_le(TimeStamp, DateTime) -> T1 = calendar:datetime_to_gregorian_seconds(TimeStamp), T2 = calendar:datetime_to_gregorian_seconds(DateTime), T1 =< T2. diff --git a/lib/snmp/test/snmp_log_test.erl b/lib/snmp/test/snmp_log_test.erl index b692017407..8478825f59 100644 --- a/lib/snmp/test/snmp_log_test.erl +++ b/lib/snmp/test/snmp_log_test.erl @@ -42,7 +42,11 @@ -export([ init_per_testcase/2, end_per_testcase/2, - all/0,groups/0,init_per_group/2,end_per_group/2, + all/0, + groups/0, + init_per_group/2, + end_per_group/2, + open_and_close/1, open_write_and_close1/1, @@ -109,16 +113,21 @@ end_per_testcase(_Case, Config) when is_list(Config) -> %%====================================================================== %% ?SKIP(not_yet_implemented). all() -> -[open_and_close, {group, open_write_and_close}, - {group, log_to_io}, {group, log_to_txt}]. + [ + open_and_close, + {group, open_write_and_close}, + {group, log_to_io}, + {group, log_to_txt}]. groups() -> - [{open_write_and_close, [], - [open_write_and_close1, open_write_and_close2, - open_write_and_close3, open_write_and_close4]}, - {log_to_io, [], [log_to_io1, log_to_io2]}, - {log_to_txt, [], - [log_to_txt1, log_to_txt2, log_to_txt3]}]. + [ + {open_write_and_close, [], + [open_write_and_close1, open_write_and_close2, + open_write_and_close3, open_write_and_close4]}, + {log_to_io, [], [log_to_io1, log_to_io2]}, + {log_to_txt, [], + [log_to_txt1, log_to_txt2, log_to_txt3]} + ]. init_per_group(_GroupName, Config) -> Config. -- cgit v1.2.3