Skip to content

Commit

Permalink
Merge pull request #4390 from esl/check-probe-metrics-types
Browse files Browse the repository at this point in the history
Check probe metrics types
  • Loading branch information
arcusfelis authored Nov 4, 2024
2 parents 89617b2 + ccc6eb9 commit 7a5650d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 49 deletions.
70 changes: 35 additions & 35 deletions doc/operation-and-maintenance/MongooseIM-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@ All metrics are divided into the following groups:
=== "Prometheus"

<h3>`counter`</h3>

A monotonically increasing metric type. It is used for events like the number of stanzas processed by the system.

**Example:**
```
# TYPE c2s_element_in_message_count counter
# HELP c2s_element_in_message_count Event: c2s_element_in, Metric: message_count
c2s_element_in_message_count{host_type="localhost"} 0
```

<h3>`gauge`</h3>

A metric that represents a current value in the system.

**Example:**
```
# TYPE mnesia_info_running_db_nodes gauge
Expand All @@ -49,9 +49,9 @@ All metrics are divided into the following groups:
```

<h3>`histogram`</h3>

A histogram collects values and groups them in buckets.

**Example:**
```
# TYPE c2s_xmpp_element_size_in_byte_size histogram
Expand All @@ -61,35 +61,35 @@ All metrics are divided into the following groups:
c2s_xmpp_element_size_in_byte_size_bucket{le="1073741824"} 0
c2s_xmpp_element_size_in_byte_size_bucket{le="+Inf"} 0
```

=== "Exometer"

<h3>`spiral`</h3>

This kind of metric provides 2 values: `total` event count (e.g. stanzas processed) and a value in 60s window (`one` value).
Dividing `one` value by 60 provides an average per-second value over last minute.

**Example:** `[{total, 1000}, {one, 20}]`

<h3>`counter`</h3>

A simple monotonically increasing value. It consists of two properties:

**Example:** `[{value, 12}, {ms_since_reset, 91761}]`

<h3>`gauge`</h3>

It is similar to a `counter` type but can be set to any value.

* `value`
* `ms_since_reset` - Time in milliseconds elapsed from the last metric update.

**Example:** `[{value, 12}, {ms_since_reset, 91761}]`

<h3>`histogram`</h3>

A histogram collects values over a sliding window of 60s and exposes the following stats:

* `n` - A number of samples.
* `mean` - An arithmetic mean.
* `min`
Expand Down Expand Up @@ -228,26 +228,26 @@ Since Exometer doesn't support labels, the host types and tags are part of the m
| Name | Type | Description (when it gets incremented) |
| ---- | ---- | -------------------------------------- |
| `wpool_rdbms_stats_workers` | gauge | Number of workers in the pool |
| `wpool_rdbms_stats_recv_oct` | counter | Number of bytes received |
| `wpool_rdbms_stats_recv_cnt` | counter | Number of packets received |
| `wpool_rdbms_stats_recv_max` | gauge | Size of the largest packet, in bytes |
| `wpool_rdbms_stats_send_oct` | counter | Number of bytes sent |
| `wpool_rdbms_stats_send_max` | gauge | Size of the largest packet |
| `wpool_rdbms_stats_send_cnt` | counter | Number of packets sent |
| `wpool_rdbms_stats_send_pend` | counter | Number of bytes waiting to be sent |
| `wpool_rdbms_stats_recv_oct` | gauge | Number of bytes received |
| `wpool_rdbms_stats_recv_cnt` | gauge | Number of packets received |
| `wpool_rdbms_stats_recv_max` | gauge | Size of the largest packet, in bytes |
| `wpool_rdbms_stats_send_oct` | gauge | Number of bytes sent |
| `wpool_rdbms_stats_send_max` | gauge | Size of the largest packet |
| `wpool_rdbms_stats_send_cnt` | gauge | Number of packets sent |
| `wpool_rdbms_stats_send_pend` | gauge | Number of bytes waiting to be sent |

