-exo_montest |
exometer |
exometer_admin |
exometer_alias |
@@ -739,11 +709,8 @@ processing is complete.
exometer_cpu |
exometer_duration |
exometer_entry |
-exometer_folsom |
-exometer_folsom_monitor |
exometer_function |
exometer_histogram |
-exometer_igor |
exometer_info |
exometer_probe |
exometer_proc |
diff --git a/doc/edoc-info b/doc/edoc-info
index d8a43fc..2b76fab 100644
--- a/doc/edoc-info
+++ b/doc/edoc-info
@@ -1,9 +1,8 @@
%% encoding: UTF-8
{application,exometer_core}.
-{modules,[exo_montest,exometer,exometer_admin,exometer_alias,exometer_cache,
- exometer_cpu,exometer_duration,exometer_entry,exometer_folsom,
- exometer_folsom_monitor,exometer_function,exometer_histogram,
- exometer_igor,exometer_info,exometer_probe,exometer_proc,
+{modules,[exometer,exometer_admin,exometer_alias,exometer_cache,exometer_cpu,
+ exometer_duration,exometer_entry,exometer_function,
+ exometer_histogram,exometer_info,exometer_probe,exometer_proc,
exometer_report,exometer_report_logger,exometer_report_tty,
exometer_shallowtree,exometer_slide,exometer_slot_slide,
exometer_spiral,exometer_uniform,exometer_util]}.
diff --git a/doc/exo_montest.md b/doc/exo_montest.md
deleted file mode 100644
index 3e61fb5..0000000
--- a/doc/exo_montest.md
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-# Module exo_montest #
-* [Description](#description)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-Demo module for `exometer_folsom_monitor` behaviours.
-
-__Behaviours:__ [`exometer_entry`](exometer_entry.md), [`exometer_folsom_monitor`](exometer_folsom_monitor.md).
-
-
-
-## Description ##
-This module simply
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### behaviour/0 ###
-
-`behaviour() -> any()`
-
-
-
-### copy_folsom/3 ###
-
-`copy_folsom(Name, Type, Opts) -> any()`
-
-
-
-### delete/3 ###
-
-`delete(X1, X2, X3) -> any()`
-
-
-
-### get_datapoints/3 ###
-
-`get_datapoints(Name, Type, X3) -> any()`
-
-
-
-### get_value/4 ###
-
-`get_value(X1, Type, X3, DPs) -> any()`
-
-
-
-### new/3 ###
-
-`new(N, X2, Opts) -> any()`
-
-
-
-### reset/3 ###
-
-`reset(X1, X2, X3) -> any()`
-
-
-
-### sample/3 ###
-
-`sample(X1, X2, X3) -> any()`
-
-
-
-### setopts/3 ###
-
-`setopts(X1, X2, X3) -> any()`
-
-
-
-### update/4 ###
-
-`update(X1, Value, Type, X4) -> any()`
-
diff --git a/doc/exometer.md b/doc/exometer.md
index 781469d..9293c26 100644
--- a/doc/exometer.md
+++ b/doc/exometer.md
@@ -28,9 +28,7 @@ Example: Putting the following in a sys.config file,
{['_'], fast_counter, [{module, exometer}]},
{['_'], gauge , [{module, exometer}]},
{['_'], histogram , [{module, exometer_histogram}]},
- {['_'], spiral , [{module, exometer_spiral}]},
- {['_'], duration , [{module, exometer_folsom}]},
- {['_'], meter , [{module, exometer_folsom}]},
+ {['_'], spiral , [{module, exometer_spiral}]}
]}
]}
```
@@ -151,7 +149,7 @@ value() = any()
## Function Index ##
-
+
@@ -163,7 +161,7 @@ value() = any()
### aggregate/2 ###
-aggregate(Pattern::ets:match_spec(), DataPoints::[datapoint()]) -> list()
+aggregate(Pattern::ets:match_spec(), DataPoints::[datapoint()]) -> list()
@@ -294,7 +292,7 @@ get_value(Name::name(), DataPoint::name()) -> [{info(), any()}]
+info(Name::name()) -> [{info(), any()}] | undefined
@@ -390,7 +388,7 @@ the counter value).
### propose/3 ###
-propose(Name::name(), Type::type(), Opts::options()) -> exometer_info:pp() | error()
+propose(Name::name(), Type::type(), Opts::options()) -> exometer_info:pp() | error()
@@ -500,7 +498,7 @@ operation likely has no effect, and will return `ok`.
### select/1 ###
-select(Pattern::ets:match_spec()) -> list()
+select(Pattern::ets:match_spec()) -> list()
@@ -515,7 +513,7 @@ metrics is `{Name, Type, Status}`.
### select/2 ###
-select(Pattern::ets:match_spec(), Limit::pos_integer() | infinity) -> {list(), _Cont}
+select(Pattern::ets:match_spec(), Limit::pos_integer() | infinity) -> {list(), _Cont}
@@ -541,7 +539,7 @@ Equivalent to [`ets:select(Cont)`](ets.md#select-1).
### select_count/1 ###
-select_count(Pattern::ets:match_spec()) -> non_neg_integer()
+select_count(Pattern::ets:match_spec()) -> non_neg_integer()
diff --git a/doc/exometer_admin.md b/doc/exometer_admin.md
index 4852f5d..c9438c9 100644
--- a/doc/exometer_admin.md
+++ b/doc/exometer_admin.md
@@ -54,7 +54,7 @@ __Behaviours:__ [`gen_server`](gen_server.md).
### find_auto_template/1 ###
-find_auto_template(Name::exometer:name()) -> #exometer_entry{} | false
+find_auto_template(Name::exometer:name()) -> #exometer_entry{} | false
diff --git a/doc/exometer_alias.md b/doc/exometer_alias.md
index 3d41f9d..a4a9930 100644
--- a/doc/exometer_alias.md
+++ b/doc/exometer_alias.md
@@ -53,7 +53,7 @@ alias() = atom() | binary()
-dp() = exometer:datapoint()
+dp() = exometer:datapoint()
@@ -69,11 +69,21 @@ fold_fun() = fun((alias(), name()
+### mp() ###
+
+
+
+mp() = {re_pattern, term(), term(), term(), term()}
+
+
+
+
+
### name() ###
-name() = exometer:name()
+name() = exometer:name()
@@ -93,7 +103,7 @@ reason() = any()
-regexp() = iodata() | re:mp()
+regexp() = iodata() | mp()
diff --git a/doc/exometer_cpu.md b/doc/exometer_cpu.md
index c2502db..dc484a8 100644
--- a/doc/exometer_cpu.md
+++ b/doc/exometer_cpu.md
@@ -23,7 +23,7 @@ __Behaviours:__ [`exometer_probe`](exometer_probe.md).
### behaviour/0 ###
-behaviour() -> exometer:behaviour()
+behaviour() -> exometer:behaviour()
diff --git a/doc/exometer_entry.md b/doc/exometer_entry.md
index 3142403..caefb7a 100644
--- a/doc/exometer_entry.md
+++ b/doc/exometer_entry.md
@@ -303,7 +303,7 @@ options.
-datapoint() = exometer:datapoint()
+datapoint() = exometer:datapoint()
diff --git a/doc/exometer_folsom.md b/doc/exometer_folsom.md
deleted file mode 100644
index b83e8e9..0000000
--- a/doc/exometer_folsom.md
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-# Module exometer_folsom #
-* [Function Index](#index)
-* [Function Details](#functions)
-
-__Behaviours:__ [`exometer_entry`](exometer_entry.md).
-
-
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### behaviour/0 ###
-
-
-behaviour() -> exometer:behaviour()
-
-
-
-
-
-### delete/3 ###
-
-`delete(Name, Type, Ref) -> any()`
-
-
-
-### get_datapoints/3 ###
-
-`get_datapoints(Name, Type, Ref) -> any()`
-
-
-
-### get_value/4 ###
-
-`get_value(Name, Type, Ref, DataPoints0) -> any()`
-
-
-
-### new/3 ###
-
-`new(Name, X2, Opts) -> any()`
-
-
-
-### reset/3 ###
-
-`reset(Name, X2, Ref) -> any()`
-
-
-
-### sample/3 ###
-
-`sample(Name, Type, Ref) -> any()`
-
-
-
-### setopts/3 ###
-
-`setopts(Entry, Options, Status) -> any()`
-
-
-
-### update/4 ###
-
-`update(Name, Value, Type, Ref) -> any()`
-
diff --git a/doc/exometer_folsom_monitor.md b/doc/exometer_folsom_monitor.md
deleted file mode 100644
index bc0b5a8..0000000
--- a/doc/exometer_folsom_monitor.md
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-# Module exometer_folsom_monitor #
-* [Description](#description)
-* [Function Index](#index)
-* [Function Details](#functions)
-
-Hook API for following folsom-based legacy code with exometer.
-
-__Behaviours:__ [`gen_server`](gen_server.md).
-
-__This module defines the `exometer_folsom_monitor` behaviour.__
Required callback functions: `copy_folsom/3`.
-
-
-
-## Description ##
-
-This module installs hooks into folsom, allowing subscribers to trap
-the creation of metrics using the folsom API, and instruct exometer
-to create matching metrics entries.
-
-Subscriptions identify a module that should be on the call stack when
-a module is created (when testing from the shell, use the module `shell`),
-and a callback module which is used to retrieve the specs for exometer
-metrics to create.
-
-## Function Index ##
-
-
-
-
-
-
-
-## Function Details ##
-
-
-
-### monitor/2 ###
-
-
-monitor(FromMod::atom(), Callback::atom()) -> ok
-
-
-
-Monitor a legacy module.
-
-`FromMod` is the name of a module that should appear on the call stack
-when a call to `folsom_metrics:new_` is made (or `'_'`,
-which will match any call stack). `Callback` is a callback module,
-exporting the function `copy_folsom(Name,Type,Opts)`, which returns a
-`{Name, Type, Options}` tuple, a list of such tuples, or the atom `false`.
-
-The callback module is called from the `exometer_folsom_monitor`
-process, so the call stack will not contain the legacy modules.
-However, if the corresponding exometer metrics end up calling other
-folsom-based metrics (e.g. using the `exometer_folsom` module), there
-will be a risk of generating a loop.
-
-
-
-### start_link/0 ###
-
-`start_link() -> any()`
-
-Start the server (called automatically by exometer).
-
diff --git a/doc/exometer_function.md b/doc/exometer_function.md
index e4e5926..842be2c 100644
--- a/doc/exometer_function.md
+++ b/doc/exometer_function.md
@@ -138,7 +138,7 @@ expr_descr() = expr_int() | erl_parse:abstract_expr()]}
+expr_erl() = {erl, [erl_parse:abstract_expr()]}
@@ -339,7 +339,7 @@ simple_fun() = {function, mod_name(), exometer:behaviour()
+behaviour() -> exometer:behaviour()
@@ -416,7 +416,7 @@ relationship between sublists is 'or'. This is the same as in Erlang.
### new/3 ###
-new(Name::exometer:name(), X2::function, Opts::exometer:options()) -> {ok, fun_rep()}
+new(Name::exometer:name(), X2::function, Opts::exometer:options()) -> {ok, fun_rep()}
diff --git a/doc/exometer_histogram.md b/doc/exometer_histogram.md
index 9558e2a..e8ddca0 100644
--- a/doc/exometer_histogram.md
+++ b/doc/exometer_histogram.md
@@ -87,7 +87,7 @@ to determine the percentiles `90` and up.
### behaviour/0 ###
-behaviour() -> exometer:behaviour()
+behaviour() -> exometer:behaviour()
@@ -187,9 +187,6 @@ Return value: `[Result1, Result2]`, where the results are
insert the values. `Time2` is the time it took to calculate all default
datapoints. The data set is shuffled between the two runs.
-To assess the accuracy of the reported percentiles, use e.g.
-`bear:get_statistics(exometer_histogram:test_series())` as a reference.
-
### test_series/0 ###
@@ -201,7 +198,7 @@ test_series() -> [integer()]
Create a series of values for histogram testing.
-These are the properties of the current test set:
+These are the properties of the current test set (note: bear no longer in use):
```erlang
diff --git a/doc/exometer_info.md b/doc/exometer_info.md
index 6e39e47..b892250 100644
--- a/doc/exometer_info.md
+++ b/doc/exometer_info.md
@@ -85,7 +85,7 @@ for each matching metric, and calls `pp(Entry)` for each entry.
### pp_lookup/1 ###
-pp_lookup(Name::exometer:name()) -> pp() | undefined
+pp_lookup(Name::exometer:name()) -> pp() | undefined
@@ -98,7 +98,7 @@ This function returns `undefined` if the entry cannot be found.
### pp_select/1 ###
-pp_select(Pat::ets:match_spec()) -> [pp()]
+pp_select(Pat::ets:match_spec()) -> [pp()]
@@ -115,7 +115,7 @@ Note that the match body of the select pattern must produce the full
### status/1 ###
-status(Exometer_entry::exometer:entry()) -> enabled | disabled
+status(Exometer_entry::exometer:entry()) -> enabled | disabled
diff --git a/doc/exometer_proc.md b/doc/exometer_proc.md
index abf6984..cb2cb5c 100644
--- a/doc/exometer_proc.md
+++ b/doc/exometer_proc.md
@@ -107,7 +107,7 @@ Apply process_flag-specific options.
### spawn_process/2 ###
-spawn_process(Name::exometer:name(), F::fun(() -> no_return())) -> pid()
+spawn_process(Name::exometer:name(), F::fun(() -> no_return())) -> pid()
diff --git a/doc/exometer_report.md b/doc/exometer_report.md
index 1d73f54..fae0779 100644
--- a/doc/exometer_report.md
+++ b/doc/exometer_report.md
@@ -198,7 +198,7 @@ with a list of one datapoint/value pair.
-datapoint() = exometer:datapoint()
+datapoint() = exometer:datapoint()
@@ -258,7 +258,7 @@ interval() = pos_integer() | atom()
-metric() = exometer:name() | {find, exometer:name()} | {select, ets:match_spec()}
+metric() = exometer:name() | {find, exometer:name()} | {select, ets:match_spec()}
@@ -308,8 +308,16 @@ time_ms() = pos_integer()
add_reporter/2 | Add a reporter. |
call_reporter/2 | Send a custom (synchronous) call to Reporter . |
cast_reporter/2 | Send a custom (asynchronous) cast to Reporter . |
delete_interval/2 | Delete a named interval. |
disable_me/2 | Used by a reporter to disable itself. |
disable_reporter/1 | Disable Reporter . |
enable_reporter/1 | Enable Reporter . |
get_intervals/1 | List the named intervals for Reporter . |
list_metrics/0 | Equivalent to list_metrics([]). |
list_metrics/1 | List all metrics matching Path , together with subscription status. |
list_reporters/0 | List the name and pid of each known reporter. |
list_subscriptions/1 | List all subscriptions for Reporter . |
new_entry/1 | Called by exometer whenever a new entry is created. |
remove_reporter/1 | Remove reporter and all its subscriptions. |
remove_reporter/2 | Remove Reporter (non-blocking call). |
restart_intervals/1 | Restart all named intervals, respecting specified delays. |
set_interval/3 | Specify a named interval. |
setopts/3 | Called by exometer when options of a metric entry are changed. |
start_link/0 | Starts the server
---------------------------------------------------------------------. |
start_reporters/0 | |
subscribe/4 | Equivalent to subscribe(Reporter, Metric, DataPoint, Interval, [],
-true). |
subscribe/5 | Equivalent to subscribe(Reporter, Metric, DataPoint, Interval, Extra,
+--------------------------------------------------------------------. |
start_reporters/0 | |
subscribe/4 | Equivalent to subscribe(Reporter,
+Metric,
+DataPoint,
+Interval,
+[],
+true). |
subscribe/5 | Equivalent to subscribe(Reporter,
+Metric,
+DataPoint,
+Interval,
+Extra,
false). |
subscribe/6 | Add a subscription to an existing reporter. |
terminate_reporter/1 | |
trigger_interval/2 | Trigger a named interval. |
unsubscribe/3 | Equivalent to unsubscribe(Reporter, Metric, DataPoint, []). |
unsubscribe/4 | Removes a subscription. |
unsubscribe_all/2 | Removes all subscriptions related to Metric in Reporter. |
@@ -465,7 +473,7 @@ List the named intervals for `Reporter`.
### list_metrics/0 ###
-list_metrics() -> {ok, [{exometer:name(), [datapoint()], [{reporter_name(), datapoint()}], exometer:status()}]} | {error, any()}
+list_metrics() -> {ok, [{exometer:name(), [datapoint()], [{reporter_name(), datapoint()}], exometer:status()}]} | {error, any()}
@@ -476,7 +484,7 @@ Equivalent to [`list_metrics([])`](#list_metrics-1).
### list_metrics/1 ###
-list_metrics(Path::metric()) -> {ok, [{exometer:name(), [datapoint()], [{reporter_name(), datapoint()}], exometer:status()}]} | {error, any()}
+list_metrics(Path::metric()) -> {ok, [{exometer:name(), [datapoint()], [{reporter_name(), datapoint()}], exometer:status()}]} | {error, any()}
@@ -514,7 +522,7 @@ List all subscriptions for `Reporter`.
### new_entry/1 ###
-new_entry(Entry::exometer:entry()) -> ok
+new_entry(Entry::exometer:entry()) -> ok
@@ -597,7 +605,7 @@ all intervals to be restarted/resynched with corresponding relative delays.
### setopts/3 ###
-setopts(Metric::exometer:entry(), Options::options(), Status::exometer:status()) -> ok
+setopts(Metric::exometer:entry(), Options::options(), Status::exometer:status()) -> ok
@@ -633,7 +641,7 @@ subscribe(Reporter::reporter_name(), Metric::<
-Equivalent to [`subscribe(Reporter, Metric, DataPoint, Interval, [],true)`](#subscribe-6).
+Equivalent to [`subscribe(Reporter,Metric,DataPoint,Interval,[],true)`](#subscribe-6).
@@ -644,7 +652,7 @@ subscribe(Reporter::reporter_name(), Metric::<
-Equivalent to [`subscribe(Reporter, Metric, DataPoint, Interval, Extra,false)`](#subscribe-6).
+Equivalent to [`subscribe(Reporter,Metric,DataPoint,Interval,Extra,false)`](#subscribe-6).
diff --git a/doc/exometer_report_logger.md b/doc/exometer_report_logger.md
index 0ed3b26..7a53b24 100644
--- a/doc/exometer_report_logger.md
+++ b/doc/exometer_report_logger.md
@@ -10,7 +10,7 @@ Exometer report collector and logger.
__Behaviours:__ [`gen_server`](gen_server.md).
-__This module defines the `exometer_report_logger` behaviour.__
Required callback functions: `logger_init_input/1`, `logger_init_output/1`, `logger_handle_data/2`.
+__This module defines the `exometer_report_logger` behaviour.__
Required callback functions: `logger_handle_data/2`.
diff --git a/doc/exometer_slide.md b/doc/exometer_slide.md
index 38b9ead..782464c 100644
--- a/doc/exometer_slide.md
+++ b/doc/exometer_slide.md
@@ -77,7 +77,7 @@ sample_fun() = fun((timestamp(), exometer_util:timestamp()
+timestamp() = exometer_util:timestamp()
@@ -149,6 +149,11 @@ add_element(TS::timestamp(), Evt::timestamp(), Evt::value(), Slide::#slide{size = integer(), n = integer(), max_n = undefined | integer(), last = integer(), buf1 = list(), buf2 = list()}, Wrap::false) -> #slide{size = integer(), n = integer(), max_n = undefined | integer(), last = integer(), buf1 = list(), buf2 = list()}
+
+
+
Add an element to the buffer, optionally indicating if a swap occurred.
This function works like [`add_element/3`](#add_element-3), but will also indicate
diff --git a/doc/exometer_spiral.md b/doc/exometer_spiral.md
index 1f3faf6..4e86642 100644
--- a/doc/exometer_spiral.md
+++ b/doc/exometer_spiral.md
@@ -23,7 +23,7 @@ __Behaviours:__ [`exometer_probe`](exometer_probe.md).
### behaviour/0 ###
-behaviour() -> exometer:behaviour()
+behaviour() -> exometer:behaviour()
diff --git a/doc/exometer_util.md b/doc/exometer_util.md
index 8673757..6062157 100644
--- a/doc/exometer_util.md
+++ b/doc/exometer_util.md
@@ -28,7 +28,7 @@ timestamp() = non_neg_integer()
+drop_duplicates/1
will drop all duplicate elements from a list of tuples identified by their first element.ensure_all_started/1 | |
get_datapoints/1 | |
get_env/2 | |
get_opt/2 | |
get_opt/3 | |
get_statistics/1 | |
get_statistics/3 | Calculate statistics from a sorted list of values. |
get_statistics2/4 | |
get_status/1 | |
histogram/1 | |
histogram/2 | |
perc/2 | |
pick_items/2 | Pick values from specified positions in a sorted list of numbers. |
report_type/3 | |
seed/0 | |
seed/0 | |
seed/1 | |
seed/1 | |
seed0/0 | |
seed0/0 | |
set_call_count/2 | |
set_call_count/3 | |
set_event_flag/2 | |
set_status/2 | |
table/0 | |
tables/0 | |
test_event_flag/2 | |
timestamp/0 | Generate a millisecond-resolution timestamp. |
timestamp_to_datetime/1 | Convert timestamp to a regular datetime. |
uniform/0 | |
uniform/0 | |
uniform/1 | |
uniform/1 | |
' is made (or '_'
,
-%% which will match any call stack). `Callback' is a callback module,
-%% exporting the function `copy_folsom(Name,Type,Opts)', which returns a
-%% `{Name, Type, Options}' tuple, a list of such tuples, or the atom `false'.
-%%
-%% The callback module is called from the `exometer_folsom_monitor'
-%% process, so the call stack will not contain the legacy modules.
-%% However, if the corresponding exometer metrics end up calling other
-%% folsom-based metrics (e.g. using the `exometer_folsom' module), there
-%% will be a risk of generating a loop.
-%% @end
-monitor(FromMod, Callback) when is_atom(FromMod), is_atom(Callback) ->
- gen_server:call(?MODULE, {monitor, FromMod, Callback}).
-
-%% @private
-hook(Args) ->
- Stack = try error(x)
- catch
- ?EXCEPTION(error, _, Stacktrace) ->
- ?GET_STACK(Stacktrace)
- end,
- gen_server:cast(?MODULE, {hook, Args, Stack}).
-
-%% @doc Start the server (called automatically by exometer).
-start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-
-%% @private
-init(_) ->
- Mon = lists:foldl(
- fun({Mf, Mc}, D) ->
- orddict:append(Mf, Mc, D)
- end, orddict:new(), find_env()),
- init_monitor(Mon),
- {ok, #st{mon = Mon}}.
-
-find_env() ->
- E1 = [E || {_, E} <- setup:find_env_vars(exometer_folsom_monitor)],
- E2 = exometer_util:get_env(folsom_monitor, []),
- lists:flatmap(
- fun({_,_} = M) -> [M];
- (L) when is_list(L) -> L
- end, E1 ++ E2).
-
-%% @private
-handle_call({monitor, Mod, CB}, _, #st{mon = Mon} = S)
- when is_atom(Mod), is_atom(CB) ->
- if Mon == [] -> do_init_monitor();
- true -> ok
- end,
- {reply, ok, S#st{mon = orddict:append(Mod, CB, Mon)}};
-handle_call(_, _, S) ->
- {reply, {error, unsupported}, S}.
-
-%% @private
-handle_cast({hook, Args, Stack}, S) ->
- check_stack(S#st.mon, Stack, Args),
- {noreply, S}.
-%% @private
-handle_info(_, S) -> {noreply, S}.
-%% @private
-terminate(_, _) -> ok.
-%% @private
-code_change(_, S, _) -> {ok, S}.
-
-init_monitor([]) ->
- ok;
-init_monitor([_|_]) ->
- do_init_monitor().
-
-do_init_monitor() ->
- case is_transformed() of
- true ->
- ?log(debug, "already transformed...~n", []),
- ok;
- false ->
- ?log(debug, "transforming folsom_metrics...~n", []),
- parse_trans_mod:transform_module(folsom_metrics, fun pt/2, [])
- end.
-
-pt(Forms, _) ->
- Funcs = funcs(),
- NewForms = parse_trans:plain_transform(
- fun(F) ->
- plain_pt(F, Funcs)
- end, Forms),
- mark_transformed(NewForms).
-
-is_transformed() ->
- Attrs = folsom_metrics:module_info(attributes),
- [true || {?MODULE,[]} <- Attrs] =/= [].
-
-mark_transformed([{attribute,L,module,_} = M|Fs]) ->
- [M, {attribute,L,?MODULE,[]} | Fs];
-mark_transformed([H|T]) ->
- [H | mark_transformed(T)].
-
-plain_pt({function,L,F,A,Cs}, Funcs) ->
- case lists:keyfind({F,A}, 1, Funcs) of
- {_, Type} ->
- {function,L,F,A,insert_hook(Type, Cs)};
- false ->
- continue
- end;
-plain_pt(_, _) ->
- continue.
-
-funcs() ->
- [{{new_counter , 1}, counter},
- {{new_gauge , 1}, gauge},
- {{new_meter , 1}, meter},
- {{new_meter_reader, 1}, meter_reader},
- {{new_history , 2}, history},
- {{new_histogram , 4}, histogram},
- {{new_spiral , 1}, spiral},
- {{new_duration , 4}, duration}].
-
-
-insert_hook(Type, Cs) ->
- lists:map(
- fun({clause,L0,Args,Gs,Body}) ->
- L = element(2,hd(Body)),
- {clause,L0,Args,Gs,
- [{call,L,{remote,L,{atom,L,?MODULE},{atom,L,hook}},
- [cons([{atom,L,Type}|Args], L)]}|Body]}
- end, Cs).
-
-cons([H|T], L) -> {cons,L,H,cons(T,L)};
-cons([] , L) -> {nil,L}.
-
-check_stack(Mon, Stack, Args) ->
- orddict:fold(
- fun('_', CBs, Acc) ->
- _ = [maybe_create(CB, Args) || CB <- CBs],
- Acc;
- (Mod, CBs, Acc) ->
- case lists:keymember(Mod, 1, Stack) of
- true ->
- _ = [maybe_create(CB, Args) || CB <- CBs];
- false ->
- ignore
- end,
- Acc
- end, ok, Mon).
-
-maybe_create(CB, [FolsomType, Name | Args]) ->
- try CB:copy_folsom(Name, FolsomType, Args) of
- {ExoName, ExoType, ExoArgs} ->
- exometer:new(ExoName, ExoType, ExoArgs);
- L when is_list(L) ->
- lists:foreach(
- fun({ExoName, ExoType, ExoArgs}) ->
- exometer:new(ExoName, ExoType, ExoArgs)
- end, L);
- false ->
- ignore
- catch
- Cat:Msg ->
- ?log(error, "~p:copy_folsom(~p,~p,~p): ~p:~p~n",
- [CB, Name, FolsomType, Args, Cat, Msg]),
- ignore
- end.
diff --git a/src/exometer_histogram.erl b/src/exometer_histogram.erl
index d3991ba..5f3cfdc 100644
--- a/src/exometer_histogram.erl
+++ b/src/exometer_histogram.erl
@@ -420,9 +420,6 @@ test_run(Module) ->
%% `{Time1, Time2, Datapoints}'. `Time1' is the time (in microsecs) it took to
%% insert the values. `Time2' is the time it took to calculate all default
%% datapoints. The data set is shuffled between the two runs.
-%%
-%% To assess the accuracy of the reported percentiles, use e.g.
-%% `bear:get_statistics(exometer_histogram:test_series())' as a reference.
%% @end
test_run(Module, Interval) ->
Series = test_series(),
@@ -462,7 +459,7 @@ tc(F) ->
-spec test_series() -> [integer()].
%% @doc Create a series of values for histogram testing.
%%
-%% These are the properties of the current test set:
+%% These are the properties of the current test set (note: bear no longer in use):
%%
%% 1> rp(bear:get_statistics(exometer_histogram:test_series())).
%% [{min,3},
diff --git a/src/exometer_util.erl b/src/exometer_util.erl
index b4dab4d..bedcd67 100644
--- a/src/exometer_util.erl
+++ b/src/exometer_util.erl
@@ -20,6 +20,7 @@
get_env/2,
tables/0,
table/0,
+ get_statistics/1,
get_statistics/3,
get_statistics2/4,
pick_items/2,
@@ -223,6 +224,10 @@ histogram(Values, DataPoints) ->
[DP || {K,_} = DP <- H,
lists:member(K, DataPoints)].
+get_statistics(Values) ->
+ Sorted = lists:sort(Values),
+ get_statistics(length(Sorted), lists:sum([V || {_,V} <- Sorted]), Sorted).
+
-spec get_statistics(Length::non_neg_integer(),
Total::non_neg_integer(),
Sorted::list()) -> [{atom(), number()}].
diff --git a/test/exometer_SUITE.erl b/test/exometer_SUITE.erl
index 6b93aca..b5b0561 100644
--- a/test/exometer_SUITE.erl
+++ b/test/exometer_SUITE.erl
@@ -32,14 +32,11 @@
test_std_histogram/1,
test_slot_histogram/1,
test_std_duration/1,
- test_folsom_histogram/1,
test_aggregate/1,
test_history1_slide/1,
test_history1_slotslide/1,
- test_history1_folsom/1,
test_history4_slide/1,
test_history4_slotslide/1,
- test_history4_folsom/1,
test_re_register_probe/1,
test_ext_predef/1,
test_app_predef/1,
@@ -95,14 +92,11 @@ groups() ->
test_std_histogram,
test_slot_histogram,
test_std_duration,
- test_folsom_histogram,
test_aggregate,
test_history1_slide,
test_history1_slotslide,
- test_history1_folsom,
test_history4_slide,
test_history4_slotslide,
- test_history4_folsom,
test_slide_ignore_outdated
]},
{re_register, [shuffle],
@@ -130,15 +124,6 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ok.
-init_per_testcase(Case, Config) when
- Case == test_folsom_histogram;
- Case == test_history1_folsom;
- Case == test_history4_folsom ->
- {ok, StartedApps} = exometer_test_util:ensure_all_started(exometer_core),
- ct:log("StartedApps = ~p", [StartedApps]),
- application:start(bear),
- application:start(folsom),
- [{started_apps, StartedApps} | Config];
init_per_testcase(Case, Config) when
Case == test_ext_predef;
Case == test_function_match ->
@@ -162,14 +147,6 @@ init_per_testcase(_Case, Config) ->
ct:log("StartedApps = ~p~n", [StartedApps]),
[{started_apps, StartedApps} | Config].
-end_per_testcase(Case, Config) when
- Case == test_folsom_histogram;
- Case == test_history1_folsom;
- Case == test_history4_folsom ->
- _ = stop_started_apps(Config),
- folsom:stop(),
- application:stop(bear),
- ok;
end_per_testcase(Case, Config) when
Case == test_ext_predef;
Case == test_function_match ->
@@ -367,32 +344,6 @@ update_duration(C, V) ->
timer:sleep(V),
exometer:update(C, timer_end).
-test_folsom_histogram(_Config) ->
- ok = exometer:new(
- C1 = [?MODULE,hist,?LINE],
- ad_hoc, [{module, exometer_folsom},
- {type, histogram}]), %% truncate by default
- ok = exometer:new(
- C2 = [?MODULE,hist,?LINE],
- ad_hoc, [{module, exometer_folsom},
- {type, histogram},
- {truncate, true}]),
- ok = exometer:new(
- C3 = [?MODULE,hist,?LINE],
- ad_hoc, [{module, exometer_folsom},
- {type, histogram},
- {truncate, false}]),
- _ = [[update_(C1,V),update_(C2,V),update_(C3,V)] || V <- vals()],
- {_, {ok,DPs1}} = timer:tc(exometer, get_value, [C1]),
- {_, {ok,DPs2}} = timer:tc(exometer, get_value, [C2]),
- {_, {ok,DPs3}} = timer:tc(exometer, get_value, [C3]),
- [{n,134},{mean,2},{min,1},{max,9},{median,2},
- {50,2},{75,3},{90,4},{95,5},{99,8},{999,9}] = DPs1 = DPs2,
- [{n,134},{mean,2126866},{min,1},{max,9},{median,2},
- {50,2},{75,3},{90,4},{95,5},{99,8},{999,9}] =
- scale_mean(DPs3),
- ok.
-
test_aggregate(_Config) ->
K = ?LINE,
ok = exometer:new(E1 = [?MODULE, K, a, 1], gauge, []),
@@ -414,18 +365,12 @@ test_history1_slide(_Config) ->
test_history1_slotslide(_Config) ->
test_history(1, slot_slide, file_path("test/data/puts_time_hist1.bin")).
-test_history1_folsom(_Config) ->
- test_history(1, folsom, file_path("test/data/puts_time_hist1.bin")).
-
test_history4_slide(_Config) ->
test_history(4, slide, file_path("test/data/puts_time_hist4.bin")).
test_history4_slotslide(_Config) ->
test_history(4, slot_slide, file_path("test/data/puts_time_hist4.bin")).
-test_history4_folsom(_Config) ->
- test_history(4, folsom, file_path("test/data/puts_time_hist4.bin")).
-
test_re_register_probe(_Config) ->
K = ?LINE,
ok = exometer:re_register(S1 = [?MODULE, K, s, 1], spiral, []), % re_register as new/3
@@ -556,7 +501,7 @@ test_history(N, slide, F) ->
RefStats = load_data(F, M),
ct:log("history(~w,s): ~p~n"
"reference: ~p~n", [N, exometer:get_value(M),
- subset(RefStats)]),
+ RefStats]),
ok;
test_history(N, slot_slide, F) ->
M = [?MODULE, hist, ?LINE],
@@ -567,27 +512,11 @@ test_history(N, slot_slide, F) ->
{slot_period, 1}]),
RefStats = load_data(F, 2000, M),
{T, {ok, Val}} = timer:tc(exometer,get_value,[M]),
- Subset = subset(RefStats),
- Error = calc_error(Val, Subset),
+ Error = calc_error(Val, RefStats),
ct:log("time: ~p~n"
"history(~w,ss): ~p~n"
"reference: ~p~n"
- "error: ~p~n", [T, N, Val, Subset, Error]),
- ok;
-test_history(N, folsom, F) ->
- M = [?MODULE, hist, ?LINE],
- ok = exometer:new(
- M, ad_hoc, [{module, exometer_folsom},
- {type, histogram},
- {truncate, true}]),
- RefStats = load_data(F, M),
- {T, {ok, Val}} = timer:tc(exometer,get_value,[M]),
- Subset = subset(RefStats),
- Error = calc_error(Val, Subset),
- ct:log("time: ~p~n"
- "history(~w,f): ~p~n"
- "reference: ~p~n"
- "error: ~p~n", [T, N, Val, Subset, Error]),
+ "error: ~p~n", [T, N, Val, RefStats, Error]),
ok.
vals() ->
@@ -620,7 +549,7 @@ load_data(F, M) ->
ct:log("load_data(~s,...)", [F]),
ct:log("CWD = ~p", [element(2, file:get_cwd())]),
{ok, [Values]} = file:consult(F),
- Stats = bear:get_statistics(Values),
+ Stats = exometer_util:get_statistics(Values),
_T1 = os:timestamp(),
_ = [ok = exometer:update(M, V) || V <- Values],
_T2 = os:timestamp(),
@@ -628,7 +557,7 @@ load_data(F, M) ->
load_data(F, Rate, M) ->
{ok, [Values]} = file:consult(F),
- Stats = bear:get_statistics(Values),
+ Stats = exometer_util:get_statistics(Values),
pace(Rate, fun([V|Vs]) ->
ok = exometer:update(M, V),
{more, Vs};
@@ -673,20 +602,25 @@ shoot(F, St, [_|T]) ->
shoot(_, St, []) ->
{more, St}.
-subset(Stats) ->
- lists:map(
- fun(mean) -> {mean, proplists:get_value(arithmetic_mean, Stats)};
- (K) when is_atom(K) -> lists:keyfind(K, 1, Stats);
- (P) when is_integer(P) ->
- lists:keyfind(P, 1, proplists:get_value(percentile,Stats,[]))
- end, [n,mean,min,max,median,50,75,90,95,99,999]).
-
calc_error(Val, Ref) ->
+ ct:pal("Val = ~p, Ref = ~p", [Val, Ref]),
lists:map(
fun({{K,V}, {K,R}}) ->
- {K, abs(V-R)/R}
- end, lists:zip(Val, Ref)).
+ {K, try_err(V, R)}
+ end, lists:zip(Val, sort_ref(Val, Ref))).
+sort_ref([{K,_}|T], Ref) ->
+ {_, V} = lists:keyfind(K, 1, Ref),
+ [{K, V} | sort_ref(T, Ref)];
+sort_ref([], _) ->
+ [].
+
+try_err(V, R) ->
+ try abs(V-R)/R
+ catch
+ error:_ ->
+ error
+ end.
compile_app1(Config) ->
DataDir = filename:absname(?config(data_dir, Config)),