Skip to content

Commit ff156a7

Browse files
committed
Move the event emitting functions to the telemetry module.
1 parent 84f9240 commit ff156a7

File tree

3 files changed

+104
-48
lines changed

3 files changed

+104
-48
lines changed

lib/fun_with_flags/store.ex

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule FunWithFlags.Store do
33

44
require Logger
55
alias FunWithFlags.Store.Cache
6-
alias FunWithFlags.{Config, Flag}
6+
alias FunWithFlags.{Config, Flag, Telemetry}
77

88
import FunWithFlags.Config, only: [persistence_adapter: 0]
99

@@ -15,11 +15,11 @@ defmodule FunWithFlags.Store do
1515
{:miss, reason, stale_value_or_nil} ->
1616
case persistence_adapter().get(flag_name) do
1717
{:ok, flag} ->
18-
emit_persistence_telemetry({:ok, nil}, :read, flag_name, nil)
18+
Telemetry.emit_persistence_event({:ok, nil}, :read, flag_name, nil)
1919
Cache.put(flag)
2020
{:ok, flag}
2121
err = {:error, _reason} ->
22-
emit_persistence_telemetry(err, :read, flag_name, nil)
22+
Telemetry.emit_persistence_event(err, :read, flag_name, nil)
2323
try_to_use_the_cached_value(reason, stale_value_or_nil, flag_name)
2424
end
2525
end
@@ -39,7 +39,7 @@ defmodule FunWithFlags.Store do
3939
def put(flag_name, gate) do
4040
flag_name
4141
|> persistence_adapter().put(gate)
42-
|> emit_persistence_telemetry(:write, flag_name, gate)
42+
|> Telemetry.emit_persistence_event(:write, flag_name, gate)
4343
|> publish_change()
4444
|> cache_persistence_result()
4545
end
@@ -49,7 +49,7 @@ defmodule FunWithFlags.Store do
4949
def delete(flag_name, gate) do
5050
flag_name
5151
|> persistence_adapter().delete(gate)
52-
|> emit_persistence_telemetry(:delete_gate, flag_name, gate)
52+
|> Telemetry.emit_persistence_event(:delete_gate, flag_name, gate)
5353
|> publish_change()
5454
|> cache_persistence_result()
5555
end
@@ -59,7 +59,7 @@ defmodule FunWithFlags.Store do
5959
def delete(flag_name) do
6060
flag_name
6161
|> persistence_adapter().delete()
62-
|> emit_persistence_telemetry(:delete_flag, flag_name, nil)
62+
|> Telemetry.emit_persistence_event(:delete_flag, flag_name, nil)
6363
|> publish_change()
6464
|> cache_persistence_result()
6565
end
@@ -70,22 +70,22 @@ defmodule FunWithFlags.Store do
7070
Logger.debug fn -> "FunWithFlags: reloading cached flag '#{flag_name}' from storage " end
7171
flag_name
7272
|> persistence_adapter().get()
73-
|> emit_persistence_telemetry(:reload, flag_name, nil)
73+
|> Telemetry.emit_persistence_event(:reload, flag_name, nil)
7474
|> cache_persistence_result()
7575
end
7676

7777

7878
@spec all_flags() :: {:ok, [FunWithFlags.Flag.t]} | {:error, any()}
7979
def all_flags do
8080
persistence_adapter().all_flags()
81-
|> emit_persistence_telemetry(:read_all_flags, nil, nil)
81+
|> Telemetry.emit_persistence_event(:read_all_flags, nil, nil)
8282
end
8383

8484

8585
@spec all_flag_names() :: {:ok, [atom]} | {:error, any()}
8686
def all_flag_names do
8787
persistence_adapter().all_flag_names()
88-
|> emit_persistence_telemetry(:read_all_flag_names, nil, nil)
88+
|> Telemetry.emit_persistence_event(:read_all_flag_names, nil, nil)
8989
end
9090

9191
defp cache_persistence_result(result = {:ok, flag}) do
@@ -109,30 +109,4 @@ defmodule FunWithFlags.Store do
109109
defp publish_change(result) do
110110
result
111111
end
112-
113-
# Receive the flag name as an explicit parameter rather than pattern matching
114-
# it from the `{:ok, %Flag{}}`, because that tuple is only available on success,
115-
# and it's therefore not available when pipelining on an error.
116-
#
117-
defp emit_persistence_telemetry(result = {:ok, _}, event_name, flag_name, gate) do
118-
metadata = %{
119-
flag_name: flag_name,
120-
gate: gate,
121-
}
122-
123-
FunWithFlags.Telemetry.persistence_event(event_name, metadata)
124-
result
125-
end
126-
127-
defp emit_persistence_telemetry(result = {:error, reason}, event_name, flag_name, gate) do
128-
metadata = %{
129-
flag_name: flag_name,
130-
gate: gate,
131-
error: reason,
132-
original_event: event_name
133-
}
134-
135-
FunWithFlags.Telemetry.persistence_event(:error, metadata)
136-
result
137-
end
138112
end

lib/fun_with_flags/telemetry.ex

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,49 @@ defmodule FunWithFlags.Telemetry do
2222

2323
require Logger
2424

