Current section

11 Versions

Jump to

Compare versions

6 files changed
+78 additions
-160 deletions
  @@ -5,35 +5,63 @@ All notable changes to this project will be documented in this file.
5 5 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 6 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 7
8 + ## [0.3.0](https://github.com/beam-telemetry/telemetry_poller/tree/v0.3.0)
9 +
10 + This release marks the upgrade to Telemetry 0.4.0. This means that Poller measurements can emit a map
11 + of values now instead of a single one, making it less "noisy" when it comes to number of emitted events.
12 +
13 + All specific memory measurements have been replaced with a single `:memory` measurement sending all
14 + the values that were emitted by old measurements at once.
15 +
16 + `:run_queue_lengths` VM measurement has been removed for now, as we believe that as detailed data
17 + as it provided is not necessary to effectively debug the system. `:total_run_queue_lengths` VM
18 + measurement has been changed so that it reports a `:total` length of run queues, length of `:cpu`
19 + run queues (including dirty CPU run queue), and length of (dirty) `:io` run queue.
20 +
21 + ### Added
22 +
23 + - `:memory` VM measurement reporting all the data returned by `:erlang.memory/0` call.
24 +
25 + ### Changed
26 +
27 + - `:total_run_queue_lengths` VM measurement is reporting a `:total`, `:cpu` and `:io` run queue lengths
28 + now. See documentation for more details.
29 +
30 + ### Removed
31 +
32 + - `:total_memory`, `:atom_memory`, `:atom_used_memory`, `:processes_memory`, `:processes_used_memory`,
33 + `:binary_memory`, `:ets_memory`, `:code_memory` and `:system_memory` VM measurements have been removed.
34 + Please use the `:memory` measurement now instead.
35 +
8 36 ## [0.2.0](https://github.com/beam-telemetry/telemetry_poller/tree/v0.2.0)
9 37
10 38 ### Added
11 39
12 - * Added `:total_run_queue_lengths` and `:run_queue_lengths` memory measurements;
40 + - Added `:total_run_queue_lengths` and `:run_queue_lengths` memory measurements;
13 41
14 42 ### Changed
15 43
16 - * `:total_run_queue_lengths` is now included in the set of default VM measurements;
17 - * A default Poller process, with a default set of VM measurements, is started when `:telemetry_poller`
44 + - `:total_run_queue_lengths` is now included in the set of default VM measurements;
45 + - A default Poller process, with a default set of VM measurements, is started when `:telemetry_poller`
18 46 application starts (configurable via `:telemetry.poller, :default` application environment).
19 - * VM measurements are now provided to Poller's `:vm_measurements` option. Passing atom `:default`
47 + - VM measurements are now provided to Poller's `:vm_measurements` option. Passing atom `:default`
20 48 to this option makes the Poller use a default set of VM measurements;
21 - * Telemetry has been upgraded to version 0.3, meaning that VM measurements now use this version to
49 + - Telemetry has been upgraded to version 0.3, meaning that VM measurements now use this version to
22 50 emit the events.
23 51
24 52 ### Removed
25 53
26 - * `Telemetry.Poller.vm_measurements/0` function has been removed in favor of `:vm_measurements`
54 + - `Telemetry.Poller.vm_measurements/0` function has been removed in favor of `:vm_measurements`
27 55 option.
28 56
29 57 ### Fixed
30 58
31 - * Fixed the type definition of `Telemetry.Poller.measurement/0` type - no Dialyzer warnings are
59 + - Fixed the type definition of `Telemetry.Poller.measurement/0` type - no Dialyzer warnings are
32 60 emitted when running it on the project.
33 61
34 62 ## [0.1.0](https://github.com/beam-telemetry/telemetry_poller/tree/v0.1.0)
35 63
36 64 ### Added
37 65
38 - * The Poller process periodically invoking registered functions which emit Telemetry events.
39 - It supports VM memory measurements and custom measurements provided as MFAs.
\ No newline at end of file
66 + - The Poller process periodically invoking registered functions which emit Telemetry events.
67 + It supports VM memory measurements and custom measurements provided as MFAs.
  @@ -9,7 +9,7 @@ Allows to periodically collect measurements and dispatch them as Telemetry event
