Skip to content

Commit 01ce385

Browse files
authored
Merge pull request #32 from amplifiedai/telemetry
Add telemetry support
2 parents d65a800 + 44cfc45 commit 01ce385

5 files changed

Lines changed: 86 additions & 7 deletions

File tree

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,28 @@ There are not many tests at the moment. if you want to run live tests on your ac
168168
```
169169
SEGMENT_KEY=yourkey mix test
170170
```
171+
172+
## Telemetry
173+
174+
This package wraps its Segment event sending in [`:telemetry.span/3`][telemetry-span-3]. You can attach to:
175+
176+
- `[:segment, :send, :start]`
177+
- `[:segment, :send, :stop]`
178+
- `[:segment, :send, :exception]`
179+
- `[:segment, :batch, :start]`
180+
- `[:segment, :batch, :stop]`
181+
- `[:segment, :batch, :exception]`
182+
183+
The measurements will include, in Erlang's `:native` time unit (likely `:nanosecond`):
184+
185+
- `system_time` with `:start` events
186+
- `duration` with `:stop` and `:exception` events
187+
188+
The metadata will include:
189+
190+
- the original `event` or `events` with all `:send` and `:batch` events respectively
191+
- our `status` (`:ok` | `:error`) and Tesla's `result` with all `:stop` events
192+
- `error` matching `result` when it isn't `{:ok, env}`
193+
- `kind`, `reason`, and `stacktrace` with `:exception` events
194+
195+
[telemetry-span-3]: https://hexdocs.pm/telemetry/telemetry.html#span-3

lib/segment/client/http.ex

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,22 @@ defmodule Segment.Http do
8585
"""
8686
@spec send(client(), Segment.segment_event()) :: :ok | :error
8787
def send(client, event) do
88-
case make_request(client, event.type, prepare_events(event), Segment.Config.retry_attempts()) do
88+
:telemetry.span([:segment, :send], %{event: event}, fn ->
89+
tesla_result =
90+
make_request(client, event.type, prepare_events(event), Segment.Config.retry_attempts())
91+
92+
case process_send_post_result(tesla_result) do
93+
:ok ->
94+
{:ok, %{event: event, status: :ok, result: tesla_result}}
95+
96+
:error ->
97+
{:error, %{event: event, status: :error, error: tesla_result, result: tesla_result}}
98+
end
99+
end)
100+
end
101+
102+
defp process_send_post_result(tesla_result) do
103+
case tesla_result do
89104
{:ok, %{status: status}} when status == 200 ->
90105
:ok
91106

@@ -114,12 +129,26 @@ defmodule Segment.Http do
114129
"""
115130
@spec batch(client(), list(Segment.segment_event()), map() | nil, map() | nil) :: :ok | :error
116131
def batch(client, events, context \\ nil, integrations \\ nil) do
117-
data =
118-
%{batch: prepare_events(events)}
119-
|> add_if(:context, context)
120-
|> add_if(:integrations, integrations)
132+
:telemetry.span([:segment, :batch], %{events: events}, fn ->
133+
data =
134+
%{batch: prepare_events(events)}
135+
|> add_if(:context, context)
136+
|> add_if(:integrations, integrations)
137+
138+
tesla_result = make_request(client, "batch", data, Segment.Config.retry_attempts())
139+
140+
case process_batch_post_result(tesla_result, events) do
141+
:ok ->
142+
{:ok, %{events: events, status: :ok, result: tesla_result}}
143+
144+
:error ->
145+
{:error, %{events: events, status: :error, error: tesla_result, result: tesla_result}}
146+
end
147+
end)
148+
end
121149

122-
case make_request(client, "batch", data, Segment.Config.retry_attempts()) do
150+
defp process_batch_post_result(tesla_result, events) do
151+
case tesla_result do
123152
{:ok, %{status: status}} when status == 200 ->
124153
:ok
125154

mix.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule AnalyticsElixir.Mixfile do
1818
end
1919

2020
def application do
21-
[applications: [:hackney, :logger, :retry, :tesla, :jason]]
21+
[applications: [:hackney, :logger, :retry, :tesla, :jason, :telemetry]]
2222
end
2323

2424
defp deps do
@@ -29,6 +29,7 @@ defmodule AnalyticsElixir.Mixfile do
2929
{:jason, ">= 1.0.0"},
3030
{:mox, "~> 0.5", only: :test},
3131
{:retry, "~> 0.13"},
32+
{:telemetry, "~> 0.4.2"},
3233
{:tesla, "~> 1.2"}
3334
]
3435
end

mix.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"poison": {:hex, :poison, "1.5.2", "560bdfb7449e3ddd23a096929fb9fc2122f709bcc758b2d5d5a5c7d0ea848910", [:mix], []},
2020
"retry": {:hex, :retry, "0.14.0", "751c0f6db0b5127acf346ea6f6c363ec4588320db785c62aa51776b4d280bf07", [:mix], [], "hexpm", "5c158bccf5e4de2a13d044b9930ceb7e7499c29e3fccd7c96f131a6b83a1cff3"},
2121
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"},
22+
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
2223
"tesla": {:hex, :tesla, "1.3.3", "26ae98627af5c406584aa6755ab5fc96315d70d69a24dd7f8369cfcb75094a45", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "2648f1c276102f9250299e0b7b57f3071c67827349d9173f34c281756a1b124c"},
2324
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
2425
}

test/segment_test.exs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ defmodule SegmentTest do
22
use ExUnit.Case
33

44
test "track debugging" do
5+
test_began = :erlang.system_time()
6+
7+
:telemetry.attach_many(
8+
self(),
9+
[[:segment, :batch, :start], [:segment, :batch, :stop]],
10+
fn n, m10s, m6a, pid -> send(pid, {:telemetry, n, m10s, m6a}) end,
11+
self()
12+
)
13+
514
Segment.start_link(System.get_env("SEGMENT_KEY"))
615

716
Segment.Analytics.track("user1", "track debugging #{elem(:os.timestamp(), 2)}")
@@ -31,6 +40,20 @@ defmodule SegmentTest do
3140
Segment.Analytics.page("user1", "page debugging #{elem(:os.timestamp(), 2)}")
3241

3342
Segment.Analytics.Batcher.flush()
43+
44+
test_ended = :erlang.system_time()
45+
46+
assert_received {:telemetry, [:segment, :batch, :start], %{system_time: system_time},
47+
%{events: events}}
48+
49+
assert_received {:telemetry, [:segment, :batch, :stop], %{duration: duration},
50+
%{events: ^events, status: :ok, result: {:ok, env}}}
51+
52+
assert system_time > test_began
53+
assert system_time <= test_ended
54+
assert length(events) == 6
55+
assert duration <= test_ended - test_began
56+
assert env.status == 200
3457
end
3558

3659
defp wait_random(n \\ 1000), do: Process.sleep(:rand.uniform(n))

0 commit comments

Comments
 (0)