Skip to content

Commit d76e96d

Browse files
committed
Add customizable duration_unit to plugins
1 parent d769563 commit d76e96d

11 files changed

Lines changed: 190 additions & 98 deletions

File tree

lib/prom_ex/plugins/absinthe.ex

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ if Code.ensure_loaded?(Absinthe) do
2020
in your `dashboard_assigns` to the snakecase version of your prefix, the default
2121
`absinthe_metric_prefix` is `{otp_app}_prom_ex_absinthe`.
2222
23+
- `duration_unit`: This is an OPTIONAL option and is a `Telemetry.Metrics.time_unit()`. It can be one of:
24+
`:second | :millisecond | :microsecond | :nanosecond`. It is `:millisecond` by default.
25+
2326
This plugin exposes the following metric groups:
2427
- `:absinthe_execute_event_metrics`
2528
- `:absinthe_subscription_event_metrics`
@@ -50,6 +53,8 @@ if Code.ensure_loaded?(Absinthe) do
5053

5154
use PromEx.Plugin
5255

56+
alias PromEx.Utils
57+
5358
# @operation_execute_start_event [:absinthe, :execute, :operation, :start]
5459
@operation_execute_stop_event [:absinthe, :execute, :operation, :stop]
5560
# @subscription_publish_start_event [:absinthe, :subscription, :publish, :start]
@@ -78,14 +83,17 @@ if Code.ensure_loaded?(Absinthe) do
7883
|> Keyword.get(:ignored_entrypoints, [])
7984
|> MapSet.new()
8085

86+
duration_unit = Keyword.get(opts, :duration_unit, :millisecond)
87+
duration_unit_plural = Utils.make_plural_atom(duration_unit)
88+
8189
event_tags = [:schema, :operation_type, :entrypoint]
8290

8391
Event.build(
8492
:absinthe_subscription_event_metrics,
8593
[
8694
# Capture GraphQL request duration information
8795
distribution(
88-
metric_prefix ++ [:subscription, :duration, :milliseconds],
96+
metric_prefix ++ [:subscription, :duration, duration_unit_plural],
8997
event_name: @subscription_publish_stop_event,
9098
measurement: :duration,
9199
description: "The time it takes for the Absinthe to publish subscription data.",
@@ -94,7 +102,7 @@ if Code.ensure_loaded?(Absinthe) do
94102
],
95103
tag_values: &subscription_stop_tag_values/1,
96104
tags: event_tags,
97-
unit: {:native, :millisecond},
105+
unit: {:native, duration_unit},
98106
drop: entrypoint_in_ignore_set?(ignored_entrypoints)
99107
)
100108
]
@@ -108,14 +116,17 @@ if Code.ensure_loaded?(Absinthe) do
108116
|> Keyword.get(:ignored_entrypoints, [])
109117
|> MapSet.new()
110118

119+
duration_unit = Keyword.get(opts, :duration_unit, :millisecond)
120+
duration_unit_plural = Utils.make_plural_atom(duration_unit)
121+
111122
event_tags = [:schema, :operation_type, :entrypoint]
112123

