From 32ea9286944210fd78d8764be12243eb0ce96c0c Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 3 Feb 2014 13:32:31 -0500 Subject: [PATCH 1/2] Don't use the proplists module when decoding error_logger messages Proplist module is a lot slower than lists:keyfind, which is a BIF, because proplists has to work with 'bare' atoms as well as 2-tuples. This should marginally improve the throughput when printing many error_logger messages. --- src/error_logger_lager_h.erl | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/error_logger_lager_h.erl b/src/error_logger_lager_h.erl index 1c7e092..3874f31 100644 --- a/src/error_logger_lager_h.erl +++ b/src/error_logger_lager_h.erl @@ -235,8 +235,8 @@ log_event(Event, State) -> ?LOGFMT(info, P, "Application ~w started on node ~w", [App, Node]); [{started, Started}, {supervisor, Name}] -> - MFA = format_mfa(proplists:get_value(mfargs, Started)), - Pid = proplists:get_value(pid, Started), + MFA = format_mfa(get_value(mfargs, Started)), + Pid = get_value(pid, Started), ?LOGFMT(debug, P, "Supervisor ~w started ~s at pid ~w", [supervisor_name(Name), MFA, Pid]); _ -> @@ -248,13 +248,13 @@ log_event(Event, State) -> {ok, State}. format_crash_report(Report, Neighbours) -> - Name = case proplists:get_value(registered_name, Report, []) of + Name = case get_value(registered_name, Report, []) of [] -> %% process_info(Pid, registered_name) returns [] for unregistered processes - proplists:get_value(pid, Report); + get_value(pid, Report); Atom -> Atom end, - {Class, Reason, Trace} = proplists:get_value(error_info, Report), + {Class, Reason, Trace} = get_value(error_info, Report), ReasonStr = format_reason({Reason, Trace}), Type = case Class of exit -> "exited"; @@ -264,17 +264,17 @@ format_crash_report(Report, Neighbours) -> [Name, length(Neighbours), Type, ReasonStr]). format_offender(Off) -> - case proplists:get_value(mfargs, Off) of + case get_value(mfargs, Off) of undefined -> %% supervisor_bridge io_lib:format("at module ~w at ~w", - [proplists:get_value(mod, Off), proplists:get_value(pid, Off)]); + [get_value(mod, Off), get_value(pid, Off)]); MFArgs -> %% regular supervisor MFA = format_mfa(MFArgs), - Name = proplists:get_value(name, Off), + Name = get_value(name, Off), io_lib:format("~p started with ~s at ~w", - [Name, MFA, proplists:get_value(pid, Off)]) + [Name, MFA, get_value(pid, Off)]) end. format_reason({'function not exported', [{M, F, A},MFA|_]}) -> @@ -361,7 +361,7 @@ format_mfa({M, F, A}) when is_list(A) -> format_mfa({M, F, A}) when is_integer(A) -> io_lib:format("~w:~w/~w", [M, F, A]); format_mfa({M, F, A, Props}) when is_list(Props) -> - case proplists:get_value(line, Props) of + case get_value(line, Props) of undefined -> format_mfa({M, F, A}); Line -> @@ -405,6 +405,16 @@ print_val(Val) -> {Str, _} = lager_trunc_io:print(Val, 500), Str. + +get_value(Key, Value) -> + get_value(Key, Value, undefined). + +get_value(Key, List, Default) -> + case lists:keyfind(Key, 1, List) of + false -> Default; + {Key, Value} -> Value + end. + supervisor_name({local, Name}) -> Name; supervisor_name(Name) -> Name. -ifdef(TEST). From b6bfaca5f3629b657ae944b6b5483e7bd6842947 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 7 Feb 2014 15:30:01 -0500 Subject: [PATCH 2/2] Add comment and fix EQC generator --- src/error_logger_lager_h.erl | 2 ++ test/trunc_io_eqc.erl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/error_logger_lager_h.erl b/src/error_logger_lager_h.erl index 3874f31..4a64528 100644 --- a/src/error_logger_lager_h.erl +++ b/src/error_logger_lager_h.erl @@ -406,6 +406,8 @@ print_val(Val) -> Str. +%% @doc Faster than proplists, but with the same API as long as you don't need to +%% handle bare atom keys get_value(Key, Value) -> get_value(Key, Value, undefined). diff --git a/test/trunc_io_eqc.erl b/test/trunc_io_eqc.erl index 532f047..9eee35e 100644 --- a/test/trunc_io_eqc.erl +++ b/test/trunc_io_eqc.erl @@ -137,7 +137,7 @@ gen_pid() -> gen_port() -> ?LAZY(begin Port = erlang:open_port({spawn, "true"}, []), - erlang:port_close(Port), + catch(erlang:port_close(Port)), Port end).