From 794acac0ce3d2f219d12517237810e7a6d81b972 Mon Sep 17 00:00:00 2001 From: Bip Thelin Date: Thu, 14 Jan 2016 08:57:48 +0100 Subject: [PATCH 01/90] Replace jiffy with jsx --- rebar.config | 2 +- src/raven.app.src | 3 +-- src/raven.erl | 22 ++++++++++------------ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/rebar.config b/rebar.config index 4d7f566..8c718d3 100644 --- a/rebar.config +++ b/rebar.config @@ -6,5 +6,5 @@ {platform_define, "^R14", no_callbacks} ]}. {deps, [ - {jiffy, ".*", {git, "git://github.com/davisp/jiffy.git", {tag, "0.13.1"}}} + {jsx, ".*", {git, "git@github.com:talentdeficit/jsx.git", {branch, master}}} ]}. diff --git a/src/raven.app.src b/src/raven.app.src index 54ee74f..98e8c0f 100644 --- a/src/raven.app.src +++ b/src/raven.app.src @@ -8,8 +8,7 @@ crypto, public_key, ssl, - inets, - jiffy + inets ]}, {mod, {raven_app, []}}, {env, [ diff --git a/src/raven.erl b/src/raven.erl index 685a1fe..2c47d1d 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -28,7 +28,7 @@ capture(Message, Params) when is_list(Message) -> capture(unicode:characters_to_binary(Message), Params); capture(Message, Params) -> Cfg = get_config(), - Document = {[ + Document = [ {event_id, event_id_i()}, {project, unicode:characters_to_binary(Cfg#cfg.project)}, {platform, erlang}, @@ -37,24 +37,24 @@ capture(Message, Params) -> {message, term_to_json_i(Message)} | lists:map(fun ({stacktrace, Value}) -> - {'sentry.interfaces.Stacktrace', {[ + {'sentry.interfaces.Stacktrace', [ {frames,lists:reverse([frame_to_json_i(Frame) || Frame <- Value])} - ]}}; + ]}; ({exception, {Type, Value}}) -> - {'sentry.interfaces.Exception', {[ + {'sentry.interfaces.Exception', [ {type, Type}, {value, term_to_json_i(Value)} - ]}}; + ]}; ({tags, Tags}) -> - {tags, {[{Key, term_to_json_i(Value)} || {Key, Value} <- Tags]}}; + {tags, [{Key, term_to_json_i(Value)} || {Key, Value} <- Tags]}; ({extra, Tags}) -> - {extra, {[{Key, term_to_json_i(Value)} || {Key, Value} <- Tags]}}; + {extra, [{Key, term_to_json_i(Value)} || {Key, Value} <- Tags]}; ({Key, Value}) -> {Key, term_to_json_i(Value)} end, Params) - ]}, + ], Timestamp = integer_to_list(unix_timestamp_i()), - Body = base64:encode(zlib:compress(jiffy:encode(Document, [force_utf8]))), + Body = base64:encode(zlib:compress(jsx:encode(Document))), UA = user_agent(), Headers = [ {"X-Sentry-Auth", @@ -136,7 +136,6 @@ frame_to_json_i({Module, Function, Arguments, Location}) -> false -> -1; {line, L} -> L end, - { case is_list(Arguments) of true -> [{vars, [iolist_to_binary(io_lib:format("~w", [Argument])) || Argument <- Arguments]}]; false -> [] @@ -148,8 +147,7 @@ frame_to_json_i({Module, Function, Arguments, Location}) -> false -> <<(atom_to_binary(Module, utf8))/binary, ".erl">>; {file, File} -> list_to_binary(File) end} - ] - }. + ]. term_to_json_i(Term) when is_binary(Term); is_atom(Term) -> Term; From 657248c5e114a79d23531e2c113b0f19fa0ebd29 Mon Sep 17 00:00:00 2001 From: Bip Thelin Date: Thu, 14 Jan 2016 09:18:12 +0100 Subject: [PATCH 02/90] Update lager backend to work with newer lager --- src/raven_lager_backend.erl | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/raven_lager_backend.erl b/src/raven_lager_backend.erl index c7b57c5..2eb235f 100644 --- a/src/raven_lager_backend.erl +++ b/src/raven_lager_backend.erl @@ -5,34 +5,34 @@ -export([ - init/1, - code_change/3, - terminate/2, - handle_call/2, - handle_event/2, - handle_info/2 + init/1, + code_change/3, + terminate/2, + handle_call/2, + handle_event/2, + handle_info/2 ]). -record(state, {level}). -init(Level) -> - {ok, #state{level=lager_util:config_to_mask(Level)}}. +init([{level, Level}]) -> + {ok, #state{level=lager_util:level_to_num(Level)}}. %% @private handle_call(get_loglevel, #state{level=Level} = State) -> {ok, Level, State}; handle_call({set_loglevel, Level}, State) -> - try lager_util:config_to_mask(Level) of + try lager_util:level_to_num(Level) of Levels -> - {ok, ok, State#state{level=Levels}} - catch - _:_ -> - {ok, {error, bad_log_level}, State} - end; + {ok, ok, State#state{level=Levels}} + catch + _:_ -> + {ok, {error, bad_log_level}, State} + end; handle_call(_, State) -> - {ok, ok, State}. + {ok, ok, State}. %% @private handle_event({log, Data}, @@ -49,13 +49,13 @@ handle_event(_Event, State) -> handle_info(_, State) -> - {ok, State}. + {ok, State}. code_change(_, State, _) -> - {ok, State}. + {ok, State}. terminate(_, _) -> - ok. + ok. capture(mask) -> ok; @@ -91,4 +91,3 @@ parse_meta([{error_logger, _} | _Rest], _Acc) -> mask; parse_meta([{_, _} | Rest], Acc) -> parse_meta(Rest, Acc). - From d2fd4137a1d43b49137ed3fc128127d69bc4e924 Mon Sep 17 00:00:00 2001 From: Bip Thelin Date: Thu, 14 Jan 2016 11:38:30 +0100 Subject: [PATCH 03/90] Cleanup raven_lager_backend --- src/raven_lager_backend.erl | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/src/raven_lager_backend.erl b/src/raven_lager_backend.erl index 2eb235f..f36ec72 100644 --- a/src/raven_lager_backend.erl +++ b/src/raven_lager_backend.erl @@ -57,37 +57,9 @@ code_change(_, State, _) -> terminate(_, _) -> ok. -capture(mask) -> - ok; capture({Message, Params}) -> raven:capture(Message, Params). -%% TODO - check what other metadata can be sent to sentry -parse_message({lager_msg, [], MetaData, Level, _, _Time, Message}) -> - case parse_meta(MetaData) of - mask -> - mask; - Extra -> - {Message, [{level, Level}, - {extra, Extra}]} - end. - - -%% @doc Extracts pid from lager message metadata. Lager messages that came -%% from error_logger are flagged as such in the metadata, in which case we -%% immediately return 'mask', indicating that the message should be skipped. -%% This assumes that raven's error_logger handler is installed, to avoid -%% double-capturing error_logger events. -%% TODO: respect default_error_logger config, instead of assuming it is set -%% to true. -parse_meta(MetaData) -> - parse_meta(MetaData, []). - -parse_meta([], Acc) -> - Acc; -parse_meta([{pid, Pid} = PidProp | Rest], Acc) when is_pid(Pid) -> - parse_meta(Rest, [PidProp | Acc]); -parse_meta([{error_logger, _} | _Rest], _Acc) -> - mask; -parse_meta([{_, _} | Rest], Acc) -> - parse_meta(Rest, Acc). +parse_message(Log) -> + {lager_msg:message(Log), [ {level, lager_msg:severity(Log)} + , {extra, lager_msg:metadata(Log)} ]}. From 63bea5a2e633d43eeeb6aecc9780f32397d7206e Mon Sep 17 00:00:00 2001 From: Hakan Nilsson Date: Wed, 6 Apr 2016 13:14:32 +0200 Subject: [PATCH 04/90] Report release to sentry --- src/raven.erl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/raven.erl b/src/raven.erl index 2c47d1d..67e2e50 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -11,7 +11,8 @@ public_key :: string(), private_key :: string(), project :: string(), - ipfamily :: atom() + ipfamily :: atom(), + release :: binary() | undefined }). -type cfg_rec() :: #cfg{}. @@ -34,6 +35,7 @@ capture(Message, Params) -> {platform, erlang}, {server_name, node()}, {timestamp, timestamp_i()}, + {release, Cfg#cfg.release}, {message, term_to_json_i(Message)} | lists:map(fun ({stacktrace, Value}) -> @@ -85,6 +87,7 @@ get_config() -> -spec get_config(App :: atom()) -> cfg_rec(). get_config(App) -> {ok, IpFamily} = application:get_env(App, ipfamily), + Release = application:get_env(App, release, undefined), case application:get_env(App, dsn) of {ok, Dsn} -> {match, [_, Protocol, PublicKey, SecretKey, Uri, Project]} = @@ -93,7 +96,8 @@ get_config(App) -> public_key = PublicKey, private_key = SecretKey, project = Project, - ipfamily = IpFamily}; + ipfamily = IpFamily, + release = Release}; undefined -> {ok, Uri} = application:get_env(App, uri), {ok, PublicKey} = application:get_env(App, public_key), @@ -103,7 +107,8 @@ get_config(App) -> public_key = PublicKey, private_key = PrivateKey, project = Project, - ipfamily = IpFamily} + ipfamily = IpFamily, + release = Release} end. From 59183cfcb9d9003519aa570bee2c95a7eb720265 Mon Sep 17 00:00:00 2001 From: Hakan Nilsson Date: Wed, 6 Apr 2016 15:52:24 +0200 Subject: [PATCH 05/90] Only include extra if metadata is available --- src/raven_lager_backend.erl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/raven_lager_backend.erl b/src/raven_lager_backend.erl index f36ec72..f8a204f 100644 --- a/src/raven_lager_backend.erl +++ b/src/raven_lager_backend.erl @@ -62,4 +62,11 @@ capture({Message, Params}) -> parse_message(Log) -> {lager_msg:message(Log), [ {level, lager_msg:severity(Log)} - , {extra, lager_msg:metadata(Log)} ]}. + | extra(Log) + ]}. + +extra(Log) -> + case lager_msg:metadata(Log) of + [] -> []; + Extra -> [{extra, Extra}] + end. From eed6d0329c8ac573807c62fc6f7d9e5dd19c43d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Fievet?= <_@sebastien-fievet.fr> Date: Tue, 5 Jul 2016 15:16:09 +0200 Subject: [PATCH 06/90] Fix lager backend init/1 signature --- src/raven_lager_backend.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/raven_lager_backend.erl b/src/raven_lager_backend.erl index f8a204f..8b709cc 100644 --- a/src/raven_lager_backend.erl +++ b/src/raven_lager_backend.erl @@ -16,6 +16,8 @@ -record(state, {level}). +init(Level) when is_atom(Level) -> + init([{level, Level}]); init([{level, Level}]) -> {ok, #state{level=lager_util:level_to_num(Level)}}. From d0086600671ad7a5fb6572bdb2bc095f3841bf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 10 Apr 2017 14:37:18 +0200 Subject: [PATCH 07/90] Adds special handling of terminated cowboy_handlers (v1.x) --- src/raven_error_logger.erl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index f1bd0e5..986ec54 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -112,6 +112,23 @@ parse_message(error = Level, Pid, "** Generic process " ++ _, [Name, LastMessage {reason, Reason} ]} ]}; +parse_message(error = Level, Pid, "Error in process " ++ _, + [Name, Node, [ {reason, Reason} + , {mfa, {Handler, _, _}} + , {stacktrace, Stacktrace} + | Extras ]]) -> + %% cowboy_handler terminate + {format_exit(process, Name, {Reason, Stacktrace}), [ + {level, Level}, + {exception, {exit, Reason}}, + {stacktrace, Stacktrace}, + {extra, [ + {name, Name}, + {pid, Pid}, + {node, Node}, + {handler, Handler} | Extras + ]} + ]}; parse_message(error = Level, Pid, "Error in process " ++ _, [Name, Node, Reason]) -> %% process terminate {Exception, Stacktrace} = parse_reason(Reason), From a92a1df1f9b34320b8df705763f6ffa860eb6470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 6 Apr 2017 15:56:14 +0200 Subject: [PATCH 08/90] Use kivra_io:format/2 --- rebar.config | 3 ++- src/raven.erl | 2 +- src/raven_error_logger.erl | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/rebar.config b/rebar.config index 8c718d3..3c4dd22 100644 --- a/rebar.config +++ b/rebar.config @@ -6,5 +6,6 @@ {platform_define, "^R14", no_callbacks} ]}. {deps, [ - {jsx, ".*", {git, "git@github.com:talentdeficit/jsx.git", {branch, master}}} + {jsx, ".*", {git, "git@github.com:talentdeficit/jsx.git", {branch, master}}}, + {kivra_lib, {git, "git@github.com:kivra/kivra_lib.git", {branch, master}}} ]}. diff --git a/src/raven.erl b/src/raven.erl index 67e2e50..b445e9e 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -157,4 +157,4 @@ frame_to_json_i({Module, Function, Arguments, Location}) -> term_to_json_i(Term) when is_binary(Term); is_atom(Term) -> Term; term_to_json_i(Term) -> - iolist_to_binary(io_lib:format("~120p", [Term])). + iolist_to_binary(kivra_io:format("~120p", [Term])). diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 986ec54..1139622 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -386,4 +386,4 @@ format_term(Term) -> %% @private format(Format, Data) -> - iolist_to_binary(io_lib:format(Format, Data)). + iolist_to_binary(kivra_io:format(Format, Data)). From bc45d0294659b9253d106c9cd0d3e7f1b049cab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 6 Apr 2017 17:14:30 +0200 Subject: [PATCH 09/90] Adds special handling of 'Unhandled error:' --- src/raven.erl | 8 ++++++++ src/raven_error_logger.erl | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/raven.erl b/src/raven.erl index b445e9e..6b2ae29 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -47,6 +47,14 @@ capture(Message, Params) -> {type, Type}, {value, term_to_json_i(Value)} ]}; + ({http_request, {Method, Url, Headers}}) -> + {'sentry.interfaces.HTTP', [ + {request, [ + {method, Method}, + {url, Url}, + {headers, Headers} + ]} + ]}; ({tags, Tags}) -> {tags, [{Key, term_to_json_i(Value)} || {Key, Value} <- Tags]}; ({extra, Tags}) -> diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 1139622..d900199 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -145,6 +145,26 @@ parse_message(error = Level, Pid, "Error in process " ++ _, [Name, Node, Reason] ]}; parse_message(_Level, _Pid, "Ranch listener " ++ _, _Data) -> mask; +%% Start of Kivra specific +parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", + [[{method, Method}, {url, Url}, {headers, Headers}], + {unknown_error, Error}] = Data) -> + {format("Unhandled error: ~p", [Error]), [ + {level, Level}, + {http_request, {Method, Url, Headers}}, + {extra, [ + {pid, Pid}, + {data, Data} + ]} + ] ++ case Error of + {lifted_exn, Exception, Stacktrace} -> + [{exception, Exception}, + {stacktrace, Stacktrace}]; + _ -> + [] + end + }; +%% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ {level, Level}, From f55848dcf2fcd2eb0e76aa614e82c1d7579dccf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 7 Apr 2017 10:45:57 +0200 Subject: [PATCH 10/90] Fixes Http interface according to Sentry version 2 --- src/raven.erl | 10 ++++------ src/raven_error_logger.erl | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/raven.erl b/src/raven.erl index 6b2ae29..3bee136 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -48,12 +48,10 @@ capture(Message, Params) -> {value, term_to_json_i(Value)} ]}; ({http_request, {Method, Url, Headers}}) -> - {'sentry.interfaces.HTTP', [ - {request, [ - {method, Method}, - {url, Url}, - {headers, Headers} - ]} + {'sentry.interfaces.Http', [ + {method, Method}, + {url, Url}, + {headers, Headers} ]}; ({tags, Tags}) -> {tags, [{Key, term_to_json_i(Value)} || {Key, Value} <- Tags]}; diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index d900199..3b5085e 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -155,15 +155,15 @@ parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", {extra, [ {pid, Pid}, {data, Data} - ]} - ] ++ case Error of + ]} | + case Error of {lifted_exn, Exception, Stacktrace} -> [{exception, Exception}, {stacktrace, Stacktrace}]; _ -> [] end - }; + ]}; %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ From 78e50bd76731b844eb66d8ee1e6cdb18f9d6256b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 7 Apr 2017 13:44:47 +0200 Subject: [PATCH 11/90] Adds special handling of 'Error: {failed, Reason}...' and possibility of extras --- src/raven_error_logger.erl | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 3b5085e..96b23ac 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -147,8 +147,8 @@ parse_message(_Level, _Pid, "Ranch listener " ++ _, _Data) -> mask; %% Start of Kivra specific parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", - [[{method, Method}, {url, Url}, {headers, Headers}], - {unknown_error, Error}] = Data) -> + [[{method, Method}, {url, Url}, {headers, Headers}], + {unknown_error, Error}] = Data) -> {format("Unhandled error: ~p", [Error]), [ {level, Level}, {http_request, {Method, Url, Headers}}, @@ -164,6 +164,24 @@ parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", [] end ]}; +parse_message(error = Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} = Exception | _] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, Exception}, + {extra, [ + {pid, Pid} + ]} + ]}; +parse_message(error = Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | Rest]) + when is_list(Extras) -> + {format(Format, [{failed, Reason} | Rest]), [ + {level, Level}, + {exception, {failed, Reason}}, + {extra, [ + {pid, Pid} | + [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] + ]} + ]}; %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ From ea29fd42303746f0b228133ff066bca265dda5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 7 Apr 2017 17:05:35 +0200 Subject: [PATCH 12/90] Don't limit custom issues to error level --- src/raven_error_logger.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 96b23ac..f5799d8 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -164,7 +164,7 @@ parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", [] end ]}; -parse_message(error = Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} = Exception | _] = Data) -> +parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} = Exception | _] = Data) -> {format(Format, Data), [ {level, Level}, {exception, Exception}, @@ -172,7 +172,7 @@ parse_message(error = Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} {pid, Pid} ]} ]}; -parse_message(error = Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | Rest]) +parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | Rest]) when is_list(Extras) -> {format(Format, [{failed, Reason} | Rest]), [ {level, Level}, From 31986a8315c286f009a359d4fdfc542c6d6c2bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 7 Apr 2017 17:06:31 +0200 Subject: [PATCH 13/90] Adds special handling of failed operations like those in kivra_core_periodic --- src/raven_error_logger.erl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index f5799d8..b98d82c 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -182,6 +182,14 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] ]} ]}; +parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is_atom(Operation) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, Operation}}, + {extra, [ + {pid, Pid} + ]} + ]}; %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ From f047ae028f2bb1e230089d4fa36ef8af3aebce98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 11 Apr 2017 12:32:15 +0200 Subject: [PATCH 14/90] Adds kivra_lib to applications --- src/raven.app.src | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/raven.app.src b/src/raven.app.src index 98e8c0f..385e04b 100644 --- a/src/raven.app.src +++ b/src/raven.app.src @@ -8,7 +8,8 @@ crypto, public_key, ssl, - inets + inets, + kivra_lib ]}, {mod, {raven_app, []}}, {env, [ From 470f1a0709e3f5edd2b3f233b3b4cd3be3385502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 11 Apr 2017 15:27:17 +0200 Subject: [PATCH 15/90] Adds special handling of mechanus_modron error logs --- src/raven_error_logger.erl | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index b98d82c..3b9ae0d 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -162,7 +162,7 @@ parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", {stacktrace, Stacktrace}]; _ -> [] - end + end ]}; parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} = Exception | _] = Data) -> {format(Format, Data), [ @@ -190,6 +190,40 @@ parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is {pid, Pid} ]} ]}; +parse_message(Level, Pid, "~p: ~p no transition for ~p" = Format, [ID, Name, Event] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, + {mechanus_modron, transition, [{state, Name}, {event, Event}]}}}, + {extra, [ + {pid, Pid}, + {state, Name}, + {event, Event}, + {modron_id, ID} + ]} + ]}; +parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, + [ID, Action, {lifted_exn, Exception, Stacktrace}] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, Exception}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid}, + {action, Action}, + {modron_id, ID} + ]} + ]}; +parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, [ID, Action, Rsn] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {mechanus_modron, action, Action, Rsn}}}, + {extra, [ + {pid, Pid}, + {action, Action}, + {modron_id, ID} + ]} + ]}; %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ From dc2c9412369ece40ee31252c30263c7a924e7091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 11 Apr 2017 16:02:31 +0200 Subject: [PATCH 16/90] Cleaner error messages for failed actions in mechanus_modron --- src/raven_error_logger.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 3b9ae0d..3738cdd 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -202,9 +202,9 @@ parse_message(Level, Pid, "~p: ~p no transition for ~p" = Format, [ID, Name, Eve {modron_id, ID} ]} ]}; -parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, - [ID, Action, {lifted_exn, Exception, Stacktrace}] = Data) -> - {format(Format, Data), [ +parse_message(Level, Pid, "~p: action ~p failed: ~p", + [ID, Action, {lifted_exn, Exception, Stacktrace}]) -> + {format("~p: action ~p failed", [ID, Action]), [ {level, Level}, {exception, Exception}, {stacktrace, Stacktrace}, From 6ccc0595eecf0f27b1f879f919491824918651a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 22 Jun 2017 13:56:22 +0200 Subject: [PATCH 17/90] Special handling of krc warnings --- src/raven_error_logger.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 3738cdd..6d1de68 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -224,6 +224,16 @@ parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, [ID, Action, Rsn] {modron_id, ID} ]} ]}; +parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, + [B, _K, Rsn, Attempt, MaxAttempts] = Data) when Attempt < MaxAttempts -> + {format(Format, Data), [ + {level, warning}, + {exception, {krc_error, {B, Rsn}}}, + {extra, [ + {pid, Pid}, + {data, Data} + ]} + ]}; %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ From 3dbdcb665870897697b50fce2ba0e5550f623833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 22 Jun 2017 15:22:24 +0200 Subject: [PATCH 18/90] Properly send exceptions that are not two element tuples --- src/raven.erl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/raven.erl b/src/raven.erl index 3bee136..cd1f0d3 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -47,6 +47,11 @@ capture(Message, Params) -> {type, Type}, {value, term_to_json_i(Value)} ]}; + ({exception, Value}) -> + {'sentry.interfaces.Exception', [ + {type, error}, + {value, term_to_json_i(Value)} + ]}; ({http_request, {Method, Url, Headers}}) -> {'sentry.interfaces.Http', [ {method, Method}, From d85f143b20dec37d9bb233f1e135396c730a21ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 10 Jul 2017 13:53:28 +0200 Subject: [PATCH 19/90] Adds special handling of pacioli error logs --- src/raven_error_logger.erl | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 6d1de68..52ad7d6 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -234,6 +234,43 @@ parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, {data, Data} ]} ]}; +parse_message(Level, Pid, "** Exception: ~p~n" + "** Reason: ~p~n" + "** Stacktrace: ~p~n" ++ _ = Format, + [ {badmatch, {rollback, function_clause, [{M, F, Args, _} | _]}} + , _Rsn + , Stacktrace + | _ + ] = Data) -> + ExceptionValue = + case Args of + [Arg1|_] when is_atom(Arg1) -> {M, F, [Arg1|'_']}; + _ -> {M, F, '_'} + end, + {format(Format, Data), [ + {level, Level}, + {exception, {{badmatch, {rollback, function_clause, '...'}}, ExceptionValue}}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; +parse_message(Level, Pid, "** Exception: ~p~n" + "** Reason: ~p~n" + "** Stacktrace: ~p~n" ++ _ = Format, + [ {badmatch, {rollback, Exception, [{M, F, Arity, _} | _]}} + , _Rsn + , Stacktrace + | _ + ] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {{badmatch, {rollback, Exception, '...'}}, {M, F, Arity}}}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ From 3c620d4e172bc61ea40b689e95dd2a8ecc7aa164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 10 Jul 2017 14:34:11 +0200 Subject: [PATCH 20/90] json encode exception type (since we're not always exactly sending the true type of an exception...) --- src/raven.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raven.erl b/src/raven.erl index cd1f0d3..29317df 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -44,7 +44,7 @@ capture(Message, Params) -> ]}; ({exception, {Type, Value}}) -> {'sentry.interfaces.Exception', [ - {type, Type}, + {type, term_to_json_i(Type)}, {value, term_to_json_i(Value)} ]}; ({exception, Value}) -> From 33a18662ff535194c6b1e317b8f4c41577e8d894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 10 Jul 2017 16:54:41 +0200 Subject: [PATCH 21/90] Small improvement --- src/raven_error_logger.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 52ad7d6..67ae8c8 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -245,7 +245,7 @@ parse_message(Level, Pid, "** Exception: ~p~n" ExceptionValue = case Args of [Arg1|_] when is_atom(Arg1) -> {M, F, [Arg1|'_']}; - _ -> {M, F, '_'} + _ -> {M, F, length(Args)} end, {format(Format, Data), [ {level, Level}, From fa33633c2837d0b6906596b4a84bc9ba39838b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 11 Jul 2017 14:33:16 +0200 Subject: [PATCH 22/90] Mask warnings for failed tasks in KKng --- src/raven_error_logger.erl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 67ae8c8..067b08c 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -271,6 +271,9 @@ parse_message(Level, Pid, "** Exception: ~p~n" {pid, Pid} ]} ]}; +% Mask warnings for failed tasks in KKng +parse_message(warning = _Level, _Pid, "failed task: ~w", [_Tid]) -> + mask; %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ From bc4ef1dbd7b0006e9654afb019bdae2810b5d35b Mon Sep 17 00:00:00 2001 From: Hakan Nilsson Date: Tue, 3 Oct 2017 14:51:06 +0200 Subject: [PATCH 23/90] crypto:rand_uniform is deprecated, use rand:uniform instead --- src/raven.erl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/raven.erl b/src/raven.erl index 29317df..2bc9cd3 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -124,11 +124,11 @@ get_config(App) -> event_id_i() -> - U0 = crypto:rand_uniform(0, (2 bsl 32) - 1), - U1 = crypto:rand_uniform(0, (2 bsl 16) - 1), - U2 = crypto:rand_uniform(0, (2 bsl 12) - 1), - U3 = crypto:rand_uniform(0, (2 bsl 32) - 1), - U4 = crypto:rand_uniform(0, (2 bsl 30) - 1), + U0 = rand:uniform((2 bsl 32) - 1) - 1, + U1 = rand:uniform((2 bsl 16) - 1) - 1, + U2 = rand:uniform((2 bsl 12) - 1) - 1, + U3 = rand:uniform((2 bsl 32) - 1) - 1, + U4 = rand:uniform((2 bsl 30) - 1) - 1, <> = <>, iolist_to_binary(io_lib:format("~32.16.0b", [UUID])). From 1126daa31691559d1029fd4c1be40dd9673b34fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 13 Nov 2017 14:23:40 +0100 Subject: [PATCH 24/90] Adds special handling for 'unable to fetch payments from pacioli for user' --- src/raven_error_logger.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 067b08c..2a3dd1d 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -234,6 +234,16 @@ parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, {data, Data} ]} ]}; +parse_message(Level, Pid, "unable to fetch payments from pacioli for user ~p: ~p" = Format, + [UKey, Rsn] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {pacioli, payment_collection, Rsn}}}, + {extra, [ + {pid, Pid}, + {user_key, UKey} + ]} + ]}; parse_message(Level, Pid, "** Exception: ~p~n" "** Reason: ~p~n" "** Stacktrace: ~p~n" ++ _ = Format, From ad8b87581f57cb23d4b25362c037ed59b5342521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 13 Nov 2017 14:49:24 +0100 Subject: [PATCH 25/90] Adds special handling for KRC exits --- src/raven_error_logger.erl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 2a3dd1d..47dbefb 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -234,6 +234,15 @@ parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, {data, Data} ]} ]}; +parse_message(Level, Pid, "Krc EXIT ~p: ~p" = Format, [Pid, Rsn] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {krc_exit, Rsn}}, + {extra, [ + {pid, Pid}, + {data, Data} + ]} + ]}; parse_message(Level, Pid, "unable to fetch payments from pacioli for user ~p: ~p" = Format, [UKey, Rsn] = Data) -> {format(Format, Data), [ From f7127e9c8c00098515994eddc60de9cefb79344e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 13 Nov 2017 15:08:12 +0100 Subject: [PATCH 26/90] Adds special handling for 'unable to pay using pacioli for user' --- src/raven_error_logger.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 47dbefb..e838f0f 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -253,6 +253,16 @@ parse_message(Level, Pid, "unable to fetch payments from pacioli for user ~p: ~p {user_key, UKey} ]} ]}; +parse_message(Level, Pid, "unable to pay using pacioli for user ~p: ~p" = Format, + [UKey, Rsn] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {pacioli, pay, Rsn}}}, + {extra, [ + {pid, Pid}, + {user_key, UKey} + ]} + ]}; parse_message(Level, Pid, "** Exception: ~p~n" "** Reason: ~p~n" "** Stacktrace: ~p~n" ++ _ = Format, From 5989147325d4db34609d82804f158c7c1df9f73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 13 Nov 2017 15:16:59 +0100 Subject: [PATCH 27/90] Moar special handling for pacioli errors --- src/raven_error_logger.erl | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index e838f0f..1dcd424 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -244,7 +244,7 @@ parse_message(Level, Pid, "Krc EXIT ~p: ~p" = Format, [Pid, Rsn] = Data) -> ]} ]}; parse_message(Level, Pid, "unable to fetch payments from pacioli for user ~p: ~p" = Format, - [UKey, Rsn] = Data) -> + [UKey, Rsn] = Data) -> {format(Format, Data), [ {level, Level}, {exception, {failed, {pacioli, payment_collection, Rsn}}}, @@ -254,7 +254,7 @@ parse_message(Level, Pid, "unable to fetch payments from pacioli for user ~p: ~p ]} ]}; parse_message(Level, Pid, "unable to pay using pacioli for user ~p: ~p" = Format, - [UKey, Rsn] = Data) -> + [UKey, Rsn] = Data) -> {format(Format, Data), [ {level, Level}, {exception, {failed, {pacioli, pay, Rsn}}}, @@ -263,6 +263,36 @@ parse_message(Level, Pid, "unable to pay using pacioli for user ~p: ~p" = Format {user_key, UKey} ]} ]}; +parse_message(Level, Pid, "unable to delete mandate from pacioli for user ~p: ~p" = Format, + [UKey, Rsn] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {pacioli, del_mandate, Rsn}}}, + {extra, [ + {pid, Pid}, + {user_key, UKey} + ]} + ]}; +parse_message(Level, Pid, "unable to cancel payments from pacioli for user ~p: ~p" = Format, + [UKey, Rsn] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {pacioli, cancel_payment, Rsn}}}, + {extra, [ + {pid, Pid}, + {user_key, UKey} + ]} + ]}; +parse_message(Level, Pid, "unable to onboard payments from pacioli for user ~p: ~p" = Format, + [UKey, Rsn] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {pacioli, new_mandate, Rsn}}}, + {extra, [ + {pid, Pid}, + {user_key, UKey} + ]} + ]}; parse_message(Level, Pid, "** Exception: ~p~n" "** Reason: ~p~n" "** Stacktrace: ~p~n" ++ _ = Format, From d9b41cfb965f79738551571806ebb2b283bf9e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 14 Nov 2017 14:35:41 +0100 Subject: [PATCH 28/90] Adds special handling for 'Brod - Error in produce response' --- src/raven_error_logger.erl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 1dcd424..44417ed 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -146,6 +146,7 @@ parse_message(error = Level, Pid, "Error in process " ++ _, [Name, Node, Reason] parse_message(_Level, _Pid, "Ranch listener " ++ _, _Data) -> mask; %% Start of Kivra specific +%% --- rest_prelude ---- parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", [[{method, Method}, {url, Url}, {headers, Headers}], {unknown_error, Error}] = Data) -> @@ -164,6 +165,7 @@ parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", [] end ]}; +%% --- General --- parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} = Exception | _] = Data) -> {format(Format, Data), [ {level, Level}, @@ -182,6 +184,7 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] ]} ]}; +%% --- kivra_core_periodic --- parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is_atom(Operation) -> {format(Format, Data), [ {level, Level}, @@ -190,6 +193,7 @@ parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is {pid, Pid} ]} ]}; +%% --- Mechanus --- parse_message(Level, Pid, "~p: ~p no transition for ~p" = Format, [ID, Name, Event] = Data) -> {format(Format, Data), [ {level, Level}, @@ -224,6 +228,19 @@ parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, [ID, Action, Rsn] {modron_id, ID} ]} ]}; +%% --- Brod --- +parse_message(Level, Pid, "Error in produce response\n" + "Topic: ~s Partition: ~B Offset: ~B Error: ~p" = Format, + [Topic, _Partition, _Offset, ErrorCode] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {brod, produce, Topic, ErrorCode}}}, + {extra, [ + {pid, Pid}, + {data, Data} + ]} + ]}; +%% --- KRC --- parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, [B, _K, Rsn, Attempt, MaxAttempts] = Data) when Attempt < MaxAttempts -> {format(Format, Data), [ @@ -243,6 +260,7 @@ parse_message(Level, Pid, "Krc EXIT ~p: ~p" = Format, [Pid, Rsn] = Data) -> {data, Data} ]} ]}; +%% --- Pacioli calls from Kivra Core --- parse_message(Level, Pid, "unable to fetch payments from pacioli for user ~p: ~p" = Format, [UKey, Rsn] = Data) -> {format(Format, Data), [ @@ -293,6 +311,7 @@ parse_message(Level, Pid, "unable to onboard payments from pacioli for user ~p: {user_key, UKey} ]} ]}; +%% --- Pacioli --- parse_message(Level, Pid, "** Exception: ~p~n" "** Reason: ~p~n" "** Stacktrace: ~p~n" ++ _ = Format, @@ -330,6 +349,7 @@ parse_message(Level, Pid, "** Exception: ~p~n" {pid, Pid} ]} ]}; +%% --- KKng --- % Mask warnings for failed tasks in KKng parse_message(warning = _Level, _Pid, "failed task: ~w", [_Tid]) -> mask; From 1493f8105cb28a62829d2c3233af9e1acab4a9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 14 Nov 2017 15:10:20 +0100 Subject: [PATCH 29/90] Adds special handling for 'ULog error' --- src/raven_error_logger.erl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 44417ed..a1b497c 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -184,6 +184,17 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] ]} ]}; +%% Beehive +parse_message(Level, Pid, "ULog error: ~p" = Format, [Reason] = _Data) -> + {Exception, Stacktrace} = parse_reason(Reason), + {format(Format, Exception), [ + {level, Level}, + {exception, Exception}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; %% --- kivra_core_periodic --- parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is_atom(Operation) -> {format(Format, Data), [ From 7dd417528d30cc146951a16031c66b32c69fa63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 14 Nov 2017 15:34:19 +0100 Subject: [PATCH 30/90] Adds special handling for 'ULog error' in ulogc --- src/raven_error_logger.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index a1b497c..d0864b5 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -195,6 +195,16 @@ parse_message(Level, Pid, "ULog error: ~p" = Format, [Reason] = _Data) -> {pid, Pid} ]} ]}; +%% ulogc +parse_message(Level, Pid, "ULog error: ~p/~p" ++ _ = Format, + [C, R | _] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {C, R}}, + {extra, [ + {pid, Pid} + ]} + ]}; %% --- kivra_core_periodic --- parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is_atom(Operation) -> {format(Format, Data), [ From 257c145cd094d7a3b6c71b9c12ff50eba97735fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 28 Nov 2017 16:27:08 +0100 Subject: [PATCH 31/90] Bugfix --- src/raven_error_logger.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index d0864b5..178f449 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -187,7 +187,7 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | %% Beehive parse_message(Level, Pid, "ULog error: ~p" = Format, [Reason] = _Data) -> {Exception, Stacktrace} = parse_reason(Reason), - {format(Format, Exception), [ + {format(Format, [Exception]), [ {level, Level}, {exception, Exception}, {stacktrace, Stacktrace}, From ceebb52051db38762c4a174a205aee461a364255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 14 Dec 2017 12:34:57 +0100 Subject: [PATCH 32/90] Adds special handling for 'ULog error' in ulog_kafka_client --- src/raven_error_logger.erl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 178f449..5824dd9 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -205,6 +205,15 @@ parse_message(Level, Pid, "ULog error: ~p/~p" ++ _ = Format, {pid, Pid} ]} ]}; +parse_message(Level, Pid, "ULog error: ~p~n" ++ _ = Format, + [Rsn | _] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {ulog_error, Rsn}}, + {extra, [ + {pid, Pid} + ]} + ]}; %% --- kivra_core_periodic --- parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is_atom(Operation) -> {format(Format, Data), [ From 9e0f8545fe7c27ef5d969c6e042b695748094100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 15 Dec 2017 14:50:08 +0100 Subject: [PATCH 33/90] Adds another handling for stacktraces in 'ULog error' in ulog_kafka_client --- src/raven_error_logger.erl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 5824dd9..0ac7995 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -205,6 +205,17 @@ parse_message(Level, Pid, "ULog error: ~p/~p" ++ _ = Format, {pid, Pid} ]} ]}; +parse_message(Level, Pid, "ULog error: ~p~n" ++ _ = Format, + [{{Class, Reason}, [{_, _, _, _} | _] = Stacktrace} | Rest]) + when Class =:= exit; Class =:= error; Class =:= throw -> + {format(Format, [{Class, Reason} | Rest]), [ + {level, Level}, + {exception, {Class, Reason}}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; parse_message(Level, Pid, "ULog error: ~p~n" ++ _ = Format, [Rsn | _] = Data) -> {format(Format, Data), [ From 866b0e4947825d9af3c9d832e7b1223bca36ef16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 15 Dec 2017 16:27:46 +0100 Subject: [PATCH 34/90] Adds special handling for terminating brod_client --- src/raven_error_logger.erl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 0ac7995..444f1a7 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -281,6 +281,18 @@ parse_message(Level, Pid, "Error in produce response\n" {data, Data} ]} ]}; +parse_message(Level, Pid, "~p [~p] ~p is terminating\nreason: ~p~n" = Format, + [_Module, _Pid, _ClientId, Reason] = Data) -> + {Exception, Stacktrace} = parse_reason(Reason), + {format(Format, Data), [ + {level, Level}, + {exception, Exception}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid}, + {data, Data} + ]} + ]}; %% --- KRC --- parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, [B, _K, Rsn, Attempt, MaxAttempts] = Data) when Attempt < MaxAttempts -> From cd4c0c6cf326083d942f3ade1ebb80993daf98d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 28 Dec 2017 12:25:26 +0100 Subject: [PATCH 35/90] Lower 'Error in produce response' to warning --- src/raven_error_logger.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 444f1a7..3a42a4e 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -270,11 +270,11 @@ parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, [ID, Action, Rsn] ]} ]}; %% --- Brod --- -parse_message(Level, Pid, "Error in produce response\n" - "Topic: ~s Partition: ~B Offset: ~B Error: ~p" = Format, +parse_message(_Level, Pid, "Error in produce response\n" + "Topic: ~s Partition: ~B Offset: ~B Error: ~p" = Format, [Topic, _Partition, _Offset, ErrorCode] = Data) -> {format(Format, Data), [ - {level, Level}, + {level, warning}, {exception, {failed, {brod, produce, Topic, ErrorCode}}}, {extra, [ {pid, Pid}, From 663612b6b212f9a070098f5e03ca1a6f29318bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 28 Dec 2017 12:36:06 +0100 Subject: [PATCH 36/90] Adds helping description to 'Error in produce response' --- src/raven_error_logger.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 3a42a4e..7efbc4b 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -273,7 +273,9 @@ parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, [ID, Action, Rsn] parse_message(_Level, Pid, "Error in produce response\n" "Topic: ~s Partition: ~B Offset: ~B Error: ~p" = Format, [Topic, _Partition, _Offset, ErrorCode] = Data) -> - {format(Format, Data), [ + Extra = "\nRetriable errors will be retried, actual failures will result in " + "an exit. Look for 'producer_down'.", + {format(Format ++ Extra, Data), [ {level, warning}, {exception, {failed, {brod, produce, Topic, ErrorCode}}}, {extra, [ From 7e09e163f7701b6bb9476248cefeb4cae2d9fb21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 3 May 2018 16:36:31 +0200 Subject: [PATCH 37/90] Adds 'Catched this: ~p' log --- src/raven_error_logger.erl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 7efbc4b..460b217 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -184,6 +184,17 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] ]} ]}; +parse_message(Level, Pid, "Catched this: ~p" ++ _ = Format, + [{{Class, Reason}, [{_, _, _, _} | _] = Stacktrace} | Rest]) + when Class =:= exit; Class =:= error; Class =:= throw -> + {format(Format, [{Class, Reason} | Rest]), [ + {level, Level}, + {exception, {Class, Reason}}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; %% Beehive parse_message(Level, Pid, "ULog error: ~p" = Format, [Reason] = _Data) -> {Exception, Stacktrace} = parse_reason(Reason), From 2601fe51ce6c34461ea2635f6c5947fb1ec1285a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 23 Oct 2018 09:19:23 +0200 Subject: [PATCH 38/90] Adds special handling for too_many_requests in rest_prelude --- src/raven_error_logger.erl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 460b217..ca96e5a 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -165,6 +165,14 @@ parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", [] end ]}; +parse_message(Level, Pid, "Too Many Requests: ~s ~p" ++ _ = Format, [Method, Resource | _] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {too_many_requests, {Method, Resource}}}, + {extra, [ + {pid, Pid} + ]} + ]}; %% --- General --- parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} = Exception | _] = Data) -> {format(Format, Data), [ From 034714e59009312a82614e0f47348f76db97608b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 26 Oct 2018 10:33:17 +0200 Subject: [PATCH 39/90] Adds support for user interface --- src/raven.erl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/raven.erl b/src/raven.erl index 2bc9cd3..e8a98c6 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -58,6 +58,11 @@ capture(Message, Params) -> {url, Url}, {headers, Headers} ]}; + % Reserved keys are 'id', 'username', 'email' and 'ip_address' out + % of which ONE needs to be supplied. Additional arbitrary keys may + % also be sent. + ({user, KVs}) when is_list(KVs) -> + {'sentry.interfaces.User', KVs}; ({tags, Tags}) -> {tags, [{Key, term_to_json_i(Value)} || {Key, Value} <- Tags]}; ({extra, Tags}) -> From 845de030eaabe8b878d3a1a0c752e2f6bd61f5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Fri, 26 Oct 2018 10:33:28 +0200 Subject: [PATCH 40/90] Adds user data to too_many_requests event --- src/raven_error_logger.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index ca96e5a..ca96689 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -165,10 +165,15 @@ parse_message(error = Level, Pid, "Unhandled error: ~p~n~p", [] end ]}; -parse_message(Level, Pid, "Too Many Requests: ~s ~p" ++ _ = Format, [Method, Resource | _] = Data) -> - {format(Format, Data), [ +parse_message(Level, Pid, "Too Many Requests: ~s ~p\n" + "Rate Limit Key: ~s\n" + "Raven User: ~p", + [Method, Resource, RateLimitKey, RavenUser] = _Data) when is_list(RavenUser) -> + {format("Too Many Requests: ~s ~p\n" + "Rate Limit Key: ~s", [Method, Resource, RateLimitKey]), [ {level, Level}, {exception, {too_many_requests, {Method, Resource}}}, + {user, RavenUser}, {extra, [ {pid, Pid} ]} From 997202ce00a3f9af5f1941354d97985494b8deec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Wed, 21 Nov 2018 10:59:41 +0100 Subject: [PATCH 41/90] Adds special handling for 'cybertron_email failed for 5 minutes' --- src/raven_error_logger.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index ca96689..4087904 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -219,6 +219,16 @@ parse_message(Level, Pid, "ULog error: ~p" = Format, [Reason] = _Data) -> {pid, Pid} ]} ]}; +%% Cybertron +parse_message(Level, Pid, "~p failed for 5 minutes: ~p" = Format, + [cybertron_email, {error, Status, _Headers, _Body}] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {failed, {cybertron_email, Status}}}, + {extra, [ + {pid, Pid} + ]} + ]}; %% ulogc parse_message(Level, Pid, "ULog error: ~p/~p" ++ _ = Format, [C, R | _] = Data) -> From 2a0422e848439378cf405622d3d56be87a739eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Mon, 26 Nov 2018 15:42:43 +0100 Subject: [PATCH 42/90] General handling of exceptions from macro in prelude.hrl (#7) --- src/raven_error_logger.erl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 4087904..45d267c 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -197,15 +197,16 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] ]} ]}; -parse_message(Level, Pid, "Catched this: ~p" ++ _ = Format, - [{{Class, Reason}, [{_, _, _, _} | _] = Stacktrace} | Rest]) +parse_message(Level, Pid, "Exception: ~p\n" + "Extras: ~p" = Format, + [{{Class, Reason}, [{_, _, _, _} | _] = Stacktrace}, Extras]) when Class =:= exit; Class =:= error; Class =:= throw -> - {format(Format, [{Class, Reason} | Rest]), [ + {format(Format, [{Class, Reason}, Extras]), [ {level, Level}, {exception, {Class, Reason}}, {stacktrace, Stacktrace}, {extra, [ - {pid, Pid} + {pid, Pid} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] ]} ]}; %% Beehive From b46e7405419506bdd8e88840d2bacedcfa87208f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Wed, 13 Feb 2019 10:59:47 +0100 Subject: [PATCH 43/90] More special handling for Pacioli exceptions --- src/raven_error_logger.erl | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 45d267c..4ebc973 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -439,6 +439,44 @@ parse_message(Level, Pid, "** Exception: ~p~n" {pid, Pid} ]} ]}; +parse_message(Level, Pid, "** Exception: ~p~n" + "** Reason: ~p~n" + "** Stacktrace: ~p~n" ++ _ = Format, + [ { { { badmatch + , {error, {Exception, [{_,_,_,_}|_] = InnerStacktrace}} + } + , [{_,_,_,_}|_] = MiddleStacktrace + } + , _ + } + , _Rsn + , _Stacktrace + | _ + ] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {badmatch, {error, Exception, '...'}}}, + {stacktrace, InnerStacktrace ++ MiddleStacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; +parse_message(Level, Pid, "** Exception: ~p~n" + "** Reason: ~p~n" + "** Stacktrace: ~p~n" ++ _ = Format, + [ {ShutdownOrNoproc, {gen_server, CallOrCast, _}} + , _Rsn + , Stacktrace + | _ + ] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {ShutdownOrNoproc, {gen_server, CallOrCast, '...'}}}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; %% --- KKng --- % Mask warnings for failed tasks in KKng parse_message(warning = _Level, _Pid, "failed task: ~w", [_Tid]) -> From 0e4afadc5c4d20aca8bbea02902eb70916ad9c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 14 Feb 2019 17:48:43 +0100 Subject: [PATCH 44/90] Adds handling for OTP 20+ gen_server reports --- src/raven_error_logger.erl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 986ec54..408049a 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -65,6 +65,41 @@ parse_message(error = Level, Pid, "** Generic server " ++ _, [Name, LastMessage, {reason, Reason} ]} ]}; +%% OTP 20 crash reports where the client pid is dead don't include the stacktrace +parse_message(error = Level, Pid, "** Generic server " ++ _, [Name, LastMessage, State, Reason, Client]) -> + %% gen_server terminate + {Exception, Stacktrace} = parse_reason(Reason), + {format_exit(gen_server, Name, Reason), [ + {level, Level}, + {exception, Exception}, + {stacktrace, Stacktrace}, + {extra, [ + {name, Name}, + {pid, Pid}, + {last_message, LastMessage}, + {state, State}, + {reason, Reason}, + {client, Client} + ]} + ]}; +%% OTP 20 crash reports contain the pid of the client and stacktrace +parse_message(error = Level, Pid, "** Generic server " ++ _, [Name, LastMessage, State, Reason, Client, ClientStacktrace]) -> + %% gen_server terminate + {Exception, Stacktrace} = parse_reason(Reason), + {format_exit(gen_server, Name, Reason), [ + {level, Level}, + {exception, Exception}, + {stacktrace, Stacktrace}, + {extra, [ + {name, Name}, + {pid, Pid}, + {last_message, LastMessage}, + {state, State}, + {reason, Reason}, + {client, Client}, + {client_stacktrace, ClientStacktrace} + ]} + ]}; parse_message(error = Level, Pid, "** State machine " ++ _, [Name, LastMessage, StateName, State, Reason]) -> %% gen_fsm terminate {Exception, Stacktrace} = parse_reason(Reason), From ddcdc49249cee0832505e5e07a2de5e5d3f53715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 26 Feb 2019 17:44:04 +0100 Subject: [PATCH 45/90] Adds handling for gen_statem reports --- src/raven_error_logger.erl | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index aae97ea..da86909 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -116,6 +116,39 @@ parse_message(error = Level, Pid, "** State machine " ++ _, [Name, LastMessage, {reason, Reason} ]} ]}; +parse_message(error = Level, Pid, "** State machine " ++ _, [Name, LastEvent, {StateName, StateData}, Class, Reason, CallbackMode, Stacktrace]) -> + %% gen_statem terminate + {format_exit(gen_statem, Name, Reason), [ + {level, Level}, + {exception, {Class, Reason}}, + {stacktrace, Stacktrace}, + {extra, [ + {name, Name}, + {pid, Pid}, + {last_event, LastEvent}, + {state_name, StateName}, + {state_data, StateData}, + {callback_mode, CallbackMode}, + {reason, Reason} + ]} + ]}; +parse_message(error = Level, Pid, "** State machine " ++ _, [Name, LastEvent, [{StateName, StateData}], Class, Reason, CallbackMode, Stacktrace]) -> + %% gen_statem terminate + %% sometimes gen_statem wraps its statename/data in a list for some reason??? + {format_exit(gen_statem, Name, Reason), [ + {level, Level}, + {exception, {Class, Reason}}, + {stacktrace, Stacktrace}, + {extra, [ + {name, Name}, + {pid, Pid}, + {last_event, LastEvent}, + {state_name, StateName}, + {state_data, StateData}, + {callback_mode, CallbackMode}, + {reason, Reason} + ]} + ]}; parse_message(error = Level, Pid, "** gen_event handler " ++ _, [ID, Name, LastMessage, State, Reason]) -> %% gen_event terminate {Exception, Stacktrace} = parse_reason(Reason), @@ -673,6 +706,10 @@ format_reason({bad_return_value, Val}) -> ["bad return value ", format_term(Val)]; format_reason({{bad_return_value, Val}, Trace}) -> ["bad return value ", format_term(Val), " in ", format_mfa(Trace)]; +format_reason({bad_return_from_state_function, Val}) -> + ["bad return value from state function ", format_term(Val)]; +format_reason({{bad_return_from_state_function, Val}, Trace}) -> + ["bad return value from state function ", format_term(Val), " in ", format_mfa(Trace)]; format_reason({{badrecord, Record}, Trace}) -> ["bad record ", format_term(Record), " in ", format_mfa(Trace)]; format_reason({{case_clause, Value}, Trace}) -> From 6b97b46a3d72006e55f97f38128f03f4482d1628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 11 Apr 2019 13:51:45 +0200 Subject: [PATCH 46/90] Adds special handling for terminating brod_consumer --- src/raven_error_logger.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index da86909..6eb606b 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -398,6 +398,16 @@ parse_message(Level, Pid, "~p [~p] ~p is terminating\nreason: ~p~n" = Format, {data, Data} ]} ]}; +parse_message(Level, Pid, "~p ~p terminating, reason:\n~p" = Format, + [_Module, _Pid, Reason] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {exit, Reason}}, + {extra, [ + {pid, Pid}, + {data, Data} + ]} + ]}; %% --- KRC --- parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, [B, _K, Rsn, Attempt, MaxAttempts] = Data) when Attempt < MaxAttempts -> From d8ba1b595aa39ac2db7d5a068b1797d72cd6bace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 11 Apr 2019 13:58:19 +0200 Subject: [PATCH 47/90] Unintentional match of Pids in 'Krc Exit' message :( --- src/raven_error_logger.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 6eb606b..5f16d59 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -419,7 +419,7 @@ parse_message(_Level, Pid, "{~p, ~p} error: ~p, attempt ~p of ~p" = Format, {data, Data} ]} ]}; -parse_message(Level, Pid, "Krc EXIT ~p: ~p" = Format, [Pid, Rsn] = Data) -> +parse_message(Level, Pid, "Krc EXIT ~p: ~p" = Format, [_Pid, Rsn] = Data) -> {format(Format, Data), [ {level, Level}, {exception, {krc_exit, Rsn}}, From 067f20fa2fb33b5dba7f6f6ade261412564cf300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Tue, 14 May 2019 11:43:57 +0200 Subject: [PATCH 48/90] Adds special handling for failed asserts in Pacioli --- src/raven_error_logger.erl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 5f16d59..23c93ab 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -555,6 +555,23 @@ parse_message(Level, Pid, "** Exception: ~p~n" {pid, Pid} ]} ]}; +parse_message(Level, Pid, "** Exception: ~p~n" + "** Reason: ~p~n" + "** Stacktrace: ~p~n" ++ _ = Format, + [ {assert, AssertData} + , _Rsn + , Stacktrace + | _ + ] = Data) -> + Expression = proplists:get_value(expression, AssertData), + {format(Format, Data), [ + {level, Level}, + {exception, {assert, format_string(Expression)}}, + {stacktrace, Stacktrace}, + {extra, [ + {pid, Pid} + ]} + ]}; %% --- KKng --- % Mask warnings for failed tasks in KKng parse_message(warning = _Level, _Pid, "failed task: ~w", [_Tid]) -> From dd2ad2ed1279cc15b873658ee22c083c417c45c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 23 May 2019 13:03:00 +0200 Subject: [PATCH 49/90] chore: 'kivra_io' has moved to 'stdlib2' and is now called 's2_io' --- rebar.config | 2 +- src/raven.app.src | 2 +- src/raven.erl | 2 +- src/raven_error_logger.erl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rebar.config b/rebar.config index 3c4dd22..e2d0b88 100644 --- a/rebar.config +++ b/rebar.config @@ -7,5 +7,5 @@ ]}. {deps, [ {jsx, ".*", {git, "git@github.com:talentdeficit/jsx.git", {branch, master}}}, - {kivra_lib, {git, "git@github.com:kivra/kivra_lib.git", {branch, master}}} + {stdlib2, {git, "git@github.com:kivra/stdlib2.git", {branch, master}}} ]}. diff --git a/src/raven.app.src b/src/raven.app.src index 385e04b..c9d1912 100644 --- a/src/raven.app.src +++ b/src/raven.app.src @@ -9,7 +9,7 @@ public_key, ssl, inets, - kivra_lib + stdlib2 ]}, {mod, {raven_app, []}}, {env, [ diff --git a/src/raven.erl b/src/raven.erl index e8a98c6..5ac197f 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -173,4 +173,4 @@ frame_to_json_i({Module, Function, Arguments, Location}) -> term_to_json_i(Term) when is_binary(Term); is_atom(Term) -> Term; term_to_json_i(Term) -> - iolist_to_binary(kivra_io:format("~120p", [Term])). + iolist_to_binary(s2_io:format("~120p", [Term])). diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 23c93ab..8aeaa60 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -822,4 +822,4 @@ format_term(Term) -> %% @private format(Format, Data) -> - iolist_to_binary(kivra_io:format(Format, Data)). + iolist_to_binary(s2_io:format(Format, Data)). From 24c4fd8483dee61809bf23a063746bdc906f96ee Mon Sep 17 00:00:00 2001 From: Hakan Nilsson Date: Tue, 18 Jun 2019 15:04:12 +0200 Subject: [PATCH 50/90] Group brod produce errors --- src/raven_error_logger.erl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 8aeaa60..2f334e1 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -328,6 +328,19 @@ parse_message(Level, Pid, "ULog error: ~p~n" ++ _ = Format, {pid, Pid} ]} ]}; +%% brod +parse_message(Level, Pid, "Produce error ~s-~B Offset: ~B Error: ~p" = Format, + [Topic, Partition, Offset, Error] = Data) -> + {format(Format, Data), [ + {level, Level}, + {exception, {brod_produce_error, Error, Topic}}, + {extra, [ + {topic, Topic}, + {partition, Partition}, + {offset, Offset}, + {pid, Pid} + ]} + ]}; %% --- kivra_core_periodic --- parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is_atom(Operation) -> {format(Format, Data), [ From 637955f05d95b0946ce5cd6ea3f683d310dbfc37 Mon Sep 17 00:00:00 2001 From: Hakan Nilsson Date: Wed, 19 Jun 2019 11:36:53 +0200 Subject: [PATCH 51/90] Handle brod produce error (take 2) --- src/raven_error_logger.erl | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 2f334e1..ff68595 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -328,19 +328,6 @@ parse_message(Level, Pid, "ULog error: ~p~n" ++ _ = Format, {pid, Pid} ]} ]}; -%% brod -parse_message(Level, Pid, "Produce error ~s-~B Offset: ~B Error: ~p" = Format, - [Topic, Partition, Offset, Error] = Data) -> - {format(Format, Data), [ - {level, Level}, - {exception, {brod_produce_error, Error, Topic}}, - {extra, [ - {topic, Topic}, - {partition, Partition}, - {offset, Offset}, - {pid, Pid} - ]} - ]}; %% --- kivra_core_periodic --- parse_message(Level, Pid, "[~p] " ++ _ = Format, [Operation | _] = Data) when is_atom(Operation) -> {format(Format, Data), [ @@ -386,8 +373,7 @@ parse_message(Level, Pid, "~p: action ~p failed: ~p" = Format, [ID, Action, Rsn] ]} ]}; %% --- Brod --- -parse_message(_Level, Pid, "Error in produce response\n" - "Topic: ~s Partition: ~B Offset: ~B Error: ~p" = Format, +parse_message(_Level, Pid, "Produce error ~s-~B Offset: ~B Error: ~p" = Format, [Topic, _Partition, _Offset, ErrorCode] = Data) -> Extra = "\nRetriable errors will be retried, actual failures will result in " "an exit. Look for 'producer_down'.", From 6c480c36655d42f029f68c652d6b8a6e0d7a8080 Mon Sep 17 00:00:00 2001 From: Max Nordlund gmail Date: Mon, 30 Sep 2019 16:47:57 +0200 Subject: [PATCH 52/90] Remove beehive special case --- src/raven_error_logger.erl | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index ff68595..9a1cf62 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -277,17 +277,6 @@ parse_message(Level, Pid, "Exception: ~p\n" {pid, Pid} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] ]} ]}; -%% Beehive -parse_message(Level, Pid, "ULog error: ~p" = Format, [Reason] = _Data) -> - {Exception, Stacktrace} = parse_reason(Reason), - {format(Format, [Exception]), [ - {level, Level}, - {exception, Exception}, - {stacktrace, Stacktrace}, - {extra, [ - {pid, Pid} - ]} - ]}; %% Cybertron parse_message(Level, Pid, "~p failed for 5 minutes: ~p" = Format, [cybertron_email, {error, Status, _Headers, _Body}] = Data) -> From 10b7d7c813113d4445b33c9c5a12472460d15ed6 Mon Sep 17 00:00:00 2001 From: Max Nordlund kivra Date: Mon, 16 Dec 2019 11:01:28 +0100 Subject: [PATCH 53/90] Ignore build and lock file --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 30b607d..170611a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .* /deps/ /ebin/ +/_build +rebar.lock \ No newline at end of file From a8a1ab2a323ae9e29e16562c642ffc5f0a236bed Mon Sep 17 00:00:00 2001 From: Max Nordlund kivra Date: Mon, 16 Dec 2019 11:01:35 +0100 Subject: [PATCH 54/90] Support Sentry users for general error macros The ?failed and ?exception macros get picked up by parse_message already and allow attaching arbitray extra data to be sent to Sentry. This makes it so that attaching `user` as extra data is sent as a proper raven user, allowing Sentry to do smart things like count the number of affected users and searching for all issues related to this user. Sentry expects certain keys to work, from the docs: id: The unique ID of the user. email: The email address of the user. ip_address: The IP of the user. username: The username of the user. All other keys are stored as extra information but not specifically processed by Sentry. To make this easier, if you don't provide a proplist/eon object, it will default to using the `user` key as `id`. --- src/raven_error_logger.erl | 65 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 9a1cf62..2ed12bf 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -10,6 +10,7 @@ handle_info/2 ]). +-export([extract_user/1]). init(_) -> {ok, []}. @@ -257,25 +258,29 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, _Reason} = Except ]}; parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | Rest]) when is_list(Extras) -> + {User, ExtrasWithoutUser} = extract_user(Extras), {format(Format, [{failed, Reason} | Rest]), [ {level, Level}, {exception, {failed, Reason}}, {extra, [ {pid, Pid} | - [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] + [ {Key, Value} || {Key, Value} <- ExtrasWithoutUser, is_atom(Key) ] ]} + | User ]}; parse_message(Level, Pid, "Exception: ~p\n" "Extras: ~p" = Format, [{{Class, Reason}, [{_, _, _, _} | _] = Stacktrace}, Extras]) when Class =:= exit; Class =:= error; Class =:= throw -> + {User, ExtrasWithoutUser} = extract_user(Extras), {format(Format, [{Class, Reason}, Extras]), [ {level, Level}, {exception, {Class, Reason}}, {stacktrace, Stacktrace}, {extra, [ - {pid, Pid} | [ {Key, Value} || {Key, Value} <- Extras, is_atom(Key) ] + {pid, Pid} | [ {Key, Value} || {Key, Value} <- ExtrasWithoutUser, is_atom(Key) ] ]} + | User ]}; %% Cybertron parse_message(Level, Pid, "~p failed for 5 minutes: ~p" = Format, @@ -564,6 +569,7 @@ parse_message(Level, Pid, "** Exception: ~p~n" % Mask warnings for failed tasks in KKng parse_message(warning = _Level, _Pid, "failed task: ~w", [_Tid]) -> mask; + %% End of Kivra specific parse_message(Level, Pid, Format, Data) -> {format(Format, Data), [ @@ -811,3 +817,58 @@ format_term(Term) -> %% @private format(Format, Data) -> iolist_to_binary(s2_io:format(Format, Data)). + +%% Start of Kivra specific +%% @private +-type proplist() :: [{any(), any()}]. +-spec extract_user(proplist() | binary()) -> {proplist(), proplist()}. +extract_user(Extras) -> + {[MaybeContext], ExtrasWithoutUser} = proplists:split(Extras, [user]), + UserContext = extract_user_context(MaybeContext), + {UserContext, ExtrasWithoutUser}. + +extract_user_context([]) -> []; +extract_user_context([{user, Context}]) when is_list(Context) -> [{user, Context}]; +extract_user_context([{user, Id}]) -> [{user, [{id, Id}]}]; +extract_user_context(Other) -> Other. + +%%%_* Tests ============================================================ +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +extract_user_test_() -> + [ + fun() -> + Actual = extract_user(Extras), + ?assertEqual(Expected, Actual) + end + || + {Extras, Expected} <- [ + {[], {[], []}}, + { + [{data, <<"stuff">>}], + {[], [{data, <<"stuff">>}]} + }, + { + [{user, <<"key">>}], + {[{user, [{id, <<"key">>}]}], []} + }, + { + [{user, [{email, <<"jane@example.com">>}]}], + {[{user, [{email, <<"jane@example.com">>}]}], []} + }, + { + [ + {user, [{id, <<"key">>}]}, + {data, <<"stuff">>} + ], + { + [{user, [{id, <<"key">>}]}], + [{data, <<"stuff">>}] + } + } + ] + ]. + +-endif. +%% End of Kivra specific From 58fd5b778e32eee247aec76a200976016ecfa791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Z=C3=B6ger?= Date: Thu, 10 Dec 2020 17:16:43 +0100 Subject: [PATCH 55/90] feat: Support for structured warning messages to Sentry (#10) * feat: Support for structured warning messages to Sentry * feat: Adds possibility to override level in ?exception macro --- src/raven_error_logger.erl | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 2ed12bf..1830fe7 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -268,13 +268,26 @@ parse_message(Level, Pid, "Error: ~p" ++ _ = Format, [{failed, Reason, Extras} | ]} | User ]}; +parse_message(Level, Pid, "Warning: ~p~n" ++ Format, [{extras, Extras} | Data]) + when is_list(Extras) -> + {User, ExtrasWithoutUser} = extract_user(Extras), + {format(Format, Data), [ + {level, Level}, + {extra, [ + {pid, Pid} | + [ {Key, Value} || {Key, Value} <- ExtrasWithoutUser, is_atom(Key) ] + ]} + | User + ]}; parse_message(Level, Pid, "Exception: ~p\n" "Extras: ~p" = Format, [{{Class, Reason}, [{_, _, _, _} | _] = Stacktrace}, Extras]) when Class =:= exit; Class =:= error; Class =:= throw -> {User, ExtrasWithoutUser} = extract_user(Extras), + ExtrasLevel = proplists:get_value(level, Extras, false), + TheLevel = ExtrasLevel orelse Level, {format(Format, [{Class, Reason}, Extras]), [ - {level, Level}, + {level, TheLevel}, {exception, {Class, Reason}}, {stacktrace, Stacktrace}, {extra, [ From bd9ea54126c656230ce56530d3c6aabf36c07dc1 Mon Sep 17 00:00:00 2001 From: Moritz Ploss Date: Thu, 12 Aug 2021 13:48:39 +0200 Subject: [PATCH 56/90] fix: Bug in parse_message --- rebar.config | 4 ++-- src/raven_error_logger.erl | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/rebar.config b/rebar.config index e2d0b88..03a9b91 100644 --- a/rebar.config +++ b/rebar.config @@ -6,6 +6,6 @@ {platform_define, "^R14", no_callbacks} ]}. {deps, [ - {jsx, ".*", {git, "git@github.com:talentdeficit/jsx.git", {branch, master}}}, - {stdlib2, {git, "git@github.com:kivra/stdlib2.git", {branch, master}}} + {jsx, ".*", {git, "git@github.com:kivra/jsx.git", {tag, "2.9.0"}}}, + {stdlib2, {git, "git@github.com:kivra/stdlib2.git", {branch, master}}} ]}. diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index 1830fe7..ba36a3e 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -284,10 +284,8 @@ parse_message(Level, Pid, "Exception: ~p\n" [{{Class, Reason}, [{_, _, _, _} | _] = Stacktrace}, Extras]) when Class =:= exit; Class =:= error; Class =:= throw -> {User, ExtrasWithoutUser} = extract_user(Extras), - ExtrasLevel = proplists:get_value(level, Extras, false), - TheLevel = ExtrasLevel orelse Level, {format(Format, [{Class, Reason}, Extras]), [ - {level, TheLevel}, + {level, proplists:get_value(level, Extras, Level)}, {exception, {Class, Reason}}, {stacktrace, Stacktrace}, {extra, [ From 2b3aa627d6b6201b51107c8c0bf7006dce84735a Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Tue, 12 Oct 2021 15:57:48 +0200 Subject: [PATCH 57/90] Add basic logger handler that sends logs to sentry --- src/raven_app.erl | 5 ++++- src/raven_logger_backend.erl | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/raven_logger_backend.erl diff --git a/src/raven_app.erl b/src/raven_app.erl index 65cc056..996e6b6 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -24,7 +24,10 @@ start(_StartType, _StartArgs) -> case application:get_env(uri) of {ok, _} -> case application:get_env(error_logger) of - {ok, true} -> error_logger:add_report_handler(raven_error_logger); + {ok, true} -> error_logger:add_report_handler(raven_error_logger); + {ok, false} -> logger:add_handler(logger_backend, raven_logger_backend, #{level => error + , filter_default => log + , filters => [{f1, {fun logger_filters:domain/2, {stop, equal, [ssl]}}}]}); _ -> ok end, raven_sup:start_link(); diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl new file mode 100644 index 0000000..db06073 --- /dev/null +++ b/src/raven_logger_backend.erl @@ -0,0 +1,10 @@ +-module(raven_logger_backend). +-export([ + log/2 +]). + + +log(LogEvent, _Config) -> + timer:sleep(5000), + raven:capture(LogEvent, []). + From 4fe754f8900fc2b1ad2cb8e853db3550dc268d4b Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Wed, 13 Oct 2021 16:28:24 +0200 Subject: [PATCH 58/90] Drop logs from httpc to prevent a log loop --- src/raven_app.erl | 6 ++++-- src/raven_logger_backend.erl | 13 +++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/raven_app.erl b/src/raven_app.erl index 996e6b6..1fbaf85 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -25,9 +25,11 @@ start(_StartType, _StartArgs) -> {ok, _} -> case application:get_env(error_logger) of {ok, true} -> error_logger:add_report_handler(raven_error_logger); - {ok, false} -> logger:add_handler(logger_backend, raven_logger_backend, #{level => error + {ok, false} -> logger:add_handler(logger_backend, raven_logger_backend, #{level => warning , filter_default => log - , filters => [{f1, {fun logger_filters:domain/2, {stop, equal, [ssl]}}}]}); + , filters => [{ssl, {fun logger_filters:domain/2, {stop, sub, [ssl]}}} + ,{sasl, {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}} + ]}); _ -> ok end, raven_sup:start_link(); diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index db06073..62f5234 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -5,6 +5,15 @@ log(LogEvent, _Config) -> - timer:sleep(5000), - raven:capture(LogEvent, []). + case is_raven_log(LogEvent) of + true -> ok; % Dropping raven log, prevents log loop + false -> raven:capture(LogEvent, []) + end. + +is_raven_log(#{meta := Meta} = _LogEvent) -> + case maps:is_key(report_cb, Meta) of + false -> false; + true -> #{report_cb := Report} = Meta, + Report =:= fun ssl_logger:format/1 + end. From 3447f637d41447cf4483d0e324c8344ed75b5564 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Fri, 15 Oct 2021 16:32:16 +0200 Subject: [PATCH 59/90] Handle more types of log messages --- src/raven_logger_backend.erl | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 62f5234..8b14a57 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -7,7 +7,8 @@ log(LogEvent, _Config) -> case is_raven_log(LogEvent) of true -> ok; % Dropping raven log, prevents log loop - false -> raven:capture(LogEvent, []) + false -> + raven:capture(get_msg(LogEvent), parse_message(LogEvent)) end. is_raven_log(#{meta := Meta} = _LogEvent) -> @@ -17,3 +18,29 @@ is_raven_log(#{meta := Meta} = _LogEvent) -> Report =:= fun ssl_logger:format/1 end. +get_msg(#{msg := MsgList} = _LogEvent) -> + case MsgList of + {string, Msg} -> Msg; + {report, _Msg} -> "rapport"; + {_, _Msg} -> "not expected" + end. + +parse_message(LogEvent) -> + Meta = maps:get(meta, LogEvent), + Msg = get_msg(LogEvent), + Level = maps:get(level, LogEvent), + [ + {level, Level}, +% {exception, {Class, Reason}}, +% {stacktrace, Stacktrace}, + {extra, [ + {name, "Name"}, + {pid, maps:get(pid, Meta)}, + {last_event, "LastEvent"}, + {state_name, "StateName"}, + {state_data, "StateData"}, + {callback_mode, "CallbackMode"}, + {reason, LogEvent} + ]} + ]. + From be5773fd8231556a4975bead4855aac935919713 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Mon, 18 Oct 2021 17:25:23 +0200 Subject: [PATCH 60/90] Fix level mismatch with sentry and handle reports better --- src/raven_app.erl | 5 +++-- src/raven_logger_backend.erl | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/raven_app.erl b/src/raven_app.erl index 1fbaf85..3888fb8 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -27,8 +27,9 @@ start(_StartType, _StartArgs) -> {ok, true} -> error_logger:add_report_handler(raven_error_logger); {ok, false} -> logger:add_handler(logger_backend, raven_logger_backend, #{level => warning , filter_default => log - , filters => [{ssl, {fun logger_filters:domain/2, {stop, sub, [ssl]}}} - ,{sasl, {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}} + , filters => [{ssl, {fun logger_filters:domain/2, {stop, sub, [ssl]}}} + ,{progress, {fun logger_filters:domain/2, {stop, equal, [progress]}}} + ,{sasl, {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}} ]}); _ -> ok end, diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 8b14a57..b9fe6d6 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -1,6 +1,5 @@ -module(raven_logger_backend). --export([ - log/2 +-export([ log/2 ]). @@ -20,15 +19,22 @@ is_raven_log(#{meta := Meta} = _LogEvent) -> get_msg(#{msg := MsgList} = _LogEvent) -> case MsgList of - {string, Msg} -> Msg; - {report, _Msg} -> "rapport"; - {_, _Msg} -> "not expected" + {string, Msg} -> Msg; + {report, Msg} -> parse_report_msg(Msg); + {Format, _Args} when is_list(Format) -> + Format; + {_, _Args} -> "unexpected" end. +parse_report_msg(#{format := Format} = Report) when is_map(Report)-> + Format; +parse_report_msg(_) -> + "Not a map". + parse_message(LogEvent) -> Meta = maps:get(meta, LogEvent), Msg = get_msg(LogEvent), - Level = maps:get(level, LogEvent), + Level = sentry_level(maps:get(level, LogEvent)), [ {level, Level}, % {exception, {Class, Reason}}, @@ -44,3 +50,5 @@ parse_message(LogEvent) -> ]} ]. +sentry_level(notice) -> info; +sentry_level(Level) -> Level. From a5969168521dd4fb456c65ea1f3abdd92f36af08 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Tue, 19 Oct 2021 14:03:06 +0200 Subject: [PATCH 61/90] Add all meta values to the additional data part of the log --- src/raven_logger_backend.erl | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index b9fe6d6..a28ccc7 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -21,16 +21,19 @@ get_msg(#{msg := MsgList} = _LogEvent) -> case MsgList of {string, Msg} -> Msg; {report, Msg} -> parse_report_msg(Msg); - {Format, _Args} when is_list(Format) -> - Format; - {_, _Args} -> "unexpected" + {Format, Args} when is_list(Format) -> + make_readable(Format, Args); + {_, _} -> "unexpected log format" end. -parse_report_msg(#{format := Format} = Report) when is_map(Report)-> - Format; +parse_report_msg(#{format := Format, args := Args} = Report) when is_map(Report)-> + make_readable(Format, Args); parse_report_msg(_) -> "Not a map". +make_readable(Format, Args) -> + iolist_to_binary(io_lib:format(Format, Args)). + parse_message(LogEvent) -> Meta = maps:get(meta, LogEvent), Msg = get_msg(LogEvent), @@ -39,15 +42,10 @@ parse_message(LogEvent) -> {level, Level}, % {exception, {Class, Reason}}, % {stacktrace, Stacktrace}, - {extra, [ - {name, "Name"}, - {pid, maps:get(pid, Meta)}, - {last_event, "LastEvent"}, - {state_name, "StateName"}, - {state_data, "StateData"}, - {callback_mode, "CallbackMode"}, - {reason, LogEvent} - ]} + {extra, lists:append(maps:to_list(Meta), + [ {logEvent, LogEvent} + , {reason, Msg} + ])} ]. sentry_level(notice) -> info; From de97c91035909abbcd3f4437c7ccab0a8838f9e3 Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Tue, 19 Oct 2021 15:14:04 +0200 Subject: [PATCH 62/90] feat:add skeleton for save sending to sentry --- .gitignore | 3 +- src/raven_send_sentry_safe.erl | 97 ++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/raven_send_sentry_safe.erl diff --git a/.gitignore b/.gitignore index 170611a..c5c162d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ +*~ .* /deps/ /ebin/ /_build -rebar.lock \ No newline at end of file +rebar.lock diff --git a/src/raven_send_sentry_safe.erl b/src/raven_send_sentry_safe.erl new file mode 100644 index 0000000..7496a4a --- /dev/null +++ b/src/raven_send_sentry_safe.erl @@ -0,0 +1,97 @@ +-module(raven_send_sentry_safe). + +-behaviour(gen_event). + +-export([start/0, stop/0, notify/1, notify/2, request/1]). + +-export([init/1, terminate/2, handle_call/2, handle_event/2]). + +-define(MGR, send_safe_mgr). + +%% API + +start() -> + Mgr = start_mgr(), + start_handler(Mgr). + +stop() -> + gen_event:stop(?MGR). + +notify(Event) -> + gen_event:notify(?MGR, Event). + +notify(_Event, N) when N =< 0 -> + ok; +notify(Event, N) -> + gen_event:notify(?MGR, Event), + notify(Event, N-1). + +request(Request) -> + ID = gen_event:send_request(?MGR, ?MODULE, Request), + gen_event:receive_response(ID, 1000). + +%% gen_event callbacks + +init(Arg) -> + io:format("init(~p)~n", [Arg]), + {ok, #{backoff_until => current_time()}}. + +terminate(Arg, State) -> + io:format("terminate(~p,~p)~n", [Arg, State]), + ok. + +handle_call(Request, State) -> + io:format("handle_call(~p,~p)~n", [Request, State]), + {ok, {self(),whereis(?MGR)}, State}. + +handle_event(Event, State) -> + io:format("handle_event(~p,~p)~n", [Event, State]), + Qlen = qlen(), + if + Qlen > 10 -> + io:format(" skip, to long queue (~p)~n", [Qlen]), + {ok, State}; + true -> + #{backoff_until := Bou} = State, + Now = current_time(), + if + Bou > Now -> + io:format(" skip, to backoff~n", []), + {ok, State}; + true -> + {ok, BackoffUntil} = send_to_sentry(), + io:format(" sent to sentry~n", []), + {ok, State#{backoff_until => BackoffUntil}} + end + end. + +%% Local + +start_mgr() -> + case gen_event:start({local,?MGR}) of + {ok, Mgr} -> + Mgr; + {error, {already_started, Mgr}} -> + Mgr + end. + +start_handler(Mgr) -> + Handlers = gen_event:which_handlers(Mgr), + case lists:member(?MODULE, Handlers) of + true -> + already_started; + false -> + ok = gen_event:add_handler(Mgr, ?MODULE, foo) + end. + +qlen() -> + {message_queue_len, Qlen} = + erlang:process_info(whereis(?MGR), message_queue_len), + Qlen. + +send_to_sentry() -> + timer:sleep(1000), + {ok, current_time()}. + +current_time() -> + erlang:system_time(microsecond). From 1881b84eee88ef6250ba8e3bd3a97e38f38feef2 Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Wed, 20 Oct 2021 11:52:43 +0200 Subject: [PATCH 63/90] chore: change from gen_event to gen_server for sending sfe to sentry --- src/raven_send_sentry_safe.erl | 78 ++++++++++++++-------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/src/raven_send_sentry_safe.erl b/src/raven_send_sentry_safe.erl index 7496a4a..90212dc 100644 --- a/src/raven_send_sentry_safe.erl +++ b/src/raven_send_sentry_safe.erl @@ -1,36 +1,33 @@ -module(raven_send_sentry_safe). --behaviour(gen_event). +-behaviour(gen_server). --export([start/0, stop/0, notify/1, notify/2, request/1]). +-export([start/0, start_link/0, stop/0, notify/1, notify/2]). --export([init/1, terminate/2, handle_call/2, handle_event/2]). - --define(MGR, send_safe_mgr). +-export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2]). %% API start() -> - Mgr = start_mgr(), - start_handler(Mgr). + gen_server:start({local, ?MODULE}, ?MODULE, undefined, []). + +start_link() -> + gen_server:start_link({local, ?MODULE}, ?MODULE, undefined, []). stop() -> - gen_event:stop(?MGR). + gen_server:stop(?MODULE). notify(Event) -> - gen_event:notify(?MGR, Event). + gen_server:cast(?MODULE, {notify, Event}). +%% Test notify(_Event, N) when N =< 0 -> ok; notify(Event, N) -> - gen_event:notify(?MGR, Event), + notify({N, Event}), notify(Event, N-1). -request(Request) -> - ID = gen_event:send_request(?MGR, ?MODULE, Request), - gen_event:receive_response(ID, 1000). - -%% gen_event callbacks +%% gen_server callbacks init(Arg) -> io:format("init(~p)~n", [Arg]), @@ -40,56 +37,47 @@ terminate(Arg, State) -> io:format("terminate(~p,~p)~n", [Arg, State]), ok. -handle_call(Request, State) -> - io:format("handle_call(~p,~p)~n", [Request, State]), - {ok, {self(),whereis(?MGR)}, State}. +handle_call(Request, From, State) -> + io:format("handle_call(~p,~p,~p)~n", [Request, From, State]), + {reply, ok, State}. -handle_event(Event, State) -> - io:format("handle_event(~p,~p)~n", [Event, State]), +handle_cast(Request = {notify, Event}, State) -> + io:format("handle_cast(~p,~p)~n", [Request, State]), Qlen = qlen(), if Qlen > 10 -> io:format(" skip, to long queue (~p)~n", [Qlen]), - {ok, State}; + {noreply, State}; true -> #{backoff_until := Bou} = State, Now = current_time(), if Bou > Now -> io:format(" skip, to backoff~n", []), - {ok, State}; + {noreply, State}; true -> - {ok, BackoffUntil} = send_to_sentry(), - io:format(" sent to sentry~n", []), - {ok, State#{backoff_until => BackoffUntil}} + io:format(" sending~n", []), + {ok, BackoffUntil} = send_to_sentry(Event), + io:format(" sent~n", []), + {noreply, State#{backoff_until => BackoffUntil}} end - end. + end; +handle_cast(Request, State) -> + io:format("handle_cast(~p,~p)~n", [Request, State]), + {ok, State}. -%% Local +handle_info(Info, State) -> + io:format("handle_info(~p,~p)~n", [Info, State]), + {noreply, State}. -start_mgr() -> - case gen_event:start({local,?MGR}) of - {ok, Mgr} -> - Mgr; - {error, {already_started, Mgr}} -> - Mgr - end. - -start_handler(Mgr) -> - Handlers = gen_event:which_handlers(Mgr), - case lists:member(?MODULE, Handlers) of - true -> - already_started; - false -> - ok = gen_event:add_handler(Mgr, ?MODULE, foo) - end. +%% Local qlen() -> {message_queue_len, Qlen} = - erlang:process_info(whereis(?MGR), message_queue_len), + erlang:process_info(self(), message_queue_len), Qlen. -send_to_sentry() -> +send_to_sentry(_Event) -> timer:sleep(1000), {ok, current_time()}. From 910db0455d5fa688dbc3409177c67550e29b1a51 Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Wed, 20 Oct 2021 13:51:58 +0200 Subject: [PATCH 64/90] chore: starte sending safe from supervisor --- src/raven_sup.erl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/raven_sup.erl b/src/raven_sup.erl index ff4d878..993d62b 100644 --- a/src/raven_sup.erl +++ b/src/raven_sup.erl @@ -16,10 +16,9 @@ start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). - %% @hidden init([]) -> - {ok, { - {one_for_one, 5, 10}, [ - ] - }}. + Config = {one_for_one, 5, 10}, + SendSentrySafe = ?WORKER(raven_send_sentry_safe, start_link, [], permanent), + Workers = [SendSentrySafe], + {ok, {Config, Workers}}. From 0b3df53d31df26f627201e375b6516e35c260c8c Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Wed, 20 Oct 2021 16:44:33 +0200 Subject: [PATCH 65/90] chore: send via safe sentry --- src/raven_logger_backend.erl | 2 +- src/raven_send_sentry_safe.erl | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index a28ccc7..d94d1d2 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -7,7 +7,7 @@ log(LogEvent, _Config) -> case is_raven_log(LogEvent) of true -> ok; % Dropping raven log, prevents log loop false -> - raven:capture(get_msg(LogEvent), parse_message(LogEvent)) + raven_send_sentry_safe:capture(get_msg(LogEvent), parse_message(LogEvent)) end. is_raven_log(#{meta := Meta} = _LogEvent) -> diff --git a/src/raven_send_sentry_safe.erl b/src/raven_send_sentry_safe.erl index 90212dc..3af2a0a 100644 --- a/src/raven_send_sentry_safe.erl +++ b/src/raven_send_sentry_safe.erl @@ -2,7 +2,7 @@ -behaviour(gen_server). --export([start/0, start_link/0, stop/0, notify/1, notify/2]). +-export([start/0, start_link/0, stop/0, capture/2]). -export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2]). @@ -17,15 +17,9 @@ start_link() -> stop() -> gen_server:stop(?MODULE). -notify(Event) -> - gen_server:cast(?MODULE, {notify, Event}). +capture(Message, Args) -> + gen_server:cast(?MODULE, {capture, Message, Args}). -%% Test -notify(_Event, N) when N =< 0 -> - ok; -notify(Event, N) -> - notify({N, Event}), - notify(Event, N-1). %% gen_server callbacks @@ -41,7 +35,7 @@ handle_call(Request, From, State) -> io:format("handle_call(~p,~p,~p)~n", [Request, From, State]), {reply, ok, State}. -handle_cast(Request = {notify, Event}, State) -> +handle_cast(Request = {capture, Message, Args}, State) -> io:format("handle_cast(~p,~p)~n", [Request, State]), Qlen = qlen(), if @@ -57,7 +51,7 @@ handle_cast(Request = {notify, Event}, State) -> {noreply, State}; true -> io:format(" sending~n", []), - {ok, BackoffUntil} = send_to_sentry(Event), + {ok, BackoffUntil} = raven_capture(Message, Args), io:format(" sent~n", []), {noreply, State#{backoff_until => BackoffUntil}} end @@ -77,9 +71,13 @@ qlen() -> erlang:process_info(self(), message_queue_len), Qlen. -send_to_sentry(_Event) -> - timer:sleep(1000), - {ok, current_time()}. +raven_capture(Message, Args) -> + case raven:capture(Message, Args) of + ok -> + {ok, current_time()}; + {ok, Seconds} -> + {ok, current_time() + Seconds*1_000_000} + end. current_time() -> erlang:system_time(microsecond). From 6863cd2e3c2c3d624183b6a6c4499c132b14878e Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Mon, 25 Oct 2021 16:28:14 +0200 Subject: [PATCH 66/90] Respect backoff from Sentry, allow disk logging from Raven Correctly handle more log reports --- src/raven.erl | 26 +++++++++++++++++++++++--- src/raven_app.erl | 1 + src/raven_logger_backend.erl | 10 ++++++---- src/raven_send_sentry_safe.erl | 11 +++++++---- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/raven.erl b/src/raven.erl index 5ac197f..ed61885 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -1,6 +1,7 @@ -module(raven). -export([ capture/2, + captureBackoff/3, user_agent/0 ]). @@ -28,6 +29,8 @@ capture(Message, Params) when is_list(Message) -> capture(unicode:characters_to_binary(Message), Params); capture(Message, Params) -> + captureBackoff(Message, Params, false). +captureBackoff(Message, Params, Synchronized) -> Cfg = get_config(), Document = [ {event_id, event_id_i()}, @@ -83,12 +86,29 @@ capture(Message, Params) -> {"User-Agent", UA} ], ok = httpc:set_options([{ipfamily, Cfg#cfg.ipfamily}]), - httpc:request(post, + {ok, Result} = httpc:request(post, {Cfg#cfg.uri ++ "/api/store/", Headers, "application/octet-stream", Body}, [], - [{body_format, binary}, {sync, false}] + [{body_format, binary}, {sync, Synchronized}] ), - ok. + case Synchronized of + false -> ok; + true -> {ok, extract_backoff(Result)} + end. + +extract_backoff(Result) when is_reference(Result) -> + io:format("~nHTTP return was reference ~p~n", [Result]), + 0; +extract_backoff({StatusLine, Headers, _Body}) -> + {_,ResponseCode, _} = StatusLine, + case ResponseCode of + 429 -> + Backoff = list_to_integer(proplists:get_value("retry-after", Headers)), + io:format(" retry: ~p~n", [Backoff]), + Backoff; + _ -> + 0 + end. -spec user_agent() -> iolist(). user_agent() -> diff --git a/src/raven_app.erl b/src/raven_app.erl index 3888fb8..3c73d37 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -29,6 +29,7 @@ start(_StartType, _StartArgs) -> , filter_default => log , filters => [{ssl, {fun logger_filters:domain/2, {stop, sub, [ssl]}}} ,{progress, {fun logger_filters:domain/2, {stop, equal, [progress]}}} + ,{raven, {fun logger_filters:domain/2, {stop, sub, [raven]}}} ,{sasl, {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}} ]}); _ -> ok diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index d94d1d2..f617d9c 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -4,13 +4,13 @@ log(LogEvent, _Config) -> - case is_raven_log(LogEvent) of - true -> ok; % Dropping raven log, prevents log loop + case is_httpc_log(LogEvent) of + true -> ok; %Dropping httpc log, prevents log loop false -> raven_send_sentry_safe:capture(get_msg(LogEvent), parse_message(LogEvent)) end. -is_raven_log(#{meta := Meta} = _LogEvent) -> +is_httpc_log(#{meta := Meta} = _LogEvent) -> case maps:is_key(report_cb, Meta) of false -> false; true -> #{report_cb := Report} = Meta, @@ -28,8 +28,10 @@ get_msg(#{msg := MsgList} = _LogEvent) -> parse_report_msg(#{format := Format, args := Args} = Report) when is_map(Report)-> make_readable(Format, Args); +parse_report_msg(#{description := Description} = Report) when is_map(Report)-> + Description; parse_report_msg(_) -> - "Not a map". + "Not a expected format". make_readable(Format, Args) -> iolist_to_binary(io_lib:format(Format, Args)). diff --git a/src/raven_send_sentry_safe.erl b/src/raven_send_sentry_safe.erl index 3af2a0a..26640cf 100644 --- a/src/raven_send_sentry_safe.erl +++ b/src/raven_send_sentry_safe.erl @@ -25,6 +25,7 @@ capture(Message, Args) -> init(Arg) -> io:format("init(~p)~n", [Arg]), + logger:update_process_metadata(#{domain => [raven]}), {ok, #{backoff_until => current_time()}}. terminate(Arg, State) -> @@ -35,8 +36,7 @@ handle_call(Request, From, State) -> io:format("handle_call(~p,~p,~p)~n", [Request, From, State]), {reply, ok, State}. -handle_cast(Request = {capture, Message, Args}, State) -> - io:format("handle_cast(~p,~p)~n", [Request, State]), +handle_cast(_Request = {capture, Message, Args}, State) -> Qlen = qlen(), if Qlen > 10 -> @@ -47,7 +47,10 @@ handle_cast(Request = {capture, Message, Args}, State) -> Now = current_time(), if Bou > Now -> - io:format(" skip, to backoff~n", []), + logger:warning(<<"Sentry dropped log event">>), + io:format(" skip, until backoff~n", []), + io:format(" now: ~p~n", [calendar:system_time_to_universal_time(Now, microsecond)]), + io:format(" backoff: ~p~n", [calendar:system_time_to_universal_time(Bou, microsecond)]), {noreply, State}; true -> io:format(" sending~n", []), @@ -72,7 +75,7 @@ qlen() -> Qlen. raven_capture(Message, Args) -> - case raven:capture(Message, Args) of + case raven:captureBackoff(Message, Args, true) of ok -> {ok, current_time()}; {ok, Seconds} -> From 55915fc57aeee305795a63d389676607bd532e44 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Tue, 26 Oct 2021 14:31:02 +0200 Subject: [PATCH 67/90] Use a separate config variable to enable otp_logger --- src/raven_app.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/raven_app.erl b/src/raven_app.erl index 3c73d37..deb6618 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -25,7 +25,10 @@ start(_StartType, _StartArgs) -> {ok, _} -> case application:get_env(error_logger) of {ok, true} -> error_logger:add_report_handler(raven_error_logger); - {ok, false} -> logger:add_handler(logger_backend, raven_logger_backend, #{level => warning + _ -> ok + end, + case application:get_env(otp_logger) of + {ok, true} -> logger:add_handler(logger_backend, raven_logger_backend, #{level => warning , filter_default => log , filters => [{ssl, {fun logger_filters:domain/2, {stop, sub, [ssl]}}} ,{progress, {fun logger_filters:domain/2, {stop, equal, [progress]}}} From 7a97dac9c0b9d6dbf48d4d579fbe233e97c3a257 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Tue, 26 Oct 2021 14:35:51 +0200 Subject: [PATCH 68/90] Remove dev logging --- src/raven_send_sentry_safe.erl | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/raven_send_sentry_safe.erl b/src/raven_send_sentry_safe.erl index 26640cf..1019c07 100644 --- a/src/raven_send_sentry_safe.erl +++ b/src/raven_send_sentry_safe.erl @@ -23,17 +23,14 @@ capture(Message, Args) -> %% gen_server callbacks -init(Arg) -> - io:format("init(~p)~n", [Arg]), +init(_Arg) -> logger:update_process_metadata(#{domain => [raven]}), {ok, #{backoff_until => current_time()}}. -terminate(Arg, State) -> - io:format("terminate(~p,~p)~n", [Arg, State]), +terminate(_Arg, _State) -> ok. -handle_call(Request, From, State) -> - io:format("handle_call(~p,~p,~p)~n", [Request, From, State]), +handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast(_Request = {capture, Message, Args}, State) -> @@ -48,23 +45,16 @@ handle_cast(_Request = {capture, Message, Args}, State) -> if Bou > Now -> logger:warning(<<"Sentry dropped log event">>), - io:format(" skip, until backoff~n", []), - io:format(" now: ~p~n", [calendar:system_time_to_universal_time(Now, microsecond)]), - io:format(" backoff: ~p~n", [calendar:system_time_to_universal_time(Bou, microsecond)]), {noreply, State}; true -> - io:format(" sending~n", []), {ok, BackoffUntil} = raven_capture(Message, Args), - io:format(" sent~n", []), {noreply, State#{backoff_until => BackoffUntil}} end end; -handle_cast(Request, State) -> - io:format("handle_cast(~p,~p)~n", [Request, State]), +handle_cast(_Request, State) -> {ok, State}. -handle_info(Info, State) -> - io:format("handle_info(~p,~p)~n", [Info, State]), +handle_info(_Info, State) -> {noreply, State}. %% Local From c7e8201ae4799a35483cfd97312702d70dd36993 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Wed, 27 Oct 2021 12:44:28 +0200 Subject: [PATCH 69/90] feat: Handle stacktrace and exception from the meta map --- src/raven_logger_backend.erl | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index f617d9c..85f4cf7 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -37,17 +37,29 @@ make_readable(Format, Args) -> iolist_to_binary(io_lib:format(Format, Args)). parse_message(LogEvent) -> - Meta = maps:get(meta, LogEvent), - Msg = get_msg(LogEvent), - Level = sentry_level(maps:get(level, LogEvent)), + Meta = maps:get(meta, LogEvent), + Msg = get_msg(LogEvent), + Level = sentry_level(maps:get(level, LogEvent)), + Exception = maps:get(exception, Meta, []), + Stacktrace = maps:get(stacktrace, Meta, []), + lists:append(create_error_list(Exception, Stacktrace), [ {level, Level}, -% {exception, {Class, Reason}}, -% {stacktrace, Stacktrace}, {extra, lists:append(maps:to_list(Meta), [ {logEvent, LogEvent} , {reason, Msg} ])} + ]). + +create_error_list([], []) -> + []; +create_error_list(Exception, []) -> + [{exception, Exception}]; +create_error_list([], Stacktrace) -> + [{stacktrace, Stacktrace}]; +create_error_list(Exception, Stacktrace) -> + [ {exception, Exception} + , {stacktrace, Stacktrace} ]. sentry_level(notice) -> info; From 9bbd29d167a395c45d210e4600e177c8b148ce4c Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Wed, 27 Oct 2021 15:05:41 +0200 Subject: [PATCH 70/90] feat: Support all raven props from logged map --- src/raven_logger_backend.erl | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 85f4cf7..ceab49b 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -38,11 +38,10 @@ make_readable(Format, Args) -> parse_message(LogEvent) -> Meta = maps:get(meta, LogEvent), + ShortMeta = maps:without([gl,pid,time], Meta), Msg = get_msg(LogEvent), Level = sentry_level(maps:get(level, LogEvent)), - Exception = maps:get(exception, Meta, []), - Stacktrace = maps:get(stacktrace, Meta, []), - lists:append(create_error_list(Exception, Stacktrace), + lists:append(proplists:from_map(ShortMeta), [ {level, Level}, {extra, lists:append(maps:to_list(Meta), @@ -51,16 +50,5 @@ parse_message(LogEvent) -> ])} ]). -create_error_list([], []) -> - []; -create_error_list(Exception, []) -> - [{exception, Exception}]; -create_error_list([], Stacktrace) -> - [{stacktrace, Stacktrace}]; -create_error_list(Exception, Stacktrace) -> - [ {exception, Exception} - , {stacktrace, Stacktrace} - ]. - sentry_level(notice) -> info; sentry_level(Level) -> Level. From 3a6ca560e513a2fb6811b4e4ef55d13606015987 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Thu, 28 Oct 2021 11:18:10 +0200 Subject: [PATCH 71/90] Changed suggested during review --- src/raven.erl | 9 ++++++--- src/raven_logger_backend.erl | 32 ++++++++++++++------------------ src/raven_send_sentry_safe.erl | 2 +- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/raven.erl b/src/raven.erl index ed61885..03280d6 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -1,7 +1,7 @@ -module(raven). -export([ capture/2, - captureBackoff/3, + capture_with_backoff/3, user_agent/0 ]). @@ -29,8 +29,11 @@ capture(Message, Params) when is_list(Message) -> capture(unicode:characters_to_binary(Message), Params); capture(Message, Params) -> - captureBackoff(Message, Params, false). -captureBackoff(Message, Params, Synchronized) -> + capture_with_backoff(Message, Params, false). + +%Synchronized set to true returns backoff +%otherwise, it is not returned +capture_with_backoff(Message, Params, Synchronized) -> Cfg = get_config(), Document = [ {event_id, event_id_i()}, diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index ceab49b..bba66d9 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -5,9 +5,8 @@ log(LogEvent, _Config) -> case is_httpc_log(LogEvent) of - true -> ok; %Dropping httpc log, prevents log loop - false -> - raven_send_sentry_safe:capture(get_msg(LogEvent), parse_message(LogEvent)) + true -> ok; %Dropping httpc log, prevents log loop + false -> raven_send_sentry_safe:capture(get_msg(LogEvent), parse_message(LogEvent)) end. is_httpc_log(#{meta := Meta} = _LogEvent) -> @@ -19,19 +18,18 @@ is_httpc_log(#{meta := Meta} = _LogEvent) -> get_msg(#{msg := MsgList} = _LogEvent) -> case MsgList of - {string, Msg} -> Msg; - {report, Msg} -> parse_report_msg(Msg); - {Format, Args} when is_list(Format) -> - make_readable(Format, Args); - {_, _} -> "unexpected log format" + {string, Msg} -> Msg; + {report, Msg} -> parse_report_msg(Msg); + {Format, Args} when is_list(Format) -> make_readable(Format, Args); + {_, _} -> "unexpected log format" end. -parse_report_msg(#{format := Format, args := Args} = Report) when is_map(Report)-> +parse_report_msg(#{format := Format, args := Args} = _Report) -> make_readable(Format, Args); -parse_report_msg(#{description := Description} = Report) when is_map(Report)-> +parse_report_msg(#{description := Description} = _Report) -> Description; parse_report_msg(_) -> - "Not a expected format". + "Not an expected format". make_readable(Format, Args) -> iolist_to_binary(io_lib:format(Format, Args)). @@ -42,13 +40,11 @@ parse_message(LogEvent) -> Msg = get_msg(LogEvent), Level = sentry_level(maps:get(level, LogEvent)), lists:append(proplists:from_map(ShortMeta), - [ - {level, Level}, - {extra, lists:append(maps:to_list(Meta), - [ {logEvent, LogEvent} - , {reason, Msg} - ])} - ]). + [ {level, Level} + , {extra, lists:append(maps:to_list(Meta) + , [ {logEvent, LogEvent} + , {reason, Msg} + ])}]). sentry_level(notice) -> info; sentry_level(Level) -> Level. diff --git a/src/raven_send_sentry_safe.erl b/src/raven_send_sentry_safe.erl index 1019c07..f29b818 100644 --- a/src/raven_send_sentry_safe.erl +++ b/src/raven_send_sentry_safe.erl @@ -65,7 +65,7 @@ qlen() -> Qlen. raven_capture(Message, Args) -> - case raven:captureBackoff(Message, Args, true) of + case raven:capture_with_backoff(Message, Args, true) of ok -> {ok, current_time()}; {ok, Seconds} -> From 4f075ed7bb9f1b52c4b172c8fdd0372383ac0ad5 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Fri, 29 Oct 2021 11:36:04 +0200 Subject: [PATCH 72/90] feat: Handle legacy error_logger formating of log messages --- src/raven_app.erl | 2 +- src/raven_logger_backend.erl | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/raven_app.erl b/src/raven_app.erl index deb6618..b63bfd8 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -28,7 +28,7 @@ start(_StartType, _StartArgs) -> _ -> ok end, case application:get_env(otp_logger) of - {ok, true} -> logger:add_handler(logger_backend, raven_logger_backend, #{level => warning + {ok, true} -> logger:add_handler(raven_otp_logger, raven_logger_backend, #{level => warning , filter_default => log , filters => [{ssl, {fun logger_filters:domain/2, {stop, sub, [ssl]}}} ,{progress, {fun logger_filters:domain/2, {stop, equal, [progress]}}} diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index bba66d9..68ad524 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -16,12 +16,16 @@ is_httpc_log(#{meta := Meta} = _LogEvent) -> Report =:= fun ssl_logger:format/1 end. +get_msg(#{msg := MsgList, meta := #{error_logger := #{report_cb := Report_cb}}} = _LogEvent) when is_function(Report_cb)-> + {report, UnformatedMsg} = MsgList, + {Format, Args} = Report_cb(UnformatedMsg), + make_readable(Format, Args); get_msg(#{msg := MsgList} = _LogEvent) -> case MsgList of {string, Msg} -> Msg; {report, Msg} -> parse_report_msg(Msg); {Format, Args} when is_list(Format) -> make_readable(Format, Args); - {_, _} -> "unexpected log format" + {_, _} -> "Unexpected log format" end. parse_report_msg(#{format := Format, args := Args} = _Report) -> From ee1224ff0c1290cf4a1092f9e4131e878596b405 Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Fri, 29 Oct 2021 14:27:36 +0200 Subject: [PATCH 73/90] Handle reports that store the log message in reason and error keys --- src/raven_logger_backend.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 68ad524..433c250 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -2,6 +2,7 @@ -export([ log/2 ]). +-define(META_FILTER, [gl,pid,time,file,line,mfa,span_ctx]). log(LogEvent, _Config) -> case is_httpc_log(LogEvent) of @@ -17,7 +18,7 @@ is_httpc_log(#{meta := Meta} = _LogEvent) -> end. get_msg(#{msg := MsgList, meta := #{error_logger := #{report_cb := Report_cb}}} = _LogEvent) when is_function(Report_cb)-> - {report, UnformatedMsg} = MsgList, + {report, UnformatedMsg} = MsgList, {Format, Args} = Report_cb(UnformatedMsg), make_readable(Format, Args); get_msg(#{msg := MsgList} = _LogEvent) -> @@ -32,6 +33,10 @@ parse_report_msg(#{format := Format, args := Args} = _Report) -> make_readable(Format, Args); parse_report_msg(#{description := Description} = _Report) -> Description; +parse_report_msg(#{reason := Reason} = _Report) -> + Reason; +parse_report_msg(#{error := Error} = _Report) -> + Error; parse_report_msg(_) -> "Not an expected format". @@ -40,7 +45,7 @@ make_readable(Format, Args) -> parse_message(LogEvent) -> Meta = maps:get(meta, LogEvent), - ShortMeta = maps:without([gl,pid,time], Meta), + ShortMeta = maps:without(?META_FILTER, Meta), Msg = get_msg(LogEvent), Level = sentry_level(maps:get(level, LogEvent)), lists:append(proplists:from_map(ShortMeta), From b697fefab83386b23391b627c835cfe7e7f1d1dd Mon Sep 17 00:00:00 2001 From: Robert Svensen Date: Wed, 3 Nov 2021 15:33:06 +0100 Subject: [PATCH 74/90] Catch format exception in logs --- src/raven_logger_backend.erl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 433c250..29b2fa6 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -41,7 +41,11 @@ parse_report_msg(_) -> "Not an expected format". make_readable(Format, Args) -> - iolist_to_binary(io_lib:format(Format, Args)). + try + iolist_to_binary(io_lib:format(Format, Args)) + catch + Exception:Reason -> iolist_to_binary(io_lib:format("Error in log format string: ~p:~p", [Exception, Reason])) + end. parse_message(LogEvent) -> Meta = maps:get(meta, LogEvent), From 37b601a85afa0d392ef317b60fce008189f8bdeb Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Wed, 24 Nov 2021 14:26:56 +0100 Subject: [PATCH 75/90] chore: improve logging, applying report_cb to one more case --- src/raven_logger_backend.erl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 29b2fa6..82d6571 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -17,7 +17,11 @@ is_httpc_log(#{meta := Meta} = _LogEvent) -> Report =:= fun ssl_logger:format/1 end. -get_msg(#{msg := MsgList, meta := #{error_logger := #{report_cb := Report_cb}}} = _LogEvent) when is_function(Report_cb)-> +get_msg(#{msg := MsgList, meta := #{error_logger := #{report_cb := Report_cb}}} = _LogEvent) when is_function(Report_cb) -> + {report, UnformatedMsg} = MsgList, + {Format, Args} = Report_cb(UnformatedMsg), + make_readable(Format, Args); +get_msg(#{msg := MsgList, meta := #{report_cb := Report_cb}} = _LogEvent) when is_function(Report_cb) -> {report, UnformatedMsg} = MsgList, {Format, Args} = Report_cb(UnformatedMsg), make_readable(Format, Args); From 3dd78dd7667cce5ff28f62f1767efae87d40c4fa Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Mon, 29 Nov 2021 13:22:01 +0100 Subject: [PATCH 76/90] chore: more general reason in sentry --- src/raven_logger_backend.erl | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 82d6571..a13881a 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -17,32 +17,33 @@ is_httpc_log(#{meta := Meta} = _LogEvent) -> Report =:= fun ssl_logger:format/1 end. -get_msg(#{msg := MsgList, meta := #{error_logger := #{report_cb := Report_cb}}} = _LogEvent) when is_function(Report_cb) -> - {report, UnformatedMsg} = MsgList, - {Format, Args} = Report_cb(UnformatedMsg), - make_readable(Format, Args); -get_msg(#{msg := MsgList, meta := #{report_cb := Report_cb}} = _LogEvent) when is_function(Report_cb) -> - {report, UnformatedMsg} = MsgList, - {Format, Args} = Report_cb(UnformatedMsg), - make_readable(Format, Args); -get_msg(#{msg := MsgList} = _LogEvent) -> +get_msg(#{msg := MsgList, meta := Meta} = _LogEvent) -> case MsgList of {string, Msg} -> Msg; - {report, Msg} -> parse_report_msg(Msg); + {report, Report} -> get_msg_from_report(Report, Meta); {Format, Args} when is_list(Format) -> make_readable(Format, Args); - {_, _} -> "Unexpected log format" + _ -> "Not an expected log format" end. -parse_report_msg(#{format := Format, args := Args} = _Report) -> +%% Specific choice of msg +get_msg_from_report(#{format := Format, args := Args} = _Report, _Meta) -> make_readable(Format, Args); -parse_report_msg(#{description := Description} = _Report) -> +get_msg_from_report(#{description := Description} = _Report, _Meta) -> Description; -parse_report_msg(#{reason := Reason} = _Report) -> +get_msg_from_report(#{reason := Reason} = _Report, _Meta) -> Reason; -parse_report_msg(#{error := Error} = _Report) -> +get_msg_from_report(#{error := Error} = _Report, _Meta) -> Error; -parse_report_msg(_) -> - "Not an expected format". +%% If no specific choice, then use provided report_cb +get_msg_from_report(Report, #{error_logger := #{report_cb := Report_cb}} = _Meta) when is_function(Report_cb) -> + {Format, Args} = Report_cb(Report), + make_readable(Format, Args); +get_msg_from_report(Report, #{report_cb := Report_cb} = _Meta) when is_function(Report_cb) -> + {Format, Args} = Report_cb(Report), + make_readable(Format, Args); +%% If nothing provided, then give up +get_msg_from_report(_Report, _Meta) -> + "Not an expected report log format". make_readable(Format, Args) -> try From 72a8b851397b7c0f7ca5640f88fcffcb46c7e9c8 Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Mon, 29 Nov 2021 15:37:28 +0100 Subject: [PATCH 77/90] chore: Add report to sentry log --- src/raven_logger_backend.erl | 49 +++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index a13881a..640403a 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -7,7 +7,10 @@ log(LogEvent, _Config) -> case is_httpc_log(LogEvent) of true -> ok; %Dropping httpc log, prevents log loop - false -> raven_send_sentry_safe:capture(get_msg(LogEvent), parse_message(LogEvent)) + false -> + Message = get_msg(LogEvent), + Args = get_args(Message, LogEvent), + raven_send_sentry_safe:capture(Message, Args) end. is_httpc_log(#{meta := Meta} = _LogEvent) -> @@ -19,10 +22,10 @@ is_httpc_log(#{meta := Meta} = _LogEvent) -> get_msg(#{msg := MsgList, meta := Meta} = _LogEvent) -> case MsgList of - {string, Msg} -> Msg; - {report, Report} -> get_msg_from_report(Report, Meta); - {Format, Args} when is_list(Format) -> make_readable(Format, Args); - _ -> "Not an expected log format" + {string, Msg} -> Msg; + {report, Report} -> get_msg_from_report(Report, Meta); + {Format, _Args} when is_list(Format) -> Format; + _ -> "Not an expected log format" end. %% Specific choice of msg @@ -52,17 +55,33 @@ make_readable(Format, Args) -> Exception:Reason -> iolist_to_binary(io_lib:format("Error in log format string: ~p:~p", [Exception, Reason])) end. -parse_message(LogEvent) -> - Meta = maps:get(meta, LogEvent), - ShortMeta = maps:without(?META_FILTER, Meta), - Msg = get_msg(LogEvent), +get_args(Message, LogEvent) -> Level = sentry_level(maps:get(level, LogEvent)), - lists:append(proplists:from_map(ShortMeta), - [ {level, Level} - , {extra, lists:append(maps:to_list(Meta) - , [ {logEvent, LogEvent} - , {reason, Msg} - ])}]). + Meta = maps:get(meta, LogEvent), + MetaBasic = maps:without(?META_FILTER, Meta), + MetaExtra = maps:with(?META_FILTER, Meta), + Msg = maps:get(msg, LogEvent), + Reason = Message, + Basic = MetaBasic#{level => Level}, + Extra = get_extra(Reason, MetaExtra, Msg), + + BasicList = proplists:from_map(Basic), + ExtraList = proplists:from_map(Extra), + + BasicList ++ [{extra, ExtraList}]. sentry_level(notice) -> info; sentry_level(Level) -> Level. + +get_extra(Reason, ExtraMeta, {report, Report}) -> + Extra = maps:merge(ExtraMeta, Report), + Extra#{reason => Reason}; +get_extra(Reason, ExtraMeta, {string, _String}) -> + ExtraMeta#{reason => Reason}; +get_extra(Reason, ExtraMeta, {Format, Args}) when is_list(Format) -> + Msg = make_readable(Format, Args), + ExtraMeta#{ reason => Reason + , msg => Msg}; +get_extra(Reason, ExtraMeta, Msg) -> + ExtraMeta#{ reason => Reason + , msg => Msg}. From 13fc7f406e42e41929359c67c024da6fcacf2877 Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Tue, 30 Nov 2021 14:47:22 +0100 Subject: [PATCH 78/90] eunit: Add report to sentry log --- Makefile | 2 +- rebar.config | 26 +++++--- src/raven_logger_backend.erl | 126 +++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index e058979..57d4789 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ PROJECT = raven DIALYZER = dialyzer -REBAR = rebar +REBAR = rebar3 all: app diff --git a/rebar.config b/rebar.config index 03a9b91..573e06a 100644 --- a/rebar.config +++ b/rebar.config @@ -1,11 +1,19 @@ %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ts=4 sw=4 noet syntax=erlang -{erl_opts, [ - warnings_as_errors, - warn_export_all, - {platform_define, "^R14", no_callbacks} -]}. -{deps, [ - {jsx, ".*", {git, "git@github.com:kivra/jsx.git", {tag, "2.9.0"}}}, - {stdlib2, {git, "git@github.com:kivra/stdlib2.git", {branch, master}}} -]}. +{erl_opts, [ warnings_as_errors, + warn_export_all, + {platform_define, "^R14", no_callbacks} + ] +}. + +{deps, [ {jsx, ".*", {git, "git@github.com:kivra/jsx.git", {tag, "2.9.0"}}}, + {stdlib2, {git, "git@github.com:kivra/stdlib2.git", {branch, master}}} + ] +}. + +{profiles, [ {test, [ {deps, [ {meck, {git, "git@github.com:kivra/meck.git", {tag, "0.8.13"}}}]}, + {extra_src_dirs, [{"test", [{recursive, true}]}]} + ] + } + ] +}. diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 640403a..b71d6f8 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -85,3 +85,129 @@ get_extra(Reason, ExtraMeta, {Format, Args}) when is_list(Format) -> get_extra(Reason, ExtraMeta, Msg) -> ExtraMeta#{ reason => Reason , msg => Msg}. + +%%%_* Tests ============================================================ +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +logger_backend_test_() -> + { setup, + fun test_setup/0, + fun test_teardown/1, + [ fun test_log_unknown/0, + fun test_log_string/0, + fun test_log_format/0, + fun test_log_report/0, + fun test_log_unknown_report/0 + ] + }. + +test_setup() -> + meck:new(raven_send_sentry_safe), + meck:new(httpc), + meck:expect(raven_send_sentry_safe, capture, 2, fun mock_capture/2), + meck:expect(httpc, set_options, 1, fun(_) -> ok end), + meck:expect(httpc, request, 4, fun mock_request/4), + application:start(raven), %% To se key vsn + application:set_env(raven, ipfamily, dummy), + application:set_env(raven, uri, "http://foo"), + application:set_env(raven, public_key, <<"hello">>), + application:set_env(raven, private_key, <<"there">>), + application:set_env(raven, project, "terraform mars"). + +test_teardown(_) -> + meck:unload([raven_send_sentry_safe]), + meck:unload([httpc]), + application:unset_env(raven, ipfamily), + application:unset_env(raven, uri), + application:unset_env(raven, public_key), + application:unset_env(raven, private_key), + application:unset_env(raven, project), + application:stop(raven). + +test_log_unknown() -> + Msg = "whatisthis", + Message = "Not an expected log format", + Args =[{correlation_id,"123456789"}, + {level,info}, + {extra,[{line, 214}, + {msg, "whatisthis"}, + {reason,"Not an expected log format"}]}], + run(Msg, Message, Args). + +test_log_string() -> + Msg = {string, "foo"}, + Message = "foo", + Args =[{correlation_id,"123456789"}, + {level,info}, + {extra,[{line, 214}, + {reason,"foo"}]}], + run(Msg, Message, Args). + +test_log_format() -> + Msg = {"Foo ~p", [14]}, + Message = "Foo ~p", + Args = [{correlation_id,"123456789"}, + {level,info}, + {extra,[{line, 214}, + {msg,<<"Foo 14">>}, + {reason,"Foo ~p"}]}], + run(Msg, Message, Args). + +test_log_report() -> + Msg = {report, #{description => "gunnar", + a => "foo", + b => "bar"}}, + Message = "gunnar", + Args = [{correlation_id,"123456789"}, + {level,info}, + {extra,[{a,"foo"}, + {b,"bar"}, + {description,"gunnar"}, + {line, 214}, + {reason,"gunnar"}]}], + run(Msg, Message, Args). + +test_log_unknown_report() -> + Msg = {report, #{a => "foo", + b => "bar"}}, + Message = "Not an expected report log format", + Args = [{correlation_id,"123456789"}, + {level,info}, + {extra,[{a,"foo"}, + {b,"bar"}, + {line, 214}, + {reason,"Not an expected report log format"}]}], + run(Msg, Message, Args). + +run(Msg, ExpectedMessage, ExpectedArgs) -> + meck:reset([raven_send_sentry_safe, httpc]), + Event = event(Msg), + log(Event, []), + [{_Pid, MFA, _}] = meck:history(raven_send_sentry_safe), + {raven_send_sentry_safe, capture, [Message, Args]} = MFA, + ?assertEqual(ExpectedMessage, Message), + ?assertEqual(sort_args(ExpectedArgs), sort_args(Args)). + +event(Msg) -> + Level = info, + Meta = meta(), + #{level => Level, meta => Meta, msg => Msg}. + +meta() -> + #{correlation_id => "123456789", + line => 214}. + +sort_args(Args) -> + SortedExtras = lists:sort(proplists:get_value(extra, Args)), + lists:sort([{extra, SortedExtras} | proplists:delete(extra, Args)]). + +mock_capture(Message, Args) -> + raven:capture(Message, Args). + +mock_request(_Op, {_Path, _Headers, _Type, Body}, _, _) -> + Decoded = jsx:decode(zlib:uncompress(base64:decode(Body))), + io:format(user, "~n~p~n", [Decoded]), + {ok, {{foo,200,bar},[],<<"body">>}}. + +-endif. From 4f0488d6750b98e4fce7dcdb9e4e562a0916ed5a Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Wed, 1 Dec 2021 11:13:28 +0100 Subject: [PATCH 79/90] chore: Add the tag correlation_id to sentry report --- src/raven_logger_backend.erl | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index b71d6f8..8e025cf 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -68,7 +68,13 @@ get_args(Message, LogEvent) -> BasicList = proplists:from_map(Basic), ExtraList = proplists:from_map(Extra), - BasicList ++ [{extra, ExtraList}]. + case maps:get(correlation_id, Meta, undefined) of + undefined -> + BasicList ++ [{extra, ExtraList}]; + CorrelationID -> + BasicList ++ [{extra, ExtraList}, + {tags, [{correlation_id, CorrelationID}]}] + end. sentry_level(notice) -> info; sentry_level(Level) -> Level. @@ -128,20 +134,22 @@ test_teardown(_) -> test_log_unknown() -> Msg = "whatisthis", Message = "Not an expected log format", - Args =[{correlation_id,"123456789"}, - {level,info}, - {extra,[{line, 214}, - {msg, "whatisthis"}, - {reason,"Not an expected log format"}]}], + Args = [{correlation_id,"123456789"}, + {level,info}, + {tags, [{correlation_id, "123456789"}]}, + {extra,[{line, 214}, + {msg, "whatisthis"}, + {reason,"Not an expected log format"}]}], run(Msg, Message, Args). test_log_string() -> Msg = {string, "foo"}, Message = "foo", - Args =[{correlation_id,"123456789"}, - {level,info}, - {extra,[{line, 214}, - {reason,"foo"}]}], + Args = [{correlation_id,"123456789"}, + {level,info}, + {tags, [{correlation_id, "123456789"}]}, + {extra,[{line, 214}, + {reason,"foo"}]}], run(Msg, Message, Args). test_log_format() -> @@ -149,6 +157,7 @@ test_log_format() -> Message = "Foo ~p", Args = [{correlation_id,"123456789"}, {level,info}, + {tags, [{correlation_id, "123456789"}]}, {extra,[{line, 214}, {msg,<<"Foo 14">>}, {reason,"Foo ~p"}]}], @@ -161,6 +170,7 @@ test_log_report() -> Message = "gunnar", Args = [{correlation_id,"123456789"}, {level,info}, + {tags, [{correlation_id, "123456789"}]}, {extra,[{a,"foo"}, {b,"bar"}, {description,"gunnar"}, @@ -174,6 +184,7 @@ test_log_unknown_report() -> Message = "Not an expected report log format", Args = [{correlation_id,"123456789"}, {level,info}, + {tags, [{correlation_id, "123456789"}]}, {extra,[{a,"foo"}, {b,"bar"}, {line, 214}, From 675ac9d314edd1a3d21da4de766c7d71f9dc7dec Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Wed, 1 Dec 2021 11:42:47 +0100 Subject: [PATCH 80/90] eunit: one more test case --- src/raven_logger_backend.erl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 8e025cf..f9c66c4 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -104,6 +104,7 @@ logger_backend_test_() -> fun test_log_string/0, fun test_log_format/0, fun test_log_report/0, + fun test_log_report_with_compound_description/0, fun test_log_unknown_report/0 ] }. @@ -178,6 +179,21 @@ test_log_report() -> {reason,"gunnar"}]}], run(Msg, Message, Args). +test_log_report_with_compound_description() -> + Msg = {report, #{description => {namn, "gunnar"}, + a => "foo", + b => "bar"}}, + Message = {namn, "gunnar"}, + Args = [{correlation_id,"123456789"}, + {level,info}, + {tags, [{correlation_id, "123456789"}]}, + {extra,[{a,"foo"}, + {b,"bar"}, + {description,{namn, "gunnar"}}, + {line, 214}, + {reason,{namn, "gunnar"}}]}], + run(Msg, Message, Args). + test_log_unknown_report() -> Msg = {report, #{a => "foo", b => "bar"}}, From 2b522adb8e9160ad65d659727d5c1f7d68f2d3ed Mon Sep 17 00:00:00 2001 From: Roland Karlsson Date: Wed, 1 Dec 2021 12:30:56 +0100 Subject: [PATCH 81/90] chore: better logging of unexpected log format --- src/raven_logger_backend.erl | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index f9c66c4..94ec3cd 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -25,7 +25,7 @@ get_msg(#{msg := MsgList, meta := Meta} = _LogEvent) -> {string, Msg} -> Msg; {report, Report} -> get_msg_from_report(Report, Meta); {Format, _Args} when is_list(Format) -> Format; - _ -> "Not an expected log format" + _ -> unexpected_log_format(Meta) end. %% Specific choice of msg @@ -45,8 +45,13 @@ get_msg_from_report(Report, #{report_cb := Report_cb} = _Meta) when is_function( {Format, Args} = Report_cb(Report), make_readable(Format, Args); %% If nothing provided, then give up -get_msg_from_report(_Report, _Meta) -> - "Not an expected report log format". +get_msg_from_report(_Report, Meta) -> + unexpected_log_format(Meta). + +unexpected_log_format(Meta) -> + Module = maps:get(module, Meta), + "Unexpected log format in module: " ++ atom_to_list(Module). + make_readable(Format, Args) -> try @@ -134,13 +139,14 @@ test_teardown(_) -> test_log_unknown() -> Msg = "whatisthis", - Message = "Not an expected log format", + Message = "Unexpected log format in module: ievan_polka", Args = [{correlation_id,"123456789"}, {level,info}, + {module, ievan_polka}, {tags, [{correlation_id, "123456789"}]}, {extra,[{line, 214}, {msg, "whatisthis"}, - {reason,"Not an expected log format"}]}], + {reason,"Unexpected log format in module: ievan_polka"}]}], run(Msg, Message, Args). test_log_string() -> @@ -148,6 +154,7 @@ test_log_string() -> Message = "foo", Args = [{correlation_id,"123456789"}, {level,info}, + {module, ievan_polka}, {tags, [{correlation_id, "123456789"}]}, {extra,[{line, 214}, {reason,"foo"}]}], @@ -158,6 +165,7 @@ test_log_format() -> Message = "Foo ~p", Args = [{correlation_id,"123456789"}, {level,info}, + {module, ievan_polka}, {tags, [{correlation_id, "123456789"}]}, {extra,[{line, 214}, {msg,<<"Foo 14">>}, @@ -171,6 +179,7 @@ test_log_report() -> Message = "gunnar", Args = [{correlation_id,"123456789"}, {level,info}, + {module, ievan_polka}, {tags, [{correlation_id, "123456789"}]}, {extra,[{a,"foo"}, {b,"bar"}, @@ -186,6 +195,7 @@ test_log_report_with_compound_description() -> Message = {namn, "gunnar"}, Args = [{correlation_id,"123456789"}, {level,info}, + {module, ievan_polka}, {tags, [{correlation_id, "123456789"}]}, {extra,[{a,"foo"}, {b,"bar"}, @@ -197,14 +207,15 @@ test_log_report_with_compound_description() -> test_log_unknown_report() -> Msg = {report, #{a => "foo", b => "bar"}}, - Message = "Not an expected report log format", + Message = "Unexpected log format in module: ievan_polka", Args = [{correlation_id,"123456789"}, {level,info}, + {module, ievan_polka}, {tags, [{correlation_id, "123456789"}]}, {extra,[{a,"foo"}, {b,"bar"}, {line, 214}, - {reason,"Not an expected report log format"}]}], + {reason,"Unexpected log format in module: ievan_polka"}]}], run(Msg, Message, Args). run(Msg, ExpectedMessage, ExpectedArgs) -> @@ -223,6 +234,7 @@ event(Msg) -> meta() -> #{correlation_id => "123456789", + module => ievan_polka, line => 214}. sort_args(Args) -> From 30582331a9f55f28aca841084e5ed16b1d13583e Mon Sep 17 00:00:00 2001 From: Christian Sunesson <52162652+chsukivra@users.noreply.github.com> Date: Mon, 24 Jan 2022 09:15:41 +0100 Subject: [PATCH 82/90] chore: proplists:from_map is not available in otp 23 (#18) some components in kivra not upgraded yet (beehive) dialyzer identified issues, so removed dead code and fixed an improper list --- src/raven_error_logger.erl | 20 +------------------- src/raven_logger_backend.erl | 4 ++-- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index ba36a3e..a6a520b 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -494,7 +494,7 @@ parse_message(Level, Pid, "** Exception: ~p~n" ] = Data) -> ExceptionValue = case Args of - [Arg1|_] when is_atom(Arg1) -> {M, F, [Arg1|'_']}; + [Arg1|_] when is_atom(Arg1) -> {M, F, [Arg1, '...']}; _ -> {M, F, length(Args)} end, {format(Format, Data), [ @@ -642,24 +642,6 @@ parse_report(Level, Pid, supervisor_report, [{errorContext, Context}, {offender, {shutdown, proplists:get_value(shutdown, Offender)} ]} ]}; -parse_report(info, Pid, progress, [{started, Started}, {supervisor, Supervisor}]) -> - Message = case proplists:get_value(name, Started, []) of - [] -> format("Supervisor ~s started child", [format_name(Supervisor)]); - Name -> format("Supervisor ~s started ~s", [format_name(Supervisor), format_name(Name)]) - end, - {Message, [ - {level, info}, - {logger, supervisors}, - {extra, [ - {supervisor, Supervisor}, - {pid, Pid}, - {child_pid, proplists:get_value(pid, Started)}, - {mfa, format_mfa(proplists:get_value(mfargs, Started))}, - {restart_type, proplists:get_value(restart_type, Started)}, - {child_type, proplists:get_value(child_type, Started)}, - {shutdown, proplists:get_value(shutdown, Started)} - ]} - ]}; parse_report(Level, Pid, Type, Report) -> Message = case proplists:get_value(message, Report, []) of [] -> <<"Report from process">>; diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 94ec3cd..bf96505 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -70,8 +70,8 @@ get_args(Message, LogEvent) -> Basic = MetaBasic#{level => Level}, Extra = get_extra(Reason, MetaExtra, Msg), - BasicList = proplists:from_map(Basic), - ExtraList = proplists:from_map(Extra), + BasicList = maps:to_list(Basic), + ExtraList = maps:to_list(Extra), case maps:get(correlation_id, Meta, undefined) of undefined -> From 56dd24d3b2bf75dadab2ebcebfaa8424fab6e678 Mon Sep 17 00:00:00 2001 From: Roland Karlsson <57994439+rolkar-kivra@users.noreply.github.com> Date: Mon, 24 Jan 2022 17:26:21 +0100 Subject: [PATCH 83/90] feat: Catch crashing otp logger plugin (#16) * Catch crashing otp logger plugin * Split raven:capture to prepare and send * Clean up debug printouts * Improvements due to review --- src/raven.erl | 18 ++++++++++++------ src/raven_app.erl | 16 ++++++++++++---- src/raven_logger_backend.erl | 34 ++++++++++++++++++++++++++++++++-- src/raven_send_sentry_safe.erl | 3 ++- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/raven.erl b/src/raven.erl index 03280d6..cb5189e 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -1,7 +1,8 @@ -module(raven). -export([ capture/2, - capture_with_backoff/3, + capture_prepare/2, + capture_with_backoff_send/2, user_agent/0 ]). @@ -29,11 +30,10 @@ capture(Message, Params) when is_list(Message) -> capture(unicode:characters_to_binary(Message), Params); capture(Message, Params) -> - capture_with_backoff(Message, Params, false). + {ok, Body} = capture_prepare(Message, Params), + capture_with_backoff_send(Body, false). -%Synchronized set to true returns backoff -%otherwise, it is not returned -capture_with_backoff(Message, Params, Synchronized) -> +capture_prepare(Message, Params) -> Cfg = get_config(), Document = [ {event_id, event_id_i()}, @@ -77,8 +77,14 @@ capture_with_backoff(Message, Params, Synchronized) -> {Key, term_to_json_i(Value)} end, Params) ], - Timestamp = integer_to_list(unix_timestamp_i()), Body = base64:encode(zlib:compress(jsx:encode(Document))), + {ok, Body}. + +%Synchronized set to true returns backoff +%otherwise, it is not returned +capture_with_backoff_send(Body, Synchronized) -> + Cfg = get_config(), + Timestamp = integer_to_list(unix_timestamp_i()), UA = user_agent(), Headers = [ {"X-Sentry-Auth", diff --git a/src/raven_app.erl b/src/raven_app.erl index b63bfd8..539f364 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -24,20 +24,28 @@ start(_StartType, _StartArgs) -> case application:get_env(uri) of {ok, _} -> case application:get_env(error_logger) of - {ok, true} -> error_logger:add_report_handler(raven_error_logger); + {ok, true} -> + error_logger:add_report_handler(raven_error_logger); _ -> ok end, case application:get_env(otp_logger) of - {ok, true} -> logger:add_handler(raven_otp_logger, raven_logger_backend, #{level => warning + {ok, true} -> + logger:add_handler(raven_otp_logger, raven_logger_backend, #{level => warning , filter_default => log , filters => [{ssl, {fun logger_filters:domain/2, {stop, sub, [ssl]}}} ,{progress, {fun logger_filters:domain/2, {stop, equal, [progress]}}} ,{raven, {fun logger_filters:domain/2, {stop, sub, [raven]}}} ,{sasl, {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}} ]}); - _ -> ok + _ -> + ok end, - raven_sup:start_link(); + case raven_sup:start_link() of + {ok, Pid} -> + {ok, Pid}; + Error -> + Error + end; _ -> {error, missing_configuration} end. diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index bf96505..4a3d042 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -2,17 +2,47 @@ -export([ log/2 ]). +-include_lib("kernel/include/logger.hrl"). -define(META_FILTER, [gl,pid,time,file,line,mfa,span_ctx]). +%% API + log(LogEvent, _Config) -> - case is_httpc_log(LogEvent) of - true -> ok; %Dropping httpc log, prevents log loop + try log(LogEvent) + catch _:Reason:StackTrace -> + LE = list_to_binary(lists:flatten(io_lib:format("~0p", [LogEvent]))), + ST = list_to_binary(lists:flatten(io_lib:format("~0p", [StackTrace]))), + ?LOG_WARNING(#{ message => <<"Raven logger backend crashed">>, + crash_message => LE, + reason => Reason, + stacktrace => ST}) + end. + +%% Private + +log(LogEvent) -> + case is_loop(LogEvent) of + true -> ok; %% Dropping prevents log loop false -> Message = get_msg(LogEvent), Args = get_args(Message, LogEvent), raven_send_sentry_safe:capture(Message, Args) end. +is_loop(LogEvent) -> + is_log_crash_log(LogEvent) or is_httpc_log(LogEvent). + +is_log_crash_log(#{msg := Msg} = _LogEvent) -> + case Msg of + {report, #{ message := <<"Raven logger backend crashed">>, + crash_message := _, + reason := _, + stacktrace := _}} -> + true; + _ -> + false + end. + is_httpc_log(#{meta := Meta} = _LogEvent) -> case maps:is_key(report_cb, Meta) of false -> false; diff --git a/src/raven_send_sentry_safe.erl b/src/raven_send_sentry_safe.erl index f29b818..715dd4d 100644 --- a/src/raven_send_sentry_safe.erl +++ b/src/raven_send_sentry_safe.erl @@ -65,7 +65,8 @@ qlen() -> Qlen. raven_capture(Message, Args) -> - case raven:capture_with_backoff(Message, Args, true) of + {ok, Body} = raven:capture_prepare(Message, Args), + case raven:capture_with_backoff_send(Body, true) of ok -> {ok, current_time()}; {ok, Seconds} -> From 6ee694adfe921c31024a6d12e733f5ff0bde601d Mon Sep 17 00:00:00 2001 From: Christian Sunesson <52162652+chsukivra@users.noreply.github.com> Date: Thu, 3 Feb 2022 14:54:31 +0100 Subject: [PATCH 84/90] feat: add possibility to configure ssl options (#19) it falls back to {ssl, []} if there is nothing in application:get_env(ssl) --- src/raven.erl | 10 ++++++++-- src/raven.hrl | 7 +++++++ src/raven_app.erl | 14 +++++++++++++- src/raven_logger_backend.erl | 11 ++++++++--- 4 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 src/raven.hrl diff --git a/src/raven.erl b/src/raven.erl index cb5189e..bbe1477 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -6,6 +6,8 @@ user_agent/0 ]). +-include("raven.hrl"). + -define(SENTRY_VERSION, "2.0"). -record(cfg, { @@ -97,8 +99,9 @@ capture_with_backoff_send(Body, Synchronized) -> ok = httpc:set_options([{ipfamily, Cfg#cfg.ipfamily}]), {ok, Result} = httpc:request(post, {Cfg#cfg.uri ++ "/api/store/", Headers, "application/octet-stream", Body}, - [], - [{body_format, binary}, {sync, Synchronized}] + [ssl_options()], + [{body_format, binary}, {sync, Synchronized}], + ?RAVEN_HTTPC_PROFILE ), case Synchronized of false -> ok; @@ -124,6 +127,9 @@ user_agent() -> {ok, Vsn} = application:get_key(raven, vsn), ["raven-erlang/", Vsn]. +ssl_options() -> + persistent_term:get(?RAVEN_SSL_PERSIST_KEY). + %% @private -spec get_config() -> cfg_rec(). get_config() -> diff --git a/src/raven.hrl b/src/raven.hrl new file mode 100644 index 0000000..6c352a6 --- /dev/null +++ b/src/raven.hrl @@ -0,0 +1,7 @@ + +%% The httpc profile used by raven +-define(RAVEN_HTTPC_PROFILE, raven). + +%% Key of persistent term for httpc ssl options +-define(RAVEN_SSL_PERSIST_KEY, {raven, ssl}). + diff --git a/src/raven_app.erl b/src/raven_app.erl index 539f364..089ef6c 100644 --- a/src/raven_app.erl +++ b/src/raven_app.erl @@ -10,6 +10,8 @@ stop/1 ]). +-include("raven.hrl"). + -spec start() -> ok | {error, term()}. start() -> ensure_started(raven). @@ -21,6 +23,14 @@ stop() -> %% @hidden start(_StartType, _StartArgs) -> + case application:get_env(ssl) of + {ok, Options} -> + persistent_term:put(?RAVEN_SSL_PERSIST_KEY, {ssl, Options}); + _ -> + logger:notice("Raven not configured with httpc ssl options"), + persistent_term:put(?RAVEN_SSL_PERSIST_KEY, {ssl, []}) + end, + {ok, _ProfilePid} = inets:start(httpc, [{profile, ?RAVEN_HTTPC_PROFILE}]), case application:get_env(uri) of {ok, _} -> case application:get_env(error_logger) of @@ -58,7 +68,9 @@ stop(_State) -> ok; _ -> ok - end. + end, + inets:stop(httpc, ?RAVEN_HTTPC_PROFILE), + ok. %% @private ensure_started(App) -> diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 4a3d042..4387f01 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -3,6 +3,8 @@ ]). -include_lib("kernel/include/logger.hrl"). +-include("raven.hrl"). + -define(META_FILTER, [gl,pid,time,file,line,mfa,span_ctx]). %% API @@ -145,11 +147,12 @@ logger_backend_test_() -> }. test_setup() -> + persistent_term:put(?RAVEN_SSL_PERSIST_KEY, {ssl, []}), meck:new(raven_send_sentry_safe), meck:new(httpc), meck:expect(raven_send_sentry_safe, capture, 2, fun mock_capture/2), meck:expect(httpc, set_options, 1, fun(_) -> ok end), - meck:expect(httpc, request, 4, fun mock_request/4), + meck:expect(httpc, request, 5, fun mock_request/5), application:start(raven), %% To se key vsn application:set_env(raven, ipfamily, dummy), application:set_env(raven, uri, "http://foo"), @@ -165,7 +168,9 @@ test_teardown(_) -> application:unset_env(raven, public_key), application:unset_env(raven, private_key), application:unset_env(raven, project), - application:stop(raven). + application:stop(raven), + persistent_term:erase(?RAVEN_SSL_PERSIST_KEY), + ok. test_log_unknown() -> Msg = "whatisthis", @@ -274,7 +279,7 @@ sort_args(Args) -> mock_capture(Message, Args) -> raven:capture(Message, Args). -mock_request(_Op, {_Path, _Headers, _Type, Body}, _, _) -> +mock_request(_Op, {_Path, _Headers, _Type, Body}, _, _, ?RAVEN_HTTPC_PROFILE) -> Decoded = jsx:decode(zlib:uncompress(base64:decode(Body))), io:format(user, "~n~p~n", [Decoded]), {ok, {{foo,200,bar},[],<<"body">>}}. From 8f61531a88e66d274d52b849257692d0b59e54b4 Mon Sep 17 00:00:00 2001 From: Moritz Ploss Date: Mon, 28 Feb 2022 15:07:01 +0100 Subject: [PATCH 85/90] fix: Don't send extra data as attributes --- src/raven_logger_backend.erl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 4387f01..4fe9010 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -5,7 +5,11 @@ -include_lib("kernel/include/logger.hrl"). -include("raven.hrl"). --define(META_FILTER, [gl,pid,time,file,line,mfa,span_ctx]). +%% see here: https://develop.sentry.dev/sdk/event-payloads/ +-define(ATTRIBUTE_FILTER, [ event_id, timestamp, platform, level, logger, + transaction, server_name, release, dist, tags, + environment, modules, extra, fingerprint, errors, + user, http_request, stacktrace, exception]). %% API @@ -95,8 +99,8 @@ make_readable(Format, Args) -> get_args(Message, LogEvent) -> Level = sentry_level(maps:get(level, LogEvent)), Meta = maps:get(meta, LogEvent), - MetaBasic = maps:without(?META_FILTER, Meta), - MetaExtra = maps:with(?META_FILTER, Meta), + MetaBasic = maps:with(?ATTRIBUTE_FILTER, Meta), + MetaExtra = maps:without(?ATTRIBUTE_FILTER, Meta), Msg = maps:get(msg, LogEvent), Reason = Message, Basic = MetaBasic#{level => Level}, From 285ff1406fad9a73379b898b4a0ae3ea83b83012 Mon Sep 17 00:00:00 2001 From: Silvio Sepulveda <88663987+ssepml@users.noreply.github.com> Date: Tue, 19 Apr 2022 13:11:48 +0200 Subject: [PATCH 86/90] Use 'reason' field when provided (defaults to message) (#21) --- src/raven_logger_backend.erl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index 4fe9010..ee7d75f 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -102,7 +102,7 @@ get_args(Message, LogEvent) -> MetaBasic = maps:with(?ATTRIBUTE_FILTER, Meta), MetaExtra = maps:without(?ATTRIBUTE_FILTER, Meta), Msg = maps:get(msg, LogEvent), - Reason = Message, + Reason = get_reason_maybe(LogEvent, Message), Basic = MetaBasic#{level => Level}, Extra = get_extra(Reason, MetaExtra, Msg), @@ -120,6 +120,11 @@ get_args(Message, LogEvent) -> sentry_level(notice) -> info; sentry_level(Level) -> Level. +get_reason_maybe(#{msg := {report, #{reason := Reason}}} = _LogEvent, _Default) -> + Reason; +get_reason_maybe(_LogEvent, Default) -> + Default. + get_extra(Reason, ExtraMeta, {report, Report}) -> Extra = maps:merge(ExtraMeta, Report), Extra#{reason => Reason}; From dccf360a778eff8e98506eea4704878aa6625a13 Mon Sep 17 00:00:00 2001 From: Silvio Sepulveda <88663987+ssepml@users.noreply.github.com> Date: Fri, 22 Apr 2022 11:23:00 +0200 Subject: [PATCH 87/90] Also get message from 'message' field (#22) --- src/raven_logger_backend.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/raven_logger_backend.erl b/src/raven_logger_backend.erl index ee7d75f..5ea05cc 100644 --- a/src/raven_logger_backend.erl +++ b/src/raven_logger_backend.erl @@ -69,6 +69,8 @@ get_msg_from_report(#{format := Format, args := Args} = _Report, _Meta) -> make_readable(Format, Args); get_msg_from_report(#{description := Description} = _Report, _Meta) -> Description; +get_msg_from_report(#{message := Message} = _Report, _Meta) -> + Message; get_msg_from_report(#{reason := Reason} = _Report, _Meta) -> Reason; get_msg_from_report(#{error := Error} = _Report, _Meta) -> From 6d8659b8cb1b58f75c783f2d49453ba80e39614a Mon Sep 17 00:00:00 2001 From: Thomas Hutchinson Date: Tue, 29 Aug 2023 11:21:26 +0200 Subject: [PATCH 88/90] Removed stdlib2 --- rebar.config | 4 +--- src/raven.erl | 2 +- src/raven_error_logger.erl | 2 +- src/raven_io.erl | 28 ++++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 src/raven_io.erl diff --git a/rebar.config b/rebar.config index 573e06a..990da36 100644 --- a/rebar.config +++ b/rebar.config @@ -6,9 +6,7 @@ ] }. -{deps, [ {jsx, ".*", {git, "git@github.com:kivra/jsx.git", {tag, "2.9.0"}}}, - {stdlib2, {git, "git@github.com:kivra/stdlib2.git", {branch, master}}} - ] +{deps, [ {jsx, ".*", {git, "git@github.com:kivra/jsx.git", {tag, "2.9.0"}}} ] }. {profiles, [ {test, [ {deps, [ {meck, {git, "git@github.com:kivra/meck.git", {tag, "0.8.13"}}}]}, diff --git a/src/raven.erl b/src/raven.erl index bbe1477..399c1b4 100644 --- a/src/raven.erl +++ b/src/raven.erl @@ -208,4 +208,4 @@ frame_to_json_i({Module, Function, Arguments, Location}) -> term_to_json_i(Term) when is_binary(Term); is_atom(Term) -> Term; term_to_json_i(Term) -> - iolist_to_binary(s2_io:format("~120p", [Term])). + iolist_to_binary(raven_io:format("~120p", [Term])). \ No newline at end of file diff --git a/src/raven_error_logger.erl b/src/raven_error_logger.erl index a6a520b..03f8467 100644 --- a/src/raven_error_logger.erl +++ b/src/raven_error_logger.erl @@ -809,7 +809,7 @@ format_term(Term) -> %% @private format(Format, Data) -> - iolist_to_binary(s2_io:format(Format, Data)). + iolist_to_binary(raven_io:format(Format, Data)). %% Start of Kivra specific %% @private diff --git a/src/raven_io.erl b/src/raven_io.erl new file mode 100644 index 0000000..8cf9acf --- /dev/null +++ b/src/raven_io.erl @@ -0,0 +1,28 @@ +-module(raven_io). + +-export([format/2]). + +-spec format(io:format(), [term()]) -> io_lib:chars(). +format(Format, Args) -> + Chars = + try lists:flatten( + io_lib:build_text( + lists:map( fun(Elem) -> update(Elem, 50, 50) end + , io_lib:scan_format(Format, Args)))) + catch + _:_ -> + lists:flatten( + io_lib:format("FORMAT ERROR: ~p ~p", [Format, Args])) + end, + + MaxLenth = 8192, + if + length(Chars) =< MaxLenth -> Chars; + true -> lists:sublist(Chars, MaxLenth - 3) ++ "..." + end. + +update(M = #{control_char := $p, args := [Arg]}, PDepth, _) -> + M#{control_char := $P, args := [Arg, PDepth]}; +update(M = #{control_char := $w, args := [Arg]}, _, WDepth) -> + M#{control_char := $W, args := [Arg, WDepth]}; +update(X, _, _) -> X. \ No newline at end of file From dc48a2c683e2d06a2f740f7fcf28ccb6f6872cc8 Mon Sep 17 00:00:00 2001 From: Thomas Hutchinson Date: Tue, 29 Aug 2023 13:25:06 +0200 Subject: [PATCH 89/90] Removed stdlib2 --- src/raven_io.erl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/raven_io.erl b/src/raven_io.erl index 8cf9acf..7814445 100644 --- a/src/raven_io.erl +++ b/src/raven_io.erl @@ -2,7 +2,6 @@ -export([format/2]). --spec format(io:format(), [term()]) -> io_lib:chars(). format(Format, Args) -> Chars = try lists:flatten( @@ -25,4 +24,17 @@ update(M = #{control_char := $p, args := [Arg]}, PDepth, _) -> M#{control_char := $P, args := [Arg, PDepth]}; update(M = #{control_char := $w, args := [Arg]}, _, WDepth) -> M#{control_char := $W, args := [Arg, WDepth]}; -update(X, _, _) -> X. \ No newline at end of file +update(X, _, _) -> X. + + +-ifdef(TEST). + +-include_lib("eunit/include/eunit.hrl"). + +format_test() -> + %% Format error + ?assertEqual( "FORMAT ERROR: \"Data: ~p\" wat" + , format("Data: ~p", wat)), + + ok. +-endif. \ No newline at end of file From c58e4c88292e44ecad09fb64c2b1e82d03881302 Mon Sep 17 00:00:00 2001 From: Thomas Hutchinson Date: Tue, 29 Aug 2023 14:35:08 +0200 Subject: [PATCH 90/90] Removed stdlib2 --- src/raven.app.src | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/raven.app.src b/src/raven.app.src index c9d1912..98e8c0f 100644 --- a/src/raven.app.src +++ b/src/raven.app.src @@ -8,8 +8,7 @@ crypto, public_key, ssl, - inets, - stdlib2 + inets ]}, {mod, {raven_app, []}}, {env, [