summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicael Karlberg <bmk@erlang.org>2013-11-18 18:09:18 +0100
committerMicael Karlberg <bmk@erlang.org>2013-11-18 18:09:18 +0100
commit93e3c5286080380cbcee45d96b0893206721590f (patch)
tree9da67708cb928fc8f4edd8ac7de6f0617f0bf393
parent78f27e212511db6b4c303f13dd698ba687fc459a (diff)
parent57abd27ee8e189791c4d97ef86de6136c4924b52 (diff)
downloaderlang-93e3c5286080380cbcee45d96b0893206721590f.tar.gz
Merge branch 'bmk/snmp/handling_corrupt_atl_when_converting/OTP-11453' into bmk/snmp/snmp4223_integration
Conflicts: lib/snmp/doc/src/notes.xml lib/snmp/src/app/snmp.appup.src lib/snmp/src/misc/snmp_log.erl
-rw-r--r--lib/snmp/doc/src/notes.xml12
-rw-r--r--lib/snmp/src/app/snmp.appup.src8
-rw-r--r--lib/snmp/src/misc/snmp_log.erl242
-rw-r--r--lib/snmp/src/misc/snmp_verbosity.erl12
4 files changed, 201 insertions, 73 deletions
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 668e986486..2350c0947e 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -82,6 +82,18 @@
<p>Own Id: OTP-11396</p>
<p>Own Id: seq12433</p>
</item>
+
+ <item>
+ <p>When converting the Audit Trail Log to text a corrupt
+ log entry could cause the entire conversion to fail. </p>
+ <p>Also, for a log with sequence numbers, failing to
+ decode a log entry would cause the conversion to fail
+ (not because of the failed decode, but because of the
+ failure to write the error message). </p>
+ <p>Own Id: OTP-111453</p>
+ <p>Aux Id: Seq 12459</p>
+ </item>
+
</list>
</section>
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 69237838ab..31f56cb73c 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -24,13 +24,13 @@
[
{"4.22.2",
[
- {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
{"4.22.1",
[
- {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
@@ -328,13 +328,13 @@
[
{"4.22.2",
[
- {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
{"4.22.1",
[
- {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index 9c6cb1e077..1aba3b56f8 100644
--- a/lib/snmp/src/misc/snmp_log.erl
+++ b/lib/snmp/src/misc/snmp_log.erl
@@ -16,6 +16,7 @@
%%
%% %CopyrightEnd%
%%
+%%
-module(snmp_log).
@@ -397,6 +398,8 @@ log_to_txt(Log, FileName, Dir, Mibs, TextFile, Start, Stop)
[Log, FileName, Dir, Mibs, TextFile, Start, Stop]),
File = filename:join(Dir, FileName),
Converter = fun(L) ->
+ ?vtrace("log_to_txt:fun -> entry with"
+ "~n L: ~p", [L]),
do_log_to_file(L, TextFile, Mibs, Start, Stop)
end,
log_convert(Log, File, Converter).
@@ -422,6 +425,8 @@ log_to_io(Log, FileName, Dir, Mibs, Start, Stop)
[Log, FileName, Dir, Mibs, Start, Stop]),
File = filename:join(Dir, FileName),
Converter = fun(L) ->
+ ?vtrace("log_to_io:fun -> entry with"
+ "~n L: ~p", [L]),
do_log_to_io(L, Mibs, Start, Stop)
end,
log_convert(Log, File, Converter).
@@ -441,8 +446,7 @@ log_convert(Log, File, Converter) ->
do_log_convert(Log, File, Converter) ->
%% ?vtrace("do_log_converter -> entry with"
%% "~n Log: ~p"
- %% "~n File: ~p"
- %% "~n disk_log:info(Log): ~p", [Log, File, disk_log:info(Log)]),
+ %% "~n File: ~p", [Log, File]),
Verbosity = get(verbosity),
{Pid, Ref} =
erlang:spawn_monitor(
@@ -450,14 +454,13 @@ do_log_convert(Log, File, Converter) ->
put(sname, lc),
put(verbosity, Verbosity),
Result = do_log_convert2(Log, File, Converter),
+ %% ?vlog("convert result: ~p", [Result]),
exit(Result)
end),
receive
{'DOWN', Ref, process, Pid, Result} ->
%% ?vtrace("do_log_converter -> received result"
- %% "~n Result: ~p"
- %% "~n disk_log:info(Log): ~p",
- %% [Result, disk_log:info(Log)]),
+ %% "~n Result: ~p", [Result]),
Result
end.
@@ -502,12 +505,23 @@ do_log_convert2(Log, File, Converter) ->
%% -- do_log_to_text ---
do_log_to_file(Log, TextFile, Mibs, Start, Stop) ->
+ ?vtrace("do_log_to_txt -> entry with"
+ "~n Log: ~p"
+ "~n TextFile: ~p"
+ "~n Start: ~p"
+ "~n Stop: ~p", [Log, TextFile, Start, Stop]),
case file:open(TextFile, [write]) of
{ok, Fd} ->
+ ?vtrace("do_log_to_txt -> outfile created - create mini MIB", []),
MiniMib = snmp_mini_mib:create(Mibs),
+ ?vtrace("do_log_to_txt -> mini-MIB created - begin conversion", []),
Write = fun(X) ->
+ ?vtrace("do_log_to_txt:fun -> "
+ "entry - try format", []),
case format_msg(X, MiniMib, Start, Stop) of
{ok, S} ->
+ ?vtrace("do_log_to_txt:fun -> "
+ "formated - now write", []),
io:format(Fd, "~s", [S]);
_ ->
?vdebug("do_log_to_txt:fun -> "
@@ -516,8 +530,12 @@ do_log_to_file(Log, TextFile, Mibs, Start, Stop) ->
end
end,
Res = (catch loop(disk_log:chunk(Log, start), Log, Write)),
+ ?vtrace("do_log_to_txt -> converted - now delete mini-MIB", []),
snmp_mini_mib:delete(MiniMib),
+ ?vtrace("do_log_to_txt -> "
+ "mini-MIB closed - now close output file", []),
file:close(Fd),
+ ?vtrace("do_log_to_txt -> done", []),
Res;
{error, Reason} ->
?vinfo("Failed opening output file: "
@@ -528,10 +546,19 @@ do_log_to_file(Log, TextFile, Mibs, Start, Stop) ->
do_log_to_io(Log, Mibs, Start, Stop) ->
+ ?vtrace("do_log_to_io -> entry with"
+ "~n Log: ~p"
+ "~n Mibs: ~p"
+ "~n Start: ~p"
+ "~n Stop: ~p", [Log, Mibs, Start, Stop]),
MiniMib = snmp_mini_mib:create(Mibs),
+ ?vtrace("do_log_to_io -> mini-MIB created - begin conversion", []),
Write = fun(X) ->
+ ?vtrace("do_log_to_io:fun -> entry", []),
case format_msg(X, MiniMib, Start, Stop) of
{ok, S} ->
+ ?vtrace("do_log_to_io:fun -> "
+ "formated - now write", []),
io:format("~s", [S]);
_ ->
?vdebug("do_log_to_io:fun -> "
@@ -540,19 +567,31 @@ do_log_to_io(Log, Mibs, Start, Stop) ->
end
end,
(catch loop(disk_log:chunk(Log, start), Log, Write)),
+ ?vtrace("do_log_to_io -> converted - now delete mini-MIB", []),
snmp_mini_mib:delete(MiniMib),
+ ?vtrace("do_log_to_io -> done", []),
ok.
loop(eof, _Log, _Write) ->
+ ?vtrace("loop -> entry when eof", []),
ok;
-loop({error, _} = Error, _Log, _Write) ->
+loop({error, _Reason} = Error, _Log, _Write) ->
+ ?vtrace("loop -> entry with error"
+ "~n Reason: ~p", [_Reason]),
Error;
loop({Cont, Terms}, Log, Write) ->
- case (catch lists:foreach(Write, Terms)) of
+ ?vtrace("loop -> entry with terms"
+ "~n Cont: ~p"
+ "~n length(Terms): ~p", [Cont, length(Terms)]),
+ case (catch lists:foreach(Write, Terms)) of
{'EXIT', Reason} ->
+ ?vtrace("loop -> failure while writing terms"
+ "~n Reason: ~p", [Reason]),
{error, Reason};
- _ ->
+ _X ->
+ ?vtrace("loop -> terms written"
+ "~n X: ~p", [_X]),
loop(disk_log:chunk(Log, Cont), Log, Write)
end;
loop({Cont, Terms, BadBytes}, Log, Write) ->
@@ -565,6 +604,8 @@ loop({Cont, Terms, BadBytes}, Log, Write) ->
loop(disk_log:chunk(Log, Cont), Log, Write)
end;
loop(Error, _Log, _Write) ->
+ ?vtrace("loop -> entry with unknown"
+ "~n Error: ~p", [Error]),
Error.
@@ -579,14 +620,17 @@ format_msg(Entry, Mib, Start, Stop) ->
%% This is an old-style entry, that never had the sequence-number
do_format_msg({Timestamp, Packet, {Addr, Port}}, Mib) ->
+ ?vdebug("do_format_msg -> old style log entry", []),
do_format_msg(Timestamp, Packet, Addr, Port, Mib);
%% This is the format without sequence-number
do_format_msg({Timestamp, Packet, Addr, Port}, Mib) ->
+ ?vdebug("do_format_msg -> log entry without seqno", []),
do_format_msg(Timestamp, Packet, Addr, Port, Mib);
%% This is the format with sequence-number
do_format_msg({Timestamp, SeqNo, Packet, Addr, Port}, Mib) ->
+ ?vdebug("do_format_msg -> log entry with seqno", []),
do_format_msg(Timestamp, SeqNo, Packet, Addr, Port, Mib);
%% This is crap...
@@ -594,103 +638,165 @@ do_format_msg(_, _) ->
format_tab("** unknown entry in log file\n\n", []).
do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode scoped pdu",
+ [TimeStamp, Addr, Port]),
case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
+ ?vtrace("do_format_msg -> scoped pdu decoded"
+ "~n ScopedPDU: ~p", [ScopedPDU]),
Msg = #message{version = 'version-3',
vsn_hdr = V3Hdr,
data = ScopedPDU},
f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+
{'EXIT', Reason} ->
- format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
+ ?vinfo("Failed decoding scoped pdu: "
+ "~n V3Hdr: ~w"
+ "~n ScopedPdu: ~w"
+ "~n Reason: ~p", [V3Hdr, ScopedPdu, Reason]),
+ format_tab("** error in log file at ~s from ~s:~w ~p\n\n",
[ts2str(TimeStamp), ip(Addr), Port, Reason])
end;
+
do_format_msg(TimeStamp, Packet, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode packet",
+ [TimeStamp, Addr, Port]),
case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
- Msg when is_record(Msg, message) ->
+ #message{data = Data} = Msg when (is_record(Data, scopedPdu) orelse
+ is_record(Data, pdu) orelse
+ is_record(Data, trappdu)) ->
+ ?vtrace("do_format_msg -> packet decoded"
+ "~n Msg: ~p", [Msg]),
f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+
+ #message{version = Vsn,
+ vsn_hdr = VsnHdr} = Msg ->
+ ?vinfo("Message not fully decoded: "
+ "~n Msg: ~p", [Msg]),
+ Reason =
+ lists:flatten(
+ io_lib:format("Message not fully decoded: "
+ "Vsn = ~p, VsnHdr = ~w", [Vsn, VsnHdr])),
+ format_tab("** error in log file ~s from ~s:~w => "
+ "\n ~s\n\n",
+ [ts2str(TimeStamp), ip(Addr), Port, Reason]);
+
{'EXIT', Reason} ->
+ ?vinfo("Failed decoding packet: "
+ "~n Packet: ~w"
+ "~n Reason: ~p", [Packet, Reason]),
format_tab("** error in log file ~p\n\n", [Reason])
end.
do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n SeqNo: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode scoped pdu",
+ [TimeStamp, SeqNo, Addr, Port]),
case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
+ ?vtrace("do_format_msg -> scoped pdu decoded"
+ "~n ScopedPDU: ~p", [ScopedPDU]),
Msg = #message{version = 'version-3',
vsn_hdr = V3Hdr,
data = ScopedPDU},
f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+
{'EXIT', Reason} ->
- format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
+ ?vinfo("Failed decoding scoped pdu: "
+ "~n V3Hdr: ~w"
+ "~n ScopedPdu: ~w"
+ "~n Reason: ~p", [V3Hdr, ScopedPdu, Reason]),
+ format_tab("** error in log file at ~s~s from ~s:~w ~p\n\n",
[ts2str(TimeStamp), sn2str(SeqNo),
ip(Addr), Port, Reason])
end;
do_format_msg(TimeStamp, SeqNo, Packet, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n SeqNo: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode message",
+ [TimeStamp, SeqNo, Addr, Port]),
case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
- Msg when is_record(Msg, message) ->
+ #message{data = Data} = Msg when (is_record(Data, scopedPdu) orelse
+ is_record(Data, pdu) orelse
+ is_record(Data, trappdu)) ->
+ ?vtrace("do_format_msg -> message decoded"
+ "~n Msg: ~p", [Msg]),
f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+
+ #message{version = Vsn,
+ vsn_hdr = VsnHdr} = Msg ->
+ ?vinfo("Message not fully decoded: "
+ "~n Msg: ~p", [Msg]),
+ Reason =
+ lists:flatten(
+ io_lib:format("Message not fully decoded: "
+ "Vsn = ~p, VsnHdr = ~w", [Vsn, VsnHdr])),
+ format_tab("** error in log file ~s~s from ~s:~w => "
+ "\n ~s\n\n",
+ [ts2str(TimeStamp), sn2str(SeqNo),
+ ip(Addr), Port, Reason]);
+
{'EXIT', Reason} ->
- format_tab("** error in log file ~s from ~p:~w ~p\n\n",
+ ?vinfo("Failed decoding packet: "
+ "~n Packet: ~w"
+ "~n Reason: ~p", [Packet, Reason]),
+ format_tab("** error in log file ~s (~s) from ~s:~w ~p\n\n",
[ts2str(TimeStamp), sn2str(SeqNo),
ip(Addr), Port, Reason])
end.
-%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, {Addr, Port}},
-%% Mib, Start, Stop) ->
-%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
-%% Mib, Start, Stop);
-%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
-%% Mib, Start, Stop) ->
-%% case timestamp_filter(TimeStamp, Start, Stop) of
-%% true ->
-%% case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
-%% ScopedPDU when record(ScopedPDU, scopedPdu) ->
-%% Msg = #message{version = 'version-3',
-%% vsn_hdr = V3Hdr,
-%% data = ScopedPDU},
-%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
-%% {'EXIT', Reason} ->
-%% format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
-%% [ts2str(TimeStamp), ip(Addr), Port, Reason])
-%% end;
-%% false ->
-%% ignore
-%% end;
-%% format_msg({TimeStamp, Packet, {Addr, Port}}, Mib, Start, Stop) ->
-%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop);
-%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop) ->
-%% case timestamp_filter(TimeStamp, Start, Stop) of
-%% true ->
-%% case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
-%% Msg when record(Msg, message) ->
-%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
-%% {'EXIT', Reason} ->
-%% format_tab("** error in log file ~p\n\n", [Reason])
-%% end;
-%% false ->
-%% ignore
-%% end;
-%% format_msg(_, _Mib, _Start, _Stop) ->
-%% format_tab("** unknown entry in log file\n\n", []).
-
f(TimeStamp, SeqNo,
#message{version = Vsn, vsn_hdr = VsnHdr, data = Data},
Addr, Port, Mib) ->
- Str = format_pdu(Data, Mib),
- HdrStr = format_header(Vsn, VsnHdr),
- case get_type(Data) of
- trappdu ->
- f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'snmpv2-trap' ->
- f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'inform-request' ->
- f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'get-response' ->
- f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- report ->
- f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- _ ->
- f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port)
+ try
+ begin
+ Str = format_pdu(Data, Mib),
+ HdrStr = format_header(Vsn, VsnHdr),
+ case get_type(Data) of
+ trappdu ->
+ f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ 'snmpv2-trap' ->
+ f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ 'inform-request' ->
+ f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ 'get-response' ->
+ f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ report ->
+ f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ _ ->
+ f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port)
+ end
+ end
+ catch
+ T:E ->
+ ?vinfo("Failed formating log entry"
+ "~n TimeStamp: ~p"
+ "~n SeqNo: ~p"
+ "~n Data: ~p"
+ "~n Vsn: ~p"
+ "~n VsnHdr: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n Error Type: ~w"
+ "~n Error: ~p",
+ [TimeStamp, SeqNo, Data, Vsn, VsnHdr, Addr, Port, T, E]),
+ format_tab("** error while formating log entry ~p\n\n", [{T, E}])
end.
f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
@@ -717,7 +823,7 @@ f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
%% Convert a timestamp 2-tupple to a printable string
%%
ts2str({Local,Universal}) ->
- dat2str(Local) ++ " , " ++ dat2str(Universal);
+ lists:flatten(dat2str(Local) ++ " , " ++ dat2str(Universal));
ts2str(_) ->
"".
@@ -814,7 +920,7 @@ get_type(#pdu{type = Type}) ->
ip({A,B,C,D}) ->
- io_lib:format("~w.~w.~w.~w", [A,B,C,D]).
+ lists:flatten(io_lib:format("~w.~w.~w.~w", [A,B,C,D])).
diff --git a/lib/snmp/src/misc/snmp_verbosity.erl b/lib/snmp/src/misc/snmp_verbosity.erl
index e5ff3daf91..7d063fd702 100644
--- a/lib/snmp/src/misc/snmp_verbosity.erl
+++ b/lib/snmp/src/misc/snmp_verbosity.erl
@@ -154,7 +154,17 @@ image_of_sname(mgr) -> "MGR";
image_of_sname(mgr_misc) -> "MGR_MISC";
image_of_sname(undefined) -> "";
-image_of_sname(V) -> lists:flatten(io_lib:format("~p",[V])).
+image_of_sname(S) when is_list(S) ->
+ %% The assumption is that its a printable string,
+ %% but just in case it is some other list...
+ try lists:flatten(io_lib:format("~s", [S])) of
+ L ->
+ L
+ catch
+ _:_ ->
+ lists:flatten(io_lib:format("~p", [S]))
+ end;
+image_of_sname(V) -> lists:flatten(io_lib:format("~p", [V])).
validate(info) -> info;