9 9
10 10 ```elixir
11 11 config :telemetry_poller, :default,
12 - vm_measurements: :default # or a list such as [:total_memory, :binary_memory, ...]
12 + vm_measurements: :default # or a list such as [:memory, ...]
13 13 ```
14 14
15 15 Poller also provides a convenient API for specifying functions called periodically to dispatch
  @@ -32,7 +32,7 @@ Telemetry.Poller.start_link(
32 32 )
33 33 ```
34 34
35 - See [documentation](https://hexdocs.pm/telemetry_poller/0.2.0) for more concrete examples and usage
35 + See [documentation](https://hexdocs.pm/telemetry_poller/0.3.0) for more concrete examples and usage
36 36 instructions.
37 37
38 38 ## Copyright and License
  @@ -4,8 +4,8 @@
4 4 <<"Allows to periodically collect measurements and dispatch them as Telemetry events">>}.
5 5 {<<"elixir">>,<<"~> 1.5">>}.
6 6 {<<"files">>,
7 - [<<"lib">>,<<"lib/telemetry_poller">>,<<"lib/telemetry_poller.ex">>,
8 - <<"lib/telemetry_poller/application.ex">>,<<"lib/telemetry_poller/vm.ex">>,
7 + [<<"lib">>,<<"lib/telemetry_poller.ex">>,<<"lib/telemetry_poller">>,
8 + <<"lib/telemetry_poller/vm.ex">>,<<"lib/telemetry_poller/application.ex">>,
9 9 <<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>,<<"LICENSE">>,
10 10 <<"CHANGELOG.md">>]}.
11 11 {<<"licenses">>,[<<"Apache 2.0">>]}.
  @@ -17,5 +17,5 @@
17 17 {<<"name">>,<<"telemetry">>},
18 18 {<<"optional">>,false},
19 19 {<<"repository">>,<<"hexpm">>},
20 - {<<"requirement">>,<<"~> 0.3">>}]]}.
21 - {<<"version">>,<<"0.2.0">>}.
20 + {<<"requirement">>,<<"~> 0.4">>}]]}.
21 + {<<"version">>,<<"0.3.0">>}.
  @@ -12,7 +12,7 @@ defmodule Telemetry.Poller do
12 12 But you may specify all VM measurements you want:
13 13
14 14 config :telemetry_poller, :default,
15 - vm_measurements: [:total_memory, :binary_memory, :total_run_queue_lengths]
15 + vm_measurements: [:memory] # measure only the memory
16 16
17 17 Measurements are MFAs called periodically by the poller process.
18 18 You can disable the default poller by setting it to `false`:
  @@ -45,29 +45,9 @@ defmodule Telemetry.Poller do
45 45
46 46 ### Memory
47 47
48 - See documentation for `:erlang.memory/0` function for more information about
49 - each type of memory measured.
50 -
51 - * `:total_memory` - dispatches an event with total amount of currently allocated memory, in bytes.
52 - Event name is `[:vm, :memory, :total]` and event metadata is empty;
53 - * `:processes_memory` - dispatches an event with amount of memory cyrrently allocated for
54 - processes, in bytes. Event name is `[:vm, :memory, :processes]` and event metadata is empty;
55 - * `:processes_used_memory` - dispatches an event with amount of memory currently used for
56 - processes, in bytes. Event name is `[:vm, :memory, :processes_used]` and event metadata is empty.
57 - Memory measured is a fraction of value collected by `:processes_memory` measurement;
58 - * `:binary_memory` - dispatches an event with amount of memory currently allocated for binaries.
59 - Event name is `[:vm, :memory, :binary]` and event metadata is empty;
60 - * `:ets_memory` - dispatches an event with amount of memory currently allocated for ETS tables.
61 - Event name is `[:vm, :memory, :ets]` and event metadata is empty;
62 - * `:system_memory` - dispatches an event with amount of currently allocated memory not directly
63 - related to any process running in the VM, in bytes. Event name is `[:vm, :memory, :system]` and
64 - event metadata is empty;
65 - * `:atom_memory` - dispatches an event with amount of memory currently allocated for atoms. Event
66 - name is `[:vm, :memory, :atom]` and event metadata is empty;
67 - * `:atom_used_memory` - dispatches an event with amount of memory currently used for atoms. Event
68 - name is `[:vm, :memory, :atom_used]` and event metadata is empty;
69 - * `:code_memory` - dispatches an event with amount of memory currently allocated for code. Event
70 - name is `[:vm, :memory, :code]` and event metadata is empty;
48 + There is only one measurement related to memory - `:memory`. The emitted event includes all the
49 + key-value pairs returned by `:erlang.memory/0` function, e.g. `:total` for total memory,
50 + `:processes_used` for memory used by all processes etc.
71 51
72 52 ### Run queue lengths
73 53
  @@ -83,40 +63,26 @@ defmodule Telemetry.Poller do
83 63
84 64 The following VM measurements related to run queue lengths are available:
85 65
86 - * `:total_run_queue_lengths` - dispatches an event with a sum of normal schedulers' run queue lengths
87 - and a dirty CPU run queue length (if dirty schedulers are available). Event name is
88 - `[:vm, run_queue_lengths, :total]` and event metadata is empty.
66 + * `:total_run_queue_lengths` - dispatches an event with a sum of schedulers' run queue lengths. The
67 + event name is `[:vm, :total_run_queue_lengths]`, event metadata is empty and it includes three
68 + measurements:
69 + * `:total` - a sum of all run queue lengths;
70 + * `:cpu` - a sum of CPU schedulers' run queue lengths, including dirty CPU run queue length
71 + on Erlang >= 20.0;
72 + * `:io` - length of dirty IO run queue. It's always 0 if running on Erlang < 20.0.
73 +
89 74
90 75 Note that the method of making this measurement varies between different Erlang versions: for
91 76 Erlang 18 and 19, the implementation is less efficient than for version 20 and up.
92 77
93 78 The length of all queues is not gathered atomically, so the event value does not represent
94 79 a consistent snapshot of the run queues' state. However, the value is accurate enough to help
95 - to indentify issues in a running system.
96 -
97 - * `:run_queue_lengths` - dispatches events with individual normal run queue lengths and a dirty
98 - CPU run queue length (if dirty schedulers are available).
99 -
100 - For normal run queues, event name is `[:vm, run_queue_lengths, :normal]` and event metadata
101 - includes a single key, `:scheduler_id`, with the scheduler ID of the queue. Note that number
102 - of schedulers is fixed at virtual machine boot time, so the number of events emitted on each
103 - measurement is constant.
104 -
105 - For dirty CPU run queue, the event name is `[:vm, :run_queue_lengths, :dirty_cpu]` and the
106 - event metadata is empty.
107 -
108 - The length of all queues is not gathered atomically, so the event values do not represent
109 - a consistent snapshot of the run queues' state. However, the value is accurate enough to help
110 - to indentify issues in a running system.
111 -
112 - If you do not need the individual run queue lengths, it is more efficient to use
113 - `:total_run_queue_lengths` measurement.
80 + to identify issues in a running system.
114 81
115 82 ### Default measurements
116 83
117 - When `:default` is provided as the value of `:vm_measurement` options, Poller uses
118 - `:total_memory`, `:processes_memory`, `:processes_used_memory`, `:binary_memory`,
119 - `:ets_memory` and `:total_run_queue_lengths` VM measurements.
84 + When `:default` is provided as the value of `:vm_measurement` options, Poller uses `:memory` and
85 + `:total_run_queue_lengths` VM measurements.
120 86
121 87 ## Example - measuring message queue length of the process
122 88
  @@ -272,25 +238,12 @@ defmodule Telemetry.Poller do
272 238
273 239 @default_period 10_000
274 240 @default_vm_measurements [
275 - :total_memory,
276 - :processes_memory,
277 - :processes_used_memory,
278 - :binary_memory,
279 - :ets_memory,
241 + :memory,
280 242 :total_run_queue_lengths
281 243 ]
282 244 @vm_measurements [
283 - :total_memory,
284 - :processes_memory,
285 - :processes_used_memory,
286 - :system_memory,
287 - :atom_memory,
288 - :atom_used_memory,
289 - :binary_memory,
290 - :code_memory,
291 - :ets_memory,
292 - :total_run_queue_lengths,
293 - :run_queue_lengths
245 + :memory,
246 + :total_run_queue_lengths
294 247 ]
295 248
296 249 @type t :: GenServer.server()
  @@ -303,17 +256,8 @@ defmodule Telemetry.Poller do
303 256 @type period :: pos_integer()
304 257 @type measurement() :: {module(), function :: atom(), args :: list()}
305 258 @type vm_measurement() ::
306 - :total_memory
307 - | :processes_memory
308 - | :processes_used_memory
309 - | :system_memory
310 - | :atom_memory
311 - | :atom_used_memory
312 - | :binary_memory
313 - | :code_memory
314 - | :ets_memory
259 + :memory
315 260 | :total_run_queue_lengths
316 - | :run_queue_lengths
317 261
318 262 ## API
  @@ -1,49 +1,10 @@
1 1 defmodule Telemetry.Poller.VM do
2 2 @moduledoc false
3 3
4 - @spec total_memory() :: :ok
5 - def total_memory() do
6 - :telemetry.execute([:vm, :memory, :total], :erlang.memory(:total))
7 - end
8 -
9 - @spec processes_memory() :: :ok
10 - def processes_memory() do
11 - :telemetry.execute([:vm, :memory, :processes], :erlang.memory(:processes))
12 - end
13 -
14 - @spec processes_used_memory() :: :ok
15 - def processes_used_memory() do
16 - :telemetry.execute([:vm, :memory, :processes_used], :erlang.memory(:processes_used))
17 - end
18 -
19 - @spec system_memory() :: :ok
20 - def system_memory() do
21 - :telemetry.execute([:vm, :memory, :system], :erlang.memory(:system))
22 - end
23 -
24 - @spec atom_memory() :: :ok
25 - def atom_memory() do
26 - :telemetry.execute([:vm, :memory, :atom], :erlang.memory(:atom))
27 - end
28 -
29 - @spec atom_used_memory() :: :ok
30 - def atom_used_memory() do
31 - :telemetry.execute([:vm, :memory, :atom_used], :erlang.memory(:atom_used))
32 - end
33 -
34 - @spec binary_memory() :: :ok
35 - def binary_memory() do
36 - :telemetry.execute([:vm, :memory, :binary], :erlang.memory(:binary))
37 - end
38 -
39 - @spec code_memory() :: :ok
40 - def code_memory() do
41 - :telemetry.execute([:vm, :memory, :code], :erlang.memory(:code))
42 - end
43 -
44 - @spec ets_memory() :: :ok
45 - def ets_memory() do
46 - :telemetry.execute([:vm, :memory, :ets], :erlang.memory(:ets))
4 + @spec memory() :: :ok
5 + def memory() do
6 + measurements = :erlang.memory() |> Map.new()
7 + :telemetry.execute([:vm, :memory], measurements)
47 8 end
48 9
49 10 @spec total_run_queue_lengths() :: :ok
  @@ -53,37 +14,22 @@ defmodule Telemetry.Poller.VM do
53 14 total =
54 15 if otp_release < 20 do
55 16 Enum.sum(:erlang.statistics(:run_queue_lengths))
17 + else
18 + :erlang.statistics(:total_run_queue_lengths_all)
19 + end
20 +
21 + cpu =
22 + if otp_release < 20 do
23 + # Before OTP 20.0 there were only normal run queues.
24 + total
56 25 else
57 26 :erlang.statistics(:total_run_queue_lengths)
58 27 end
59 28
60 29 :telemetry.execute(
61 - [:vm, :run_queue_lengths, :total],
62 - total,
30 + [:vm, :total_run_queue_lengths],
31 + %{total: total, cpu: cpu, io: total - cpu},
63 32 %{}
64 33 )
65 34 end
66 -
67 - @spec run_queue_lengths() :: :ok
68 - def run_queue_lengths() do
69 - individual_lengths = :erlang.statistics(:run_queue_lengths)
70 - normal_schedulers_count = :erlang.system_info(:schedulers)
71 -
72 - {normal_run_queue_lengths, dirty_run_queue_lengths} =
73 - Enum.split(individual_lengths, normal_schedulers_count)
74 -
75 - for {run_queue_length, scheduler_id} <- Enum.with_index(normal_run_queue_lengths, 1) do
76 - :telemetry.execute([:vm, :run_queue_lengths, :normal], run_queue_length, %{
77 - scheduler_id: scheduler_id
78 - })
79 - end
80 -
81 - case dirty_run_queue_lengths do
82 - [dirty_cpu_run_queue_length] ->
83 - :telemetry.execute([:vm, :run_queue_lengths, :dirty_cpu], dirty_cpu_run_queue_length)
84 -
85 - _ ->
86 - :ok
87 - end
88 - end
89 35 end
Loading more files…