25+
@typedoc false
26+
@type pipelining_value :: {:ok, any()} | {:error, any()}
27+
28+
# Receive the flag name as an explicit parameter rather than pattern matching
29+
# it from the `{:ok, _}` tuple, because:
30+
#
31+
# * That tuple is only available on success, and it's therefore not available
32+
# when pipelining on an error.
33+
# * It makes it possible to use this function even when the :ok result does
34+
# not contain a flag.
35+
#
2536
@doc false
26-
@spec persistence_event(atom, :telemetry.event_metadata()) :: :ok
27-
def persistence_event(event_name, metadata) do
37+
@spec emit_persistence_event(
38+
pipelining_value(),
39+
event_name :: atom(),
40+
flag_name :: (atom() | nil),
41+
gate :: (FunWithFlags.Gate.t | nil)
42+
) :: pipelining_value()
43+
def emit_persistence_event(result = {:ok, _}, event_name, flag_name, gate) do
44+
metadata = %{
45+
flag_name: flag_name,
46+
gate: gate,
47+
}
48+
49+
do_send_event([:fun_with_flags, :persistence, event_name], metadata)
50+
result
51+
end
52+
53+
def emit_persistence_event(result = {:error, reason}, event_name, flag_name, gate) do
54+
metadata = %{
55+
flag_name: flag_name,
56+
gate: gate,
57+
error: reason,
58+
original_event: event_name
59+
}
60+
61+
do_send_event([:fun_with_flags, :persistence, :error], metadata)
62+
result
63+
end
64+
65+
@doc false
66+
@spec do_send_event([atom], :telemetry.event_metadata()) :: :ok
67+
def do_send_event(event_name, metadata) do
2868
measurements = %{
2969
system_time: :erlang.system_time()
3070
}
@@ -33,11 +73,6 @@ defmodule FunWithFlags.Telemetry do
3373
"Telemetry event: #{event_name}, metadata: #{inspect(metadata)}, measurements: #{inspect(measurements)}"
3474
end)
3575

36-
:telemetry.execute([:fun_with_flags, :persistence, event_name], measurements, metadata)
76+
:telemetry.execute(event_name, measurements, metadata)
3777
end
38-
39-
# @spec as_milliseconds(integer) :: integer
40-
# defp as_milliseconds(time) do
41-
# :erlang.convert_time_unit(time, :native, :millisecond)
42-
# end
4378
end

test/fun_with_flags/telemetry_test.exs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,67 @@ defmodule FunWithFlags.TelemetryTest do
22
use ExUnit.Case, async: true
33

44
alias FunWithFlags.Telemetry, as: FWFTel
5+
alias FunWithFlags.Gate
56

67
@moduletag :telemetry
78

8-
describe "persistence_event()" do
9+
describe "emit_persistence_event()" do
10+
test "with a success tuple" do
11+
result = {:ok, "something"}
12+
event_name = :some_event
13+
flag_name = :some_flag
14+
gate = %Gate{type: :boolean, enabled: true}
15+
16+
ref = :telemetry_test.attach_event_handlers(self(), [[:fun_with_flags, :persistence, event_name]])
17+
18+
assert ^result = FWFTel.emit_persistence_event(result, event_name, flag_name, gate)
19+
20+
assert_received {
21+
[:fun_with_flags, :persistence, ^event_name],
22+
^ref,
23+
%{system_time: time_value},
24+
%{flag_name: ^flag_name, gate: ^gate}
25+
}
26+
27+
assert is_integer(time_value)
28+
29+
:telemetry.detach(ref)
30+
end
31+
32+
test "with an error tuple" do
33+
result = {:error, "some error"}
34+
event_name = :some_event
35+
flag_name = :some_flag
36+
gate = %Gate{type: :boolean, enabled: true}
37+
38+
ref = :telemetry_test.attach_event_handlers(self(), [[:fun_with_flags, :persistence, :error]])
39+
40+
assert ^result = FWFTel.emit_persistence_event(result, event_name, flag_name, gate)
41+
42+
assert_received {
43+
[:fun_with_flags, :persistence, :error],
44+
^ref,
45+
%{system_time: time_value},
46+
%{flag_name: ^flag_name, gate: ^gate, error: "some error", original_event: ^event_name}
47+
}
48+
49+
assert is_integer(time_value)
50+
51+
:telemetry.detach(ref)
52+
end
53+
end
54+
55+
describe "do_send_event()" do
956
test "it emits an event with the right prefix and measures" do
1057
metadata = %{foo: "bar"}
11-
event = :monkey
58+
event = [:foo, :bar, :monkey]
1259

13-
ref = :telemetry_test.attach_event_handlers(self(), [[:fun_with_flags, :persistence, event]])
60+
ref = :telemetry_test.attach_event_handlers(self(), [event])
1461

15-
assert :ok = FWFTel.persistence_event(event, metadata)
62+
assert :ok = FWFTel.do_send_event(event, metadata)
1663

1764
assert_received {
18-
[:fun_with_flags, :persistence, ^event],
65+
^event,
1966
^ref,
2067
%{system_time: time_value},
2168
^metadata

0 commit comments

Comments
 (0)