113124
Event.build(
114125
:absinthe_execute_event_metrics,
115126
[
116127
# Capture GraphQL request duration information
117128
distribution(
118-
metric_prefix ++ [:execute, :duration, :milliseconds],
129+
metric_prefix ++ [:execute, :duration, duration_unit_plural],
119130
event_name: @operation_execute_stop_event,
120131
measurement: :duration,
121132
description: "The time it takes for the Absinthe to complete the operation.",
@@ -124,7 +135,7 @@ if Code.ensure_loaded?(Absinthe) do
124135
],
125136
tag_values: &operation_execute_stop_tag_values/1,
126137
tags: event_tags,
127-
unit: {:native, :millisecond},
138+
unit: {:native, duration_unit},
128139
drop: entrypoint_in_ignore_set?(ignored_entrypoints)
129140
),
130141

lib/prom_ex/plugins/application.ex

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ defmodule PromEx.Plugins.Application do
2424
in your `dashboard_assigns` to the snakecase version of your prefix, the default
2525
`application_metric_prefix` is `{otp_app}_prom_ex_application`.
2626
27+
- `duration_unit`: This is an OPTIONAL option and is a `Telemetry.Metrics.time_unit()`. It can be one of:
28+
`:second | :millisecond | :microsecond | :nanosecond`. It is `:millisecond` by default.
29+
2730
This plugin exposes the following metric groups:
2831
- `:application_versions_manual_metrics`
2932
@@ -119,18 +122,21 @@ defmodule PromEx.Plugins.Application do
119122
otp_app = Keyword.fetch!(opts, :otp_app)
120123
poll_rate = Keyword.get(opts, :poll_rate, 5_000)
121124
metric_prefix = Keyword.get(opts, :metric_prefix, PromEx.metric_prefix(otp_app, :application))
125+
duration_unit = Keyword.get(opts, :duration_unit, :millisecond)
126+
duration_unit_plural = PromEx.Utils.make_plural_atom(duration_unit)
122127

123128
Polling.build(
124129
:application_time_polling_metrics,
125130
poll_rate,
126131
{__MODULE__, :execute_time_metrics, []},
127132
[
128133
last_value(
129-
metric_prefix ++ [:uptime, :milliseconds, :count],
134+
metric_prefix ++ [:uptime, duration_unit_plural, :count],
130135
event_name: [:prom_ex, :plugin, :application, :uptime, :count],
131-
description: "The total number of wall clock milliseconds that have passed since the application started.",
136+
description:
137+
"The total number of wall clock #{duration_unit_plural} that have passed since the application started.",
132138
measurement: :count,
133-
unit: :millisecond
139+
unit: duration_unit
134140
)
135141
]
136142
)

lib/prom_ex/plugins/beam.ex

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ defmodule PromEx.Plugins.Beam do
1414
in your `dashboard_assigns` to the snakecase version of your prefix, the default
1515
`beam_metric_prefix` is `{otp_app}_prom_ex_beam`.
1616
17+
- `duration_unit`: This is an OPTIONAL option and is a `Telemetry.Metrics.time_unit()`. It can be one of:
18+
`:second | :millisecond | :microsecond | :nanosecond`. It is `:millisecond` by default.
19+
1720
This plugin exposes the following metric groups:
1821
- `:beam_memory_polling_metrics`
1922
- `:beam_internal_polling_metrics`
@@ -57,6 +60,7 @@ defmodule PromEx.Plugins.Beam do
5760
poll_rate = Keyword.get(opts, :poll_rate, 5_000)
5861
otp_app = Keyword.fetch!(opts, :otp_app)
5962
metric_prefix = Keyword.get(opts, :metric_prefix, PromEx.metric_prefix(otp_app, :beam))
63+
duration_unit = Keyword.get(opts, :duration_unit, :millisecond)
6064

6165
# TODO: Investigate Microstate accounting metrics
6266
# http://erlang.org/doc/man/erlang.html#statistics_microstate_accounting
@@ -69,7 +73,7 @@ defmodule PromEx.Plugins.Beam do
6973
memory_metrics(metric_prefix, poll_rate),
7074
mnesia_metrics(metric_prefix, poll_rate),
7175
distribution_metrics(metric_prefix, poll_rate),
72-
beam_internal_metrics(metric_prefix, poll_rate)
76+
beam_internal_metrics(metric_prefix, poll_rate, duration_unit)
7377
]
7478
end
7579

@@ -104,7 +108,9 @@ defmodule PromEx.Plugins.Beam do
104108
)
105109
end
106110

