From b3b94092d7079eda68ffd04cf5cefb3cd1fbabfd Mon Sep 17 00:00:00 2001 From: Anthony Molinaro Date: Fri, 9 Oct 2015 16:38:46 -0700 Subject: [PATCH] add contexts to performance (and missing file) --- ChangeLog | 4 +++ include/mondemand.hrl | 8 ++++- mondemand_dev.config | 6 ++-- src/mondemand.app.src | 2 +- src/mondemand.erl | 41 +++++++++++++++------- src/mondemand_config.erl | 22 ++++++++++-- src/mondemand_internal.hrl | 1 + src/mondemand_perfmsg.erl | 71 ++++++++++++++++++++++++++++---------- src/mondemand_statsmsg.erl | 6 +--- src/mondemand_util.erl | 30 +++++++++------- 10 files changed, 135 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2167111..16071fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Version 5.4.1 (molinaro) + * missing file in 5.4.0 release, as well as some additions to the +performance tracing event. Added contexts and a caller_label + Version 5.4.0 (molinaro) * support performance messages as well as allowing sending of different events to different channels. diff --git a/include/mondemand.hrl b/include/mondemand.hrl index 6f8d3f2..ab92c3c 100644 --- a/include/mondemand.hrl +++ b/include/mondemand.hrl @@ -13,7 +13,13 @@ -define (MD_PERF_EVENT, <<"MonDemand::PerfMsg">>). % internal record for MonDemand::PerfMsg --record (md_perf_msg, { id, timings = [] }). +-record (md_perf_msg, { id, + caller_label, + num_context = 0, + context = [], + num_timings = 0, + timings = [] + }). -record (md_perf_timing, { label, start_time, end_time }). % related to stats messages diff --git a/mondemand_dev.config b/mondemand_dev.config index 0154ce0..c23782a 100644 --- a/mondemand_dev.config +++ b/mondemand_dev.config @@ -1,8 +1,8 @@ [ { mondemand, [ -% { lwes_channel, { 1, [ { "127.0.0.1", 20602 } ] } } %, -% { lwes_channel, { 2, [{"127.0.0.1",20602}, {"172.16.107.128", 20602}] } }, - { config_file, "mondemand.conf" } + { lwes_channel, { 1, [ { "127.0.0.1", 20602 } ] } } %, +% { lwes_channel, { 2, [{"127.0.0.1",20602}, {"172.16.107.128", 20602}] } } %, +% { config_file, "mondemand.conf" } % { send_interval, 5 } ] } diff --git a/src/mondemand.app.src b/src/mondemand.app.src index f3db9b3..ba89042 100644 --- a/src/mondemand.app.src +++ b/src/mondemand.app.src @@ -1,7 +1,7 @@ { application, mondemand, [ { description, "Erlang Mondemand Bindings." }, - { vsn, "5.4.0" }, + { vsn, "5.4.1" }, { modules, [] }, { registered, [mondemand,mondemand_sup]}, { applications, [kernel,stdlib,lwes]}, diff --git a/src/mondemand.erl b/src/mondemand.erl index 9de5f83..22ba7e3 100644 --- a/src/mondemand.erl +++ b/src/mondemand.erl @@ -53,8 +53,11 @@ send_trace/3, send_trace/5, - send_perf_info/2, % (Id, Timings) - send_perf_info/4, % (Id, Label, StartTime, StopTime) + % performance tracing functions + send_perf_info/3, % (Id, CallerLabel, Timings) + send_perf_info/4, % (Id, CallerLabel, Timings, Context) + send_perf_info/5, % (Id, CallerLabel, Label, StartTime, StopTime) + send_perf_info/6, % (Id, CallerLabel, Label, StartTime, StopTime, Context) % other functions send_stats/3, @@ -214,18 +217,30 @@ send_trace (ProgId, Owner, TraceId, Message, Context) -> }) end. -send_perf_info (Id, Label, StartTime, EndTime) -> - Event = mondemand_perfmsg:to_lwes ( - mondemand_perfmsg:new (Id, Label, StartTime, EndTime) - ), - send_event (Event). -send_perf_info (Id, Timings) -> - Event = - mondemand_perfmsg:to_lwes ( - mondemand_perfmsg:new (Id, Timings) - ), - send_event (Event). +send_perf_info (Id, CallerLabel, Timings, Context) + when is_list (Timings), is_list (Context) -> + Event = + mondemand_perfmsg:to_lwes ( + mondemand_perfmsg:new (Id, CallerLabel, Timings, Context) + ), + send_event (Event). + +send_perf_info (Id, CallerLabel, Timings) + when is_list (Timings) -> + send_perf_info (Id, CallerLabel, Timings, []). + +send_perf_info (Id, CallerLabel, Label, StartTime, StopTime, Context) + when is_list (Context) -> + Event = + mondemand_perfmsg:to_lwes ( + mondemand_perfmsg:new (Id, CallerLabel, Label, + StartTime, StopTime, Context) + ), + send_event (Event). + +send_perf_info (Id, CallerLabel, Label, StartTime, StopTime) -> + send_perf_info (Id, CallerLabel, Label, StartTime, StopTime, []). send_stats (ProgId, Context, Stats) -> Event = diff --git a/src/mondemand_config.erl b/src/mondemand_config.erl index d5706e4..2d7b98a 100644 --- a/src/mondemand_config.erl +++ b/src/mondemand_config.erl @@ -45,8 +45,18 @@ lwes_config () -> % they are checked in that order case application:get_env (mondemand, lwes_channel) of {ok, {H,P}} when is_list (H), is_integer (P) -> - {1, [{H,P}]}; % allow old config style to continue to work - {ok, Config} -> Config; % new style is to just pass anything through + % allow old config style to continue to work + [ {T, {1,[{H,P}]}} || T <- [ stats, perf,log, trace ] ]; + {ok, {N, L}} when is_integer (N), is_list (L) -> + % allow old config style to continue to work + [ {T, {N, L} } || T <- [ stats, perf,log, trace ] ]; + {ok, Config} when is_list (Config) -> + case valid_config (Config) of + false -> + {error, invalid_config}; % new style is to just pass anything through + true -> + Config + end; undefined -> case application:get_env (mondemand, config_file) of {ok, File} -> @@ -56,6 +66,14 @@ lwes_config () -> end end. +valid_config (Config) when is_list (Config) -> + lists:foldl (fun (T, A) -> + lists:keymember (T, 1, Config) andalso A + end, + true, + [stats, perf, log, trace]). + + parse_config (File) -> case read_file (File) of {error, E} -> {error, E}; diff --git a/src/mondemand_internal.hrl b/src/mondemand_internal.hrl index 6893ebe..a4e0f74 100644 --- a/src/mondemand_internal.hrl +++ b/src/mondemand_internal.hrl @@ -21,6 +21,7 @@ % tokens in MonDemand::PerfMsg -define (MD_PERF_ID, <<"id">>). +-define (MD_PERF_CALLER_LABEL, <<"caller_label">>). -define (MD_PERF_LABEL, <<"label">>). -define (MD_PERF_START, <<"start">>). -define (MD_PERF_END, <<"end">>). diff --git a/src/mondemand_perfmsg.erl b/src/mondemand_perfmsg.erl index 46638b4..1f6397f 100644 --- a/src/mondemand_perfmsg.erl +++ b/src/mondemand_perfmsg.erl @@ -3,18 +3,37 @@ -include ("mondemand_internal.hrl"). -include_lib ("lwes/include/lwes.hrl"). --export ([ new/2, % (Id, [{Label, Start, End}]) - new/4, % (Id, Label, Start, End) +-export ([ new/3, % (Id, CallerLabel, [{Label, Start, End}]) + new/4, % (Id, CallerLabel, [{Label, Start, End}], [{Key, Value}]) + new/5, % (Id, CallerLabel, Label, Start, End) + new/6, % (Id, CallerLabel, Label, Start, End, [{Key, Value}]) new_timing/3, % (Label, Start, End) to_lwes/1, from_lwes/1 ]). -new (Id, Timings) -> - ValidatedTimings = [ new_timing (L, S, E) || { L, S, E } <- Timings ], - #md_perf_msg { id = Id, timings = ValidatedTimings }. -new (Id, Label, Start, End) -> - #md_perf_msg { id = Id, timings = [ new_timing (Label, Start, End) ] }. +new (Id, CallerLabel, Timings) -> + new (Id, CallerLabel, Timings, []). + +new (Id, CallerLabel, Timings, Context) -> + ValidatedTimings = + lists:map (fun (T = #md_perf_timing {}) -> T; + ({L, S, E}) -> new_timing (L, S, E) + end, + Timings), + ValidatedContext = mondemand_util:binaryify_context (Context), + #md_perf_msg { id = Id, + caller_label = CallerLabel, + num_timings = length (ValidatedTimings), + timings = ValidatedTimings, + num_context = length (ValidatedContext), + context = ValidatedContext + }. + +new (Id, CallerLabel, Label, Start, End) -> + new (Id, CallerLabel, [new_timing (Label, Start, End)], []). +new (Id, CallerLabel, Label, Start, End, Context) -> + new (Id, CallerLabel, [new_timing (Label, Start, End)], Context). new_timing (Label, Start, End) -> #md_perf_timing { label = Label, @@ -28,11 +47,7 @@ validate_time (Timestamp) when is_integer (Timestamp) -> Timestamp. timings_from_lwes (Data) -> - Num = - case dict:find (?MD_NUM, Data) of - error -> 0; - {ok, C} -> C - end, + Num = mondemand_util:find_in_dict (?MD_NUM, Data, 0), { Num, lists:foreach (fun(N) -> timing_from_lwes (N, Data) @@ -45,10 +60,11 @@ timing_from_lwes (TimingIndex, Data) -> E = dict:fetch (perf_end_key (TimingIndex), Data), #md_perf_timing { label = L, start_time = S, end_time = E }. -timings_to_lwes (Timings) -> - lists:zipwith (fun timing_to_lwes/2, - lists:seq (1, length(Timings)), - Timings). +timings_to_lwes (NumTimings, Timings) -> + [ { ?LWES_U_INT_16, ?MD_NUM, NumTimings } + | lists:zipwith (fun timing_to_lwes/2, + lists:seq (1, NumTimings), + Timings)]. timing_to_lwes (TimingIndex, #md_perf_timing { label = L, start_time = S, end_time = E }) -> @@ -59,16 +75,33 @@ timing_to_lwes (TimingIndex, to_lwes (L) when is_list (L) -> lists:map (fun to_lwes/1, L); to_lwes (#md_perf_msg { id = Id, - timings = Timings }) -> + caller_label = CallerLabel, + num_timings = NumTimings, + timings = Timings, + num_context = NumContexts, + context = Context + }) -> #lwes_event { name = ?MD_PERF_EVENT, attrs = lists:flatten ([ { ?LWES_STRING, ?MD_PERF_ID, Id }, - timings_to_lwes (Timings) ]) + { ?LWES_STRING, ?MD_PERF_CALLER_LABEL, CallerLabel}, + timings_to_lwes (NumTimings, Timings), + mondemand_util:context_to_lwes (undefined, + NumContexts, + Context) + ]) }. from_lwes (#lwes_event { attrs = Data}) -> + {NumTimings, Timings} = timings_from_lwes (Data), + {_, NumContexts, Context} = mondemand_util:context_from_lwes (Data), #md_perf_msg { id = dict:fetch (?MD_PERF_ID, Data), - timings = timings_from_lwes (Data) }. + caller_label = dict:fetch (?MD_PERF_CALLER_LABEL, Data), + num_context = NumContexts, + context = Context, + num_timings = NumTimings, + timings = Timings + }. perf_label_key (N) -> ?ELEMENT_OF_TUPLE_LIST (N, ?MD_PERF_LABEL). diff --git a/src/mondemand_statsmsg.erl b/src/mondemand_statsmsg.erl index 1c5e2d9..d8321c7 100644 --- a/src/mondemand_statsmsg.erl +++ b/src/mondemand_statsmsg.erl @@ -160,11 +160,7 @@ from_lwes (#lwes_event { attrs = Data}) -> }. metrics_from_lwes (Data) -> - Num = - case dict:find (?MD_NUM, Data) of - error -> 0; - {ok, C} -> C - end, + Num = mondemand_util:find_in_dict (?MD_NUM, Data, 0), { Num, lists:map ( fun (N) -> diff --git a/src/mondemand_util.erl b/src/mondemand_util.erl index 3915e63..ae139a4 100644 --- a/src/mondemand_util.erl +++ b/src/mondemand_util.erl @@ -54,11 +54,7 @@ context_from_context (DefaultHost, Context) -> context_from_lwes (Data) -> - Num = - case dict:find (?MD_CTXT_NUM, Data) of - error -> 0; - {ok, C} -> C - end, + Num = mondemand_util:find_in_dict (?MD_NUM, Data, 0), { Host, Context } = lists:foldl ( fun (N, {H, A}) -> K = dict:fetch (context_name_key (N), Data), @@ -82,13 +78,23 @@ context_value_key (N) -> context_to_lwes (Host, NumContexts, Context) -> case lists:keymember (?MD_HOST, 1, Context) of false -> - [ - { ?LWES_U_INT_16, ?MD_CTXT_NUM, NumContexts + 1}, - lists:zipwith (fun context_to_lwes/2, - lists:seq (1, NumContexts), - Context), - context_to_lwes (NumContexts+1, { ?MD_HOST, Host }) - ]; + case Host of + undefined -> + [ + { ?LWES_U_INT_16, ?MD_CTXT_NUM, NumContexts}, + lists:zipwith (fun context_to_lwes/2, + lists:seq (1, NumContexts), + Context) + ]; + _ -> + [ + { ?LWES_U_INT_16, ?MD_CTXT_NUM, NumContexts + 1}, + lists:zipwith (fun context_to_lwes/2, + lists:seq (1, NumContexts), + Context), + context_to_lwes (NumContexts+1, { ?MD_HOST, Host }) + ] + end; true -> [ { ?LWES_U_INT_16, ?MD_CTXT_NUM, NumContexts},