Skip to content

Commit 19e2477

Browse files
authored
Improve "GenServer terminating" reports (#723)
1 parent bed583f commit 19e2477

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed

lib/sentry/logger_handler.ex

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,8 @@ defmodule Sentry.LoggerHandler do
367367
sentry_opts =
368368
sentry_opts
369369
|> Keyword.put(:stacktrace, stacktrace)
370-
|> Keyword.update!(:extra, &Map.put(&1, :crash_reason, inspect(reason)))
371-
|> Keyword.update!(:extra, &Map.merge(extra_info_from_message(chardata_message), &1))
370+
|> add_extra_to_sentry_opts(%{crash_reason: inspect(reason)})
371+
|> add_extra_to_sentry_opts(extra_info_from_message(chardata_message))
372372

373373
case reason do
374374
{type, {GenServer, :call, [_pid, call, _timeout]}} = reason
@@ -383,8 +383,7 @@ defmodule Sentry.LoggerHandler do
383383
Sentry.capture_message(Exception.format_exit(reason), sentry_opts)
384384

385385
_other ->
386-
string_message = :unicode.characters_to_binary(chardata_message)
387-
Sentry.capture_message(string_message, sentry_opts)
386+
try_to_parse_message_or_just_report_it(chardata_message, sentry_opts)
388387
end
389388
end
390389

@@ -419,4 +418,77 @@ defmodule Sentry.LoggerHandler do
419418
defp extra_info_from_message(_message) do
420419
%{}
421420
end
421+
422+
# We do this because messages from Erlang's gen_* behaviours are often full of interesting
423+
# and useful data. For example, GenServer messages contain the PID, the reason, the last
424+
# message, and a treasure trove of stuff. If we cannot parse the message, such is life
425+
# and we just report it as is.
426+
427+
defp try_to_parse_message_or_just_report_it(
428+
[
429+
[
430+
"GenServer ",
431+
inspected_pid,
432+
" terminating",
433+
chardata_reason,
434+
"\nLast message",
435+
[" (from ", inspected_sender_pid, ")"],
436+
": ",
437+
inspected_last_message
438+
],
439+
"\nState: ",
440+
inspected_state | _
441+
],
442+
sentry_opts
443+
) do
444+
string_reason = chardata_reason |> :unicode.characters_to_binary() |> String.trim()
445+
446+
sentry_opts =
447+
sentry_opts
448+
|> Keyword.put(:interpolation_parameters, [inspected_pid])
449+
|> add_extra_to_sentry_opts(%{
450+
pid_which_sent_last_message: inspected_sender_pid,
451+
last_message: inspected_last_message,
452+
genserver_state: inspected_state
453+
})
454+
455+
Sentry.capture_message("GenServer %s terminating: #{string_reason}", sentry_opts)
456+
end
457+
458+
defp try_to_parse_message_or_just_report_it(
459+
[
460+
[
461+
"GenServer ",
462+
inspected_pid,
463+
" terminating",
464+
chardata_reason,
465+
"\nLast message: ",
466+
inspected_last_message
467+
],
468+
"\nState: ",
469+
inspected_state | _
470+
],
471+
sentry_opts
472+
) do
473+
string_reason = chardata_reason |> :unicode.characters_to_binary() |> String.trim()
474+
475+
sentry_opts =
476+
sentry_opts
477+
|> Keyword.put(:interpolation_parameters, [inspected_pid])
478+
|> add_extra_to_sentry_opts(%{
479+
last_message: inspected_last_message,
480+
genserver_state: inspected_state
481+
})
482+
483+
Sentry.capture_message("GenServer %s terminating: #{string_reason}", sentry_opts)
484+
end
485+
486+
defp try_to_parse_message_or_just_report_it(chardata_message, sentry_opts) do
487+
string_message = :unicode.characters_to_binary(chardata_message)
488+
Sentry.capture_message(string_message, sentry_opts)
489+
end
490+
491+
defp add_extra_to_sentry_opts(sentry_opts, new_extra) do
492+
Keyword.update(sentry_opts, :extra, %{}, &Map.merge(new_extra, &1))
493+
end
422494
end

test/sentry/logger_handler_test.exs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,18 @@ defmodule Sentry.LoggerHandlerTest do
180180

181181
assert_receive {^ref, event}
182182

183-
assert event.message.formatted =~ "** (stop) :bad_exit"
183+
assert event.message.message == "GenServer %s terminating: ** (stop) :bad_exit"
184+
assert event.message.params == [inspect(test_genserver)]
184185

185186
if System.otp_release() >= "26" do
186187
assert [] = event.exception
187188
assert [thread] = event.threads
188189
assert thread.stacktrace == nil
189190
assert event.extra.genserver_state == ":no_state"
190-
assert event.extra.last_message =~ "{:run, #Function"
191+
assert event.extra.last_message =~ ~r/^\{:run, .*/
192+
assert event.extra.pid_which_sent_last_message == inspect(self())
193+
assert event.extra.genserver_state == ":no_state"
194+
assert event.extra.crash_reason == ":bad_exit"
191195
end
192196
end
193197

0 commit comments

Comments
 (0)