From 68106b8386032f116afc84a94d9c3e0e99063351 Mon Sep 17 00:00:00 2001 From: Gonzalo <456459+grzuy@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:44:38 -0300 Subject: [PATCH] feat: Tower.Event datetime insead of :logger.timestamp --- lib/tower/ephemeral_reporter.ex | 27 +++++++----- lib/tower/event.ex | 26 ++++++++---- test/tower_test.exs | 73 ++++++++++++++++++--------------- 3 files changed, 77 insertions(+), 49 deletions(-) diff --git a/lib/tower/ephemeral_reporter.ex b/lib/tower/ephemeral_reporter.ex index 5858c1a..508920b 100644 --- a/lib/tower/ephemeral_reporter.ex +++ b/lib/tower/ephemeral_reporter.ex @@ -20,39 +20,46 @@ defmodule Tower.EphemeralReporter do defp do_report_event(%Event{ id: id, - time: time, + datetime: datetime, kind: :error, reason: exception, stacktrace: stacktrace, metadata: metadata }) do - add_error(id, time, exception.__struct__, Exception.message(exception), stacktrace, metadata) + add_error( + id, + datetime, + exception.__struct__, + Exception.message(exception), + stacktrace, + metadata + ) end defp do_report_event(%Event{ id: id, - time: time, + datetime: datetime, kind: :exit, reason: reason, stacktrace: stacktrace, metadata: metadata }) do - add_error(id, time, :exit, reason, stacktrace, metadata) + add_error(id, datetime, :exit, reason, stacktrace, metadata) end defp do_report_event(%Event{ id: id, - time: time, + datetime: datetime, kind: :throw, reason: reason, stacktrace: stacktrace }) do - add_error(id, time, :throw, reason, stacktrace) + add_error(id, datetime, :throw, reason, stacktrace) end defp do_report_event(%Event{ id: id, - time: time, + datetime: datetime, kind: :message, level: level, reason: message, @@ -60,7 +67,7 @@ defmodule Tower.EphemeralReporter do }) do add(%{ id: id, - time: time, + datetime: datetime, level: level, kind: nil, reason: message, @@ -73,10 +80,10 @@ defmodule Tower.EphemeralReporter do Agent.get(__MODULE__, & &1) end - defp add_error(id, time, kind, reason, stacktrace, metadata \\ %{}) do + defp add_error(id, datetime, kind, reason, stacktrace, metadata \\ %{}) do add(%{ id: id, - time: time, + datetime: datetime, level: :error, kind: kind, reason: reason, diff --git a/lib/tower/event.ex b/lib/tower/event.ex index 292caa9..98978f0 100644 --- a/lib/tower/event.ex +++ b/lib/tower/event.ex @@ -1,5 +1,5 @@ defmodule Tower.Event do - defstruct [:id, :time, :level, :kind, :reason, :stacktrace, :log_event, :metadata] + defstruct [:id, :datetime, :level, :kind, :reason, :stacktrace, :log_event, :metadata] @type error_kind :: :error | :exit | :throw @type non_error_kind :: :message @@ -7,7 +7,7 @@ defmodule Tower.Event do @type t :: %__MODULE__{ id: Uniq.UUID.t(), - time: :logger.timestamp(), + datetime: DateTime.t(), level: :logger.level(), kind: error_kind() | non_error_kind(), reason: reason(), @@ -16,6 +16,8 @@ defmodule Tower.Event do metadata: map() } + @logger_time_unit :microsecond + @spec from_caught(Exception.kind(), reason(), Exception.stacktrace()) :: t() @spec from_caught(Exception.kind(), reason(), Exception.stacktrace(), Keyword.t()) :: t() def from_caught(kind, reason, stacktrace, options \\ []) @@ -44,7 +46,7 @@ defmodule Tower.Event do %__MODULE__{ id: new_id(), - time: log_event[:meta][:time] || now(), + datetime: event_datetime(log_event), level: :error, kind: :error, reason: exception, @@ -61,7 +63,7 @@ defmodule Tower.Event do %__MODULE__{ id: new_id(), - time: log_event[:meta][:time] || now(), + datetime: event_datetime(log_event), level: :error, kind: :exit, reason: reason, @@ -78,7 +80,7 @@ defmodule Tower.Event do %__MODULE__{ id: new_id(), - time: log_event[:meta][:time] || now(), + datetime: event_datetime(log_event), level: :error, kind: :throw, reason: reason, @@ -95,7 +97,7 @@ defmodule Tower.Event do %__MODULE__{ id: new_id(), - time: log_event[:meta][:time] || now(), + datetime: event_datetime(log_event), level: level, kind: :message, reason: message, @@ -104,7 +106,17 @@ defmodule Tower.Event do } end - defp now do + defp event_datetime(log_event) do + log_event + |> event_timestamp() + |> DateTime.from_unix!(@logger_time_unit) + end + + defp event_timestamp(%{meta: %{time: log_event_time}}) do + log_event_time + end + + defp event_timestamp(_) do :logger.timestamp() end diff --git a/test/tower_test.exs b/test/tower_test.exs index 44268f9..820ef71 100644 --- a/test/tower_test.exs +++ b/test/tower_test.exs @@ -27,7 +27,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: ArithmeticError, reason: "bad argument in arithmetic expression", @@ -37,7 +37,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -51,7 +51,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: RuntimeError, reason: "error inside process", @@ -61,7 +61,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -75,7 +75,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: :throw, reason: "error", @@ -85,7 +85,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -99,7 +99,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: :throw, reason: [something: "here"], @@ -109,7 +109,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -131,7 +131,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: :exit, reason: :abnormal, @@ -141,7 +141,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -155,7 +155,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: :exit, reason: :kill, @@ -165,7 +165,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -192,7 +192,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: nil, reason: "Something went wrong here", @@ -202,7 +202,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) end @tag capture_log: true @@ -225,7 +225,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: nil, reason: @@ -236,7 +236,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) end @tag capture_log: true @@ -250,7 +250,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :critical, kind: nil, reason: [something: :reported, this: :critical], @@ -260,7 +260,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) end test "reports message manually" do @@ -270,7 +270,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :info, kind: nil, reason: "Something interesting", @@ -283,7 +283,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) end test "reports Exception manually" do @@ -299,7 +299,7 @@ defmodule TowerTest do assert_eventually( [ %{ - time: time, + datetime: datetime, level: :error, kind: ArithmeticError, reason: "bad argument in arithmetic expression", @@ -308,7 +308,7 @@ defmodule TowerTest do ] = reported_events() ) - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -326,7 +326,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: ArithmeticError, reason: "bad argument in arithmetic expression", @@ -336,7 +336,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -354,7 +354,7 @@ defmodule TowerTest do assert_eventually( [ %{ - time: time, + datetime: datetime, level: :error, kind: :throw, reason: "error", @@ -363,7 +363,7 @@ defmodule TowerTest do ] = reported_events() ) - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -382,7 +382,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: :throw, reason: "error", @@ -392,7 +392,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -410,7 +410,7 @@ defmodule TowerTest do assert_eventually( [ %{ - time: time, + datetime: datetime, level: :error, kind: :exit, reason: :abnormal, @@ -419,7 +419,7 @@ defmodule TowerTest do ] = reported_events() ) - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -438,7 +438,7 @@ defmodule TowerTest do [ %{ id: id, - time: time, + datetime: datetime, level: :error, kind: :exit, reason: :abnormal, @@ -448,7 +448,7 @@ defmodule TowerTest do ) assert String.length(id) == 36 - assert_in_delta(time, :logger.timestamp(), 100_000) + assert recent_datetime?(datetime) assert is_list(stacktrace) end @@ -480,4 +480,13 @@ defmodule TowerTest do end end) end + + defp recent_datetime?(datetime) do + diff = + :logger.timestamp() + |> DateTime.from_unix!(:microsecond) + |> DateTime.diff(datetime, :microsecond) + + diff >= 0 && diff < 100_000 + end end