=== "Exometer"

| Name | Type | Description (when it gets incremented) |
|--------------------------------------------------------------|---------|----------------------------------------|
| `[HostType, wpool_rdbms_stats, PoolTag, workers]` | counter | Number of workers in the pool |
| `[HostType, wpool_rdbms_stats, PoolTag, recv_oct]` | spiral | Number of bytes received |
| `[HostType, wpool_rdbms_stats, PoolTag, recv_cnt]` | spiral | Number of packets received |
| `[HostType, wpool_rdbms_stats, PoolTag, recv_max]` | gauge | Size of the largest packet, in bytes |
| `[HostType, wpool_rdbms_stats, PoolTag, send_oct]` | spiral | Number of bytes sent |
| `[HostType, wpool_rdbms_stats, PoolTag, send_max]` | gauge | Size of the largest packet |
| `[HostType, wpool_rdbms_stats, PoolTag, send_cnt]` | spiral | Number of packets sent |
| `[HostType, wpool_rdbms_stats, PoolTag, send_pend]` | spiral | Number of bytes waiting to be sent |
| `[HostType, wpool_rdbms_stats, PoolTag, workers]` | gauge | Number of workers in the pool |
| `[HostType, wpool_rdbms_stats, PoolTag, recv_oct]` | gauge | Number of bytes received |
| `[HostType, wpool_rdbms_stats, PoolTag, recv_cnt]` | gauge | Number of packets received |
| `[HostType, wpool_rdbms_stats, PoolTag, recv_max]` | gauge | Size of the largest packet, in bytes |
| `[HostType, wpool_rdbms_stats, PoolTag, send_oct]` | gauge | Number of bytes sent |
| `[HostType, wpool_rdbms_stats, PoolTag, send_max]` | gauge | Size of the largest packet |
| `[HostType, wpool_rdbms_stats, PoolTag, send_cnt]` | gauge | Number of packets sent |
| `[HostType, wpool_rdbms_stats, PoolTag, send_pend]` | gauge | Number of bytes waiting to be sent |

When using a Rabbit worker pool, metrics defined in [mod_event_pusher_rabbit](../modules/mod_event_pusher_rabbit.md) are
available.
Expand Down
36 changes: 33 additions & 3 deletions src/instrument/mongoose_instrument.erl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
-type handler_key() :: atom(). % key in the `instrumentation' section of the config file
-type handler_fun() :: fun((event_name(), labels(), config(), measurements()) -> any()).
-type handlers() :: {[handler_fun()], config()}.
-type handler_map() :: #{labels() => handlers()}.
-type execution_time() :: integer().
-type measure_fun(Result) :: fun((execution_time(), Result) -> measurements()).
-type handler_module_opts() :: #{atom() => any()}.
Expand Down Expand Up @@ -274,16 +275,45 @@ set_up_and_register_event(EventName, Labels, Config, Events) ->
{ExistingLabels, _, _} = maps:next(maps:iterator(HandlerMap)),
case label_keys(ExistingLabels) of
LabelKeys ->
Handlers = do_set_up(EventName, Labels, Config),
Events#{EventName := HandlerMap#{Labels => Handlers}};
handle_metrics_config(EventName, Labels, Config, HandlerMap, Events);
ExistingKeys ->
{error, #{what => inconsistent_labels,
event_name => EventName, labels => Labels,
existing_label_keys => ExistingKeys}}
end;
#{} ->
handle_metrics_config(EventName, Labels, Config, new, Events)
end.

-spec handle_metrics_config(event_name(), labels(), config(), handler_map() | new, event_map()) ->
event_map() | {error, map()}.
handle_metrics_config(EventName, Labels, Config, HandlerMap, Events) ->
case filter_improper_probe_metrics(Config) of
{ok, _} ->
Handlers = do_set_up(EventName, Labels, Config),
Events#{EventName => #{Labels => Handlers}}
case HandlerMap of
new ->
Events#{EventName => #{Labels => Handlers}};
_ ->
Events#{EventName := HandlerMap#{Labels => Handlers}}
end;
{error, FilteredMetrics} ->
{error, #{what => non_gauge_metrics_in_probe,
event_name => EventName, labels => Labels,
improper_metrics => FilteredMetrics}}
end.

-spec filter_improper_probe_metrics(config()) -> {ok, #{}} | {error, metrics()}.
filter_improper_probe_metrics(Config) ->
case Config of
#{probe := _, metrics := Metrics} ->
FilteredMetrics = maps:filter(fun(_, V) -> V =/= gauge end, Metrics),
case map_size(FilteredMetrics) of
0 -> {ok, FilteredMetrics};
_ -> {error, FilteredMetrics}
end;
_ ->
{ok, #{}}
end.

-spec do_set_up(event_name(), labels(), config()) -> handlers().
Expand Down
16 changes: 5 additions & 11 deletions src/wpool/mongoose_wpool_rdbms.erl
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ instrumentation(global, Tag) ->
% Services use global pools. Since the same number of labels for a metric is expected, for an
% event, global pool has to emit an event under a different name.
[{wpool_global_rdbms_stats, #{pool_tag => Tag},
#{probe => #{module => ?MODULE}, metrics => rdbms_data_stats_measurement_types()}}];
#{probe => #{module => ?MODULE}, metrics => gauges([workers | inet_stats()])}}];
instrumentation(HostType, Tag) ->
[{wpool_rdbms_stats, #{host_type => HostType, pool_tag => Tag},
#{probe => #{module => ?MODULE}, metrics => rdbms_data_stats_measurement_types()}}].
#{probe => #{module => ?MODULE}, metrics => gauges([workers | inet_stats()])}}].

-spec probe(mongoose_instrument:event_name(), mongoose_instrument:labels()) ->
mongoose_instrument:measurements().
Expand Down Expand Up @@ -166,12 +166,6 @@ empty_inet_stats_measurements() ->
send_cnt => 0,
send_pend => 0}.

rdbms_data_stats_measurement_types() ->
#{workers => counter,
recv_oct => spiral,
recv_cnt => spiral,
recv_max => gauge,
send_oct => spiral,
send_max => gauge,
send_cnt => spiral,
send_pend => spiral}.
-spec gauges([mongoose_instrument:metric_name()]) -> mongoose_instrument:metrics().
gauges(Keys) ->
maps:from_keys(Keys, gauge).
14 changes: 14 additions & 0 deletions test/mongoose_instrument_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ api_test_cases() ->
set_up_and_span_with_error,
span_fails_when_not_set_up,
set_up_probe,
set_up_probe_with_incorrect_metric_type,
set_up_failing_probe,
set_up_and_tear_down_probe,
unexpected_events,
Expand Down Expand Up @@ -224,6 +225,19 @@ set_up_probe(Config) ->
fun(L) -> length(L) > 1 end),
?assertEqual([ExpectedEvent, ExpectedEvent], History2).

set_up_probe_with_incorrect_metric_type(Config) ->
Event = ?config(event, Config),
Cfg = #{metrics => #{test_metric => gauge},
probe => #{module => ?MODULE, interval => 1}},
Cfg1 = #{metrics => ImproperMetrics = #{test_metric => spiral},
probe => #{module => ?MODULE, interval => 1}},
Specs = [{Event, #{key => value1}, Cfg},
{Event, #{key => value2}, Cfg1}],
?assertError(#{what := non_gauge_metrics_in_probe, improper_metrics := ImproperMetrics},
mongoose_instrument:set_up(Event, ?LABELS, Cfg1)),
?assertError(#{what := non_gauge_metrics_in_probe, improper_metrics := ImproperMetrics},
mongoose_instrument:set_up(Specs)).

set_up_failing_probe(Config) ->
Event = ?config(event, Config),
Labels = ?LABELS,
Expand Down

0 comments on commit 7a5650d

Please sign in to comment.