Skip to content

Commit

Permalink
Fix timezone issue
Browse files Browse the repository at this point in the history
  • Loading branch information
achouippe committed Oct 10, 2024
1 parent 97b84e3 commit 3c3d833
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 18 deletions.
12 changes: 6 additions & 6 deletions neurow/lib/neurow/ecs_log_formatter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ defmodule Neurow.EcsLogFormatter do

# ECS Reference: https://www.elastic.co/guide/en/ecs/current/index.html

def format(level, message, timestamp, metadata) do
{{year, month, day}, {hour, minute, second, millisecond}} = timestamp
{:ok, date} = Date.new(year, month, day)
{:ok, time} = Time.new(hour, minute, second, millisecond * 1000)
{:ok, datetime} = DateTime.new(date, time)
def format(level, message, _timestamp, metadata) do
# The timestamp provided in input parameter is in the system timezone,
# but there is no clean way to get the system timezone in Elixir/Erlang to convert it to UTC and/or format it in ISO8601.
# So we use the unix timestamp provided in the metadata to get the event datetime time in UTC
{:ok, event_datetime} = DateTime.from_unix(metadata[:time], :microsecond)

{module, function, arity} = metadata[:mfa]

%{
"@timestamp" => datetime |> DateTime.to_iso8601(),
"@timestamp" => event_datetime |> DateTime.to_iso8601(),
"log.level" => level,
"log.name" => "#{module}.#{function}/#{arity}",
"log.source" => %{
Expand Down
21 changes: 9 additions & 12 deletions neurow/test/neurow/ecs_log_formatter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ defmodule Neurow.EcsLogFormatterTest do
use ExUnit.Case

test "generates ECS compliant logs with default metadata" do
timestamp = {{2024, 10, 23}, {12, 25, 45, 123}}

metadata = %{
time: 1_728_556_213_722_376,
mfa: {Neurow.EcsLogFormatterTest, :fake_function, 4},
file: "test/neurow/ecs_log_formatter_test.exs",
line: 10
}

json_log =
Neurow.EcsLogFormatter.format(:info, "Hello, world!", timestamp, metadata)
Neurow.EcsLogFormatter.format(:info, "Hello, world!", nil, metadata)
|> :jiffy.decode([:return_maps])

assert json_log == %{
"@timestamp" => "2024-10-23T12:25:45.123000Z",
"@timestamp" => "2024-10-10T10:30:13.722376Z",
"log.level" => "info",
"log.name" => "Elixir.Neurow.EcsLogFormatterTest.fake_function/4",
"log.source" => %{
Expand All @@ -35,21 +34,20 @@ defmodule Neurow.EcsLogFormatterTest do
end

test "supports optional trace_id metadata" do
timestamp = {{2024, 10, 23}, {12, 25, 45, 123}}

metadata = %{
time: 1_728_556_213_722_376,
mfa: {Neurow.EcsLogFormatterTest, :fake_function, 4},
file: "test/neurow/ecs_log_formatter_test.exs",
line: 10,
trace_id: "1234567890"
}

json_log =
Neurow.EcsLogFormatter.format(:info, "Hello, world!", timestamp, metadata)
Neurow.EcsLogFormatter.format(:info, "Hello, world!", nil, metadata)
|> :jiffy.decode([:return_maps])

assert json_log == %{
"@timestamp" => "2024-10-23T12:25:45.123000Z",
"@timestamp" => "2024-10-10T10:30:13.722376Z",
"log.level" => "info",
"log.name" => "Elixir.Neurow.EcsLogFormatterTest.fake_function/4",
"log.source" => %{
Expand All @@ -70,21 +68,20 @@ defmodule Neurow.EcsLogFormatterTest do
end

test "supports optional error_code metadata" do
timestamp = {{2024, 10, 23}, {12, 25, 45, 123}}

metadata = %{
time: 1_728_556_213_722_376,
mfa: {Neurow.EcsLogFormatterTest, :fake_function, 4},
file: "test/neurow/ecs_log_formatter_test.exs",
line: 10,
error_code: "invalid_last_event_id"
}

json_log =
Neurow.EcsLogFormatter.format(:info, "Hello, world!", timestamp, metadata)
Neurow.EcsLogFormatter.format(:info, "Hello, world!", nil, metadata)
|> :jiffy.decode([:return_maps])

assert json_log == %{
"@timestamp" => "2024-10-23T12:25:45.123000Z",
"@timestamp" => "2024-10-10T10:30:13.722376Z",
"log.level" => "info",
"log.name" => "Elixir.Neurow.EcsLogFormatterTest.fake_function/4",
"log.source" => %{
Expand Down

0 comments on commit 3c3d833

Please sign in to comment.