Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/error_tracker.ex
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ defmodule ErrorTracker do
# sent a Telemetry event
# If it is a new error, sent a Telemetry event
case existing_status do
:resolved -> Telemetry.unresolved_error(error)
:resolved -> Telemetry.previously_resolved_error(error, occurrence)
:unresolved -> :noop
nil -> Telemetry.new_error(error)
nil -> Telemetry.new_error(error, occurrence)
end

Telemetry.new_occurrence(occurrence, muted)
Expand Down
28 changes: 19 additions & 9 deletions lib/error_tracker/telemetry.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,41 @@ defmodule ErrorTracker.Telemetry do
Each event is emitted with some measures and metadata, which can be used to
receive information without having to query the database again:

| event | measures | metadata |
| --------------------------------------- | -------------- | ----------------------------------|
| `[:error_tracker, :error, :new]` | `:system_time` | `:error` |
| `[:error_tracker, :error, :unresolved]` | `:system_time` | `:error` |
| `[:error_tracker, :error, :resolved]` | `:system_time` | `:error` |
| `[:error_tracker, :occurrence, :new]` | `:system_time` | `:occurrence`, `:error`, `:muted` |
| event | measures | metadata |
| --------------------------------------- | -------------- | ----------------------------------------------- |
| `[:error_tracker, :error, :new]` | `:system_time` | `:error`, `:occurrence` |
| `[:error_tracker, :error, :unresolved]` | `:system_time` | `:error`, `:occurrence` (nullable) |
| `[:error_tracker, :error, :resolved]` | `:system_time` | `:error` |
| `[:error_tracker, :occurrence, :new]` | `:system_time` | `:occurrence`, `:error`, `:muted` |

The metadata keys contain the following data:

* `:error` - An `%ErrorTracker.Error{}` struct representing the error.
* `:occurrence` - An `%ErrorTracker.Occurrence{}` struct representing the occurrence.
For `:new` error events this is the first occurrence. For `:unresolved` events this
is the occurrence that triggered the state change, or `nil` when the error was manually
unresolved from the UI.
* `:muted` - A boolean indicating whether the error is muted or not.
"""

@doc false
def new_error(%ErrorTracker.Error{} = error) do
def new_error(%ErrorTracker.Error{} = error, %ErrorTracker.Occurrence{} = occurrence) do
measurements = %{system_time: System.system_time()}
metadata = %{error: error}
metadata = %{error: error, occurrence: occurrence}
:telemetry.execute([:error_tracker, :error, :new], measurements, metadata)
end

@doc false
def unresolved_error(%ErrorTracker.Error{} = error) do
measurements = %{system_time: System.system_time()}
metadata = %{error: error}
metadata = %{error: error, occurrence: nil}
:telemetry.execute([:error_tracker, :error, :unresolved], measurements, metadata)
end

@doc false
def previously_resolved_error(%ErrorTracker.Error{} = error, %ErrorTracker.Occurrence{} = occurrence) do
measurements = %{system_time: System.system_time()}
metadata = %{error: error, occurrence: occurrence}
:telemetry.execute([:error_tracker, :error, :unresolved], measurements, metadata)
end

Expand Down
27 changes: 24 additions & 3 deletions test/error_tracker/telemetry_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ defmodule ErrorTracker.TelemetryTest do
end

# Since the error is new, both the new error and new occurrence events will be emitted
%Occurrence{error: error = %Error{}} = ErrorTracker.report(exception, stacktrace)
assert_receive {:telemetry_event, [:error_tracker, :error, :new], _, %{error: %Error{}}}
occurrence = %Occurrence{error: error = %Error{}} = ErrorTracker.report(exception, stacktrace)
assert_receive {:telemetry_event, [:error_tracker, :error, :new], _, %{error: %Error{}, occurrence: ^occurrence}}

assert_receive {:telemetry_event, [:error_tracker, :occurrence, :new], _, %{occurrence: %Occurrence{}, muted: false}}

Expand Down Expand Up @@ -49,6 +49,27 @@ defmodule ErrorTracker.TelemetryTest do
# The unresolved event will be emitted
{:ok, _unresolved} = ErrorTracker.unresolve(resolved)

assert_receive {:telemetry_event, [:error_tracker, :error, :unresolved], _, %{error: %Error{}}}
assert_receive {:telemetry_event, [:error_tracker, :error, :unresolved], _, %{error: %Error{}, occurrence: nil}}
end

test "events are emitted for previously resolved errors" do
{exception, stacktrace} =
try do
raise "This error was resolved but came back"
rescue
e -> {e, __STACKTRACE__}
end

%Occurrence{error: error = %Error{}} = ErrorTracker.report(exception, stacktrace)

ErrorTracker.resolve(error)

occurrence = ErrorTracker.report(exception, stacktrace)

assert_receive {:telemetry_event, [:error_tracker, :error, :unresolved], _,
%{
error: %Error{reason: "This error was resolved but came back"},
occurrence: ^occurrence
}}
end
end
Loading