changedCHANGELOG.md
@@ -5,6 +5,12 @@ 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 | +## [1.2.0](https://github.com/elixir-telemetry/telemetry/tree/v1.2.0) |
9 | + |
10 | +### Added |
11 | + |
12 | +- Added `telemetry_test` module for testing telemetry events. (#118) |
13 | + |
8 14 | ## [1.1.0](https://github.com/elixir-telemetry/telemetry/tree/v1.1.0) |
9 15 | |
10 16 | ### Added |
changedREADME.md
@@ -12,7 +12,7 @@ custom handlers. | |
12 12 | > Note: this library is agnostic to tooling and therefore is not directly related to |
13 13 | > OpenTelemetry. For OpenTelemetry in the Erlang VM, see |
14 14 | > [opentelemetry-erlang](https://github.com/open-telemetry/opentelemetry-erlang), and check |
15 | -> [opentelemetry_telemetry](https://github.com/opentelemetry-beam/opentelemetry_telemetry) |
15 | +> [opentelemetry_telemetry](https://github.com/open-telemetry/opentelemetry-erlang-contrib/tree/main/utilities/opentelemetry_telemetry) |
16 16 | > to connect both libraries. |
17 17 | |
18 18 | ## Usage |
changedhex_metadata.config
@@ -4,12 +4,13 @@ | |
4 4 | <<"Dynamic dispatching library for metrics and instrumentations">>}. |
5 5 | {<<"files">>, |
6 6 | [<<"CHANGELOG.md">>,<<"LICENSE">>,<<"NOTICE">>,<<"README.md">>,<<"mix.exs">>, |
7 | - <<"rebar.config">>,<<"rebar.lock">>,<<"src/telemetry.app.src">>, |
7 | + <<"rebar.config">>,<<"rebar.lock">>,<<"src">>,<<"src/telemetry.app.src">>, |
8 8 | <<"src/telemetry.erl">>,<<"src/telemetry.hrl">>,<<"src/telemetry_app.erl">>, |
9 | - <<"src/telemetry_handler_table.erl">>,<<"src/telemetry_sup.erl">>]}. |
9 | + <<"src/telemetry_handler_table.erl">>,<<"src/telemetry_sup.erl">>, |
10 | + <<"src/telemetry_test.erl">>]}. |
10 11 | {<<"licenses">>,[<<"Apache-2.0">>]}. |
11 12 | {<<"links">>, |
12 13 | [{<<"Github">>,<<"https://github.com/beam-telemetry/telemetry">>}]}. |
13 14 | {<<"name">>,<<"telemetry">>}. |
14 15 | {<<"requirements">>,[]}. |
15 | -{<<"version">>,<<"1.1.0">>}. |
16 | +{<<"version">>,<<"1.2.0">>}. |
changedsrc/telemetry.app.src
@@ -1,6 +1,6 @@ | |
1 1 | {application,telemetry, |
2 2 | [{description,"Dynamic dispatching library for metrics and instrumentations"}, |
3 | - {vsn,"1.1.0"}, |
3 | + {vsn,"1.2.0"}, |
4 4 | {registered,[]}, |
5 5 | {mod,{telemetry_app,[]}}, |
6 6 | {applications,[kernel,stdlib]}, |
changedsrc/telemetry.erl
@@ -193,14 +193,15 @@ execute([_ | _] = EventName, Measurements, Metadata) when is_map(Measurements) a | |
193 193 | %% |
194 194 | %% When providing `StartMetadata' and `StopMetadata', these values will be sent independently to `start' and |
195 195 | %% `stop' events. If an exception occurs, exception metadata will be merged onto the `StartMetadata'. In general, |
196 | -%% `StopMetadata' should only provide values that are additive to `StartMetadata' so that handlers, such as those |
197 | -%% used for metrics, can rely entirely on the `stop' event. |
196 | +%% it is <strong>highly recommended</strong> that `StopMetadata' should include the values from `StartMetadata' |
197 | +%% so that handlers, such as those used for metrics, can rely entirely on the `stop' event. Failure to include |
198 | +%% all of `StartMetadata' in `StopMetadata' can add significant complexity to event handlers. |
198 199 | %% |
199 200 | %% A default span context is added to event metadata under the `telemetry_span_context' key if none is provided by |
200 201 | %% the user in the `StartMetadata'. This context is useful for tracing libraries to identify unique |
201 | -%% executions of span events within a process to match start, stop, and exception events. Users |
202 | -%% should ensure this value is unique within the context of a process at a minimum if overriding this key and |
203 | -%% that the same value is provided to both `StartMetadata' and `StopMetadata'. |
202 | +%% executions of span events within a process to match start, stop, and exception events. Metadata keys, which |
203 | +%% should be available to both `start' and `stop' events need to supplied separately for `StartMetadata' and |
204 | +%% `StopMetadata'. |
204 205 | %% |
205 206 | %% For `telemetry' events denoting the <strong>start</strong> of a larger event, the following data is provided: |
206 207 | %% |
addedsrc/telemetry_test.erl
@@ -0,0 +1,59 @@ | |
1 | +%%%------------------------------------------------------------------- |
2 | +%% @doc Functions for testing execution of Telemetry events. |
3 | +%% |
4 | +%% Testing that the correct Telemetry events are emitted with the |
5 | +%% right measurements and metadata is essential for library authors. |
6 | +%% It helps to maintain stable APIs and avoid accidental changes |
7 | +%% to events. |
8 | +%% @end |
9 | +%%%------------------------------------------------------------------- |
10 | + |
11 | +-module(telemetry_test). |
12 | + |
13 | +-export([attach_event_handlers/2]). |
14 | + |
15 | +%% @doc Attaches a "message" handler to the given events. |
16 | +%% |
17 | +%% The attached handler sends a message to `destination_pid` every time it handles one of the |
18 | +%% events in `events`. The function returns a reference that you can use to make sure that |
19 | +%% messages come from this handler. This reference is also used as the handler ID, so you |
20 | +%% can use it to detach the handler with {link telemetry:detach/1}. |
21 | +%% |
22 | +%% The shape of messages sent to `destination_pid` is: |
23 | +%% |
24 | +%% ``` |
25 | +%% {Event, Ref, Measurements, Metadata} |
26 | +%% ''' |
27 | +%% |
28 | +%% For example, in Erlang a test could look like this: |
29 | +%% |
30 | +%% ``` |
31 | +%% Ref = telemetry_test:attach_event_handlers(self(), [[some, event]]), |
32 | +%% function_that_emits_the_event(), |
33 | +%% receive |
34 | +%% {[some, event], Ref, #{measurement := _}, #{meta := _}} -> |
35 | +%% telemetry:detach(Ref) |
36 | +%% after 1000 -> |
37 | +%% ct:fail(timeout_receive_attach_event_handlers) |
38 | +%% end. |
39 | +%% ''' |
40 | +%% |
41 | +%% In Elixir, a similar test would look like this: |
42 | +%% |
43 | +%% ``` |
44 | +%% ref = :telemetry_test.attach_event_handlers(self(), [[:some, :event]]) |
45 | +%% function_that_emits_the_event() |
46 | +%% assert_received {[:some, :event], ^ref, %{measurement: _}, %{meta: _}} |
47 | +%% ''' |
48 | +%% |
49 | +-spec attach_event_handlers(DestinationPID, Events) -> reference() when |
50 | + DestinationPID :: pid(), |
51 | + Events :: [telemetry:event_name(), ...]. |
52 | +attach_event_handlers(DestPID, Events) when is_pid(DestPID) and is_list(Events) -> |
53 | + Ref = make_ref(), |
54 | + Config = #{dest_pid => DestPID, ref => Ref}, |
55 | + telemetry:attach_many(Ref, Events, fun handle_event/4, Config), |
56 | + Ref. |
57 | + |
58 | +handle_event(Event, Measurements, Metadata, #{dest_pid := DestPID, ref := Ref}) -> |
59 | + DestPID ! {Event, Ref, Measurements, Metadata}. |