107-
defp beam_internal_metrics(metric_prefix, poll_rate) do
111+
defp beam_internal_metrics(metric_prefix, poll_rate, duration_unit) do
112+
duration_unit_plural = String.to_atom("#{duration_unit}s")
113+
108114
Polling.build(
109115
:beam_internal_polling_metrics,
110116
poll_rate,
@@ -158,11 +164,12 @@ defmodule PromEx.Plugins.Beam do
158164
unit: :byte
159165
),
160166
last_value(
161-
metric_prefix ++ [:stats, :uptime, :milliseconds, :count],
167+
metric_prefix ++ [:stats, :uptime, duration_unit_plural, :count],
162168
event_name: [:prom_ex, :plugin, :beam, :uptime, :count],
163-
description: "The total number of wall clock milliseconds that have passed since the system started.",
169+
description:
170+
"The total number of wall clock #{duration_unit_plural} that have passed since the system started.",
164171
measurement: :count,
165-
unit: :millisecond
172+
unit: duration_unit
166173
),
167174
last_value(
168175
metric_prefix ++ [:stats, :port, :count],

lib/prom_ex/plugins/broadway.ex

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ if Code.ensure_loaded?(Broadway) do
7777
alias Broadway.{BatchInfo, Options}
7878
alias PromEx.Utils
7979

80-
@millisecond_duration_buckets [10, 100, 500, 1_000, 10_000, 30_000, 60_000]
8180
@message_batch_size_buckets [1, 5, 10, 20, 50, 100]
8281

8382
@init_topology_event [:broadway, :topology, :init]
@@ -92,6 +91,7 @@ if Code.ensure_loaded?(Broadway) do
9291
def event_metrics(opts) do
9392
otp_app = Keyword.fetch!(opts, :otp_app)
9493
metric_prefix = Keyword.get(opts, :metric_prefix, PromEx.metric_prefix(otp_app, :broadway))
94+
duration_unit = Keyword.get(opts, :duration_unit, :millisecond)
9595

9696
# Telemetry metrics will emit warnings if multiple handlers with the same names are defined.
9797
# As a result, this plugin supports gathering metrics on multiple processors and batches, but needs
@@ -102,13 +102,15 @@ if Code.ensure_loaded?(Broadway) do
102102

103103
# Event metrics definitions
104104
[
105-
topology_init_events(metric_prefix),
106-
handle_message_events(metric_prefix),
107-
handle_batch_events(metric_prefix)
105+
topology_init_events(metric_prefix, duration_unit),
106+
handle_message_events(metric_prefix, duration_unit),
107+
handle_batch_events(metric_prefix, duration_unit)
108108
]
109109
end
110110

111-
defp topology_init_events(metric_prefix) do
111+
defp topology_init_events(metric_prefix, duration_unit) do
112+
duration_unit_plural = Utils.make_plural_atom(duration_unit)
113+
112114
Event.build(
113115
:broadway_init_event_metrics,
114116
[
@@ -121,29 +123,29 @@ if Code.ensure_loaded?(Broadway) do
121123
tag_values: &extract_init_tag_values/1
122124
),
123125
last_value(
124-
metric_prefix ++ [:init, :hibernate_after, :default, :milliseconds],
126+
metric_prefix ++ [:init, :hibernate_after, :default, duration_unit_plural],
125127
event_name: @init_topology_event,
126128
description: "The Broadway supervisor's hibernate after default value.",
127129
measurement: extract_default_config_measurement(:hibernate_after),
128130
tags: [:name],
129131
tag_values: &extract_init_tag_values/1
130132
),
131133
last_value(
132-
metric_prefix ++ [:init, :resubscribe_interval, :default, :milliseconds],
134+
metric_prefix ++ [:init, :resubscribe_interval, :default, duration_unit_plural],
133135
event_name: @init_topology_event,
134136
description: "The Broadway supervisor's resubscribe interval default value.",
135137
measurement: extract_default_config_measurement(:resubscribe_interval),
136138
tags: [:name],
137139
tag_values: &extract_init_tag_values/1
138140
),
139141
last_value(
140-
metric_prefix ++ [:init, :max, :duration, :default, :milliseconds],
142+
metric_prefix ++ [:init, :max, :duration, :default, duration_unit_plural],
141143
event_name: @init_topology_event,
142-
description: "The Broadway supervisor's max seconds default value (in milliseconds).",
144+
description: "The Broadway supervisor's max seconds default value (in #{duration_unit_plural}).",
143145
measurement: extract_default_config_measurement(:max_seconds),
144146
tags: [:name],
145147
tag_values: &extract_init_tag_values/1,
146-
unit: {:second, :millisecond}
148+
unit: {:second, duration_unit}
147149
),
148150
last_value(
149151
metric_prefix ++ [:init, :max_restarts, :default, :value],
@@ -154,15 +156,15 @@ if Code.ensure_loaded?(Broadway) do
154156
tag_values: &extract_init_tag_values/1
155157
),
156158
last_value(
157-
metric_prefix ++ [:init, :shutdown, :default, :milliseconds],
159+
metric_prefix ++ [:init, :shutdown, :default, duration_unit_plural],
158160
event_name: @init_topology_event,
159161
description: "The Broadway supervisor's shutdown default value.",
160162
measurement: extract_default_config_measurement(:shutdown),
161163
tags: [:name],
162164
tag_values: &extract_init_tag_values/1
163165
),
164166
last_value(
165-
metric_prefix ++ [:init, :processor, :hibernate_after, :milliseconds],
167+
metric_prefix ++ [:init, :processor, :hibernate_after, duration_unit_plural],
166168
event_name: @init_topology_processors_proxy_event,
167169
description: "The Broadway processors hibernate after value.",
168170
measurement: fn _measurements, %{hibernate_after: hibernate_after} -> hibernate_after end,
@@ -183,7 +185,7 @@ if Code.ensure_loaded?(Broadway) do
183185
tags: [:name, :processor]
184186
),
185187
last_value(
186-
metric_prefix ++ [:init, :batcher, :hibernate_after, :milliseconds],
188+
metric_prefix ++ [:init, :batcher, :hibernate_after, duration_unit_plural],
187189
event_name: @init_topology_batchers_proxy_event,
188190
description: "The Broadway batchers hibernate after value.",
189191
measurement: fn _measurements, %{hibernate_after: hibernate_after} -> hibernate_after end,
@@ -204,7 +206,7 @@ if Code.ensure_loaded?(Broadway) do
204206
tags: [:name, :batcher]
205207
),
206208
last_value(
207-
metric_prefix ++ [:init, :batcher, :batch_timeout, :milliseconds],
209+
metric_prefix ++ [:init, :batcher, :batch_timeout, duration_unit_plural],
208210
event_name: @init_topology_batchers_proxy_event,
209211
description: "The Broadway batchers timeout value.",
210212
measurement: fn _measurements, %{batch_timeout: batch_timeout} -> batch_timeout end,
@@ -267,53 +269,57 @@ if Code.ensure_loaded?(Broadway) do
267269
end
268270
end
269271

270-
defp handle_message_events(metric_prefix) do
272+
defp handle_message_events(metric_prefix, duration_unit) do
273+
duration_unit_plural = Utils.make_plural_atom(duration_unit)
274+
271275
Event.build(
272276
:broadway_message_event_metrics,
273277
[
274278
distribution(
275-
metric_prefix ++ [:process, :message, :duration, :milliseconds],
279+
metric_prefix ++ [:process, :message, :duration, duration_unit_plural],
276280
event_name: @message_stop_event,
277281
measurement: :duration,
278282
description: "The time it takes Broadway to process a message.",
279283
reporter_options: [
280-
buckets: @millisecond_duration_buckets
284+
buckets: buckets_for_unit(duration_unit)
281285
],
282286
tags: [:processor_key, :name],
283287
tag_values: &extract_message_tag_values/1,
284-
unit: {:native, :millisecond}
288+
unit: {:native, duration_unit}
285289
),
286290
distribution(
287-
metric_prefix ++ [:process, :message, :exception, :duration, :milliseconds],
291+
metric_prefix ++ [:process, :message, :exception, :duration, duration_unit_plural],
288292
event_name: @message_exception_event,
289293
measurement: :duration,
290294
description: "The time it takes Broadway to process a message that results in an error.",
291295
reporter_options: [
292-
buckets: @millisecond_duration_buckets
296+
buckets: buckets_for_unit(duration_unit)
293297
],
294298
tags: [:processor_key, :name, :kind, :reason],
295299
tag_values: &extract_exception_tag_values/1,
296-
unit: {:native, :millisecond}
300+
unit: {:native, duration_unit}
297301
)
298302
]
299303
)
300304
end
301305

302-
defp handle_batch_events(metric_prefix) do
306+
defp handle_batch_events(metric_prefix, duration_unit) do
307+
duration_unit_plural = Utils.make_plural_atom(duration_unit)
308+
303309
Event.build(
304310
:broadway_batch_event_metrics,
305311
[
306312
distribution(
307-
metric_prefix ++ [:process, :batch, :duration, :milliseconds],
313+
metric_prefix ++ [:process, :batch, :duration, duration_unit_plural],
308314
event_name: @batch_stop_event,
309315
measurement: :duration,
310316
description: "The time it takes Broadway to process a batch of messages.",
311317
reporter_options: [
312-
buckets: @millisecond_duration_buckets
318+
buckets: buckets_for_unit(duration_unit)
313319
],
314320
tags: [:batcher, :name],
315321
tag_values: &extract_batcher_tag_values/1,
316-
unit: {:native, :millisecond}
322+
unit: {:native, duration_unit}
317323
),
318324
distribution(
319325
metric_prefix ++ [:process, :batch, :failure, :size],
@@ -387,6 +393,15 @@ if Code.ensure_loaded?(Broadway) do
387393
name: Utils.normalize_module_name(name)
388394
}
389395
end
396+
397+
defp buckets_for_unit(unit) do
398+
case unit do
399+
:nanosecond -> [1, 100, 1_000, 2_000, 10_000, 50_000, 1_000_000]
400+
:microsecond -> [10_000, 100_000, 500_000, 1_000_000, 10_000_000, 30_000_000, 60_000_000]
401+
:millisecond -> [10, 100, 500, 1_000, 10_000, 30_000, 60_000]
402+
:second -> [1, 5, 10, 100, 500, 1_000, 10_000]
403+
end
404+
end
390405
end
391406
else
392407
defmodule PromEx.Plugins.Broadway do

0 commit comments

Comments
 (0)