Skip to content

Commit

Permalink
filterx: Fix strptime to remove unwanted gmtoff in datetime conversion
Browse files Browse the repository at this point in the history
The strptime function relies on the wallclocktime_strptime utility to parse time, leveraging its extensive heuristics. Additionally, we use the wallclocktime to unixtime conversion from the wallclocktime module, as the internal time representation in filterx datetime is unixtime.
However, this conversion introduces an unintended side effect: the GMT offset (gmtoff) value is retained even after converting to UTC. This results in a double application of the time offset when the unixtime handler functions process the timestamp later.
To address this issue, the simplest solution was to manually reset the GMT offset (gmtoff) to zero after the conversion.
This approach is questionable, as it discards timezone information at the moment of creating the datetime object in certain cases. A potential improvement could involve creating a custom wallclocktime-to-unixtime converter to avoid such side effects.

Signed-off-by: shifter <[email protected]>
  • Loading branch information
bshifter committed Jan 24, 2025
1 parent b41e1eb commit 964fb28
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 5 deletions.
2 changes: 2 additions & 0 deletions lib/filterx/object-datetime.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ filterx_typecast_datetime_isodate(FilterXExpr *s, FilterXObject *args[], gsize a
}

convert_wall_clock_time_to_unix_time(&wct, &ut);
ut.ut_gmtoff = 0;
return filterx_datetime_new(&ut);
}

Expand Down Expand Up @@ -288,6 +289,7 @@ _strptime_eval(FilterXExpr *s)
if (end)
{
convert_wall_clock_time_to_unix_time(&wct, &ut);
ut.ut_gmtoff = 0;
result = filterx_datetime_new(&ut);
}
else
Expand Down
6 changes: 3 additions & 3 deletions lib/filterx/tests/test_object_datetime.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ Test(filterx_datetime, test_filterx_datetime_repr)
GString *repr = scratch_buffers_alloc();
g_string_assign(repr, "foo");
cr_assert(filterx_object_repr(obj, repr));
cr_assert_str_eq("2024-03-18T12:34:13.000+09:00", repr->str);
cr_assert_str_eq("2024-03-18T03:34:13.000+00:00", repr->str);
cr_assert(filterx_object_repr_append(obj, repr));
cr_assert_str_eq("2024-03-18T12:34:13.000+09:002024-03-18T12:34:13.000+09:00", repr->str);
cr_assert_str_eq("2024-03-18T03:34:13.000+00:002024-03-18T03:34:13.000+00:00", repr->str);

filterx_simple_function_free_args(args, G_N_ELEMENTS(args));
filterx_object_unref(obj);
Expand Down Expand Up @@ -310,7 +310,7 @@ Test(filterx_datetime, test_filterx_datetime_strptime_matching_nth_timefmt)

GString *repr = scratch_buffers_alloc();
cr_assert(filterx_object_repr(obj, repr));
cr_assert_str_eq(repr->str, "2024-04-08T10:11:12.000+01:00");
cr_assert_str_eq(repr->str, "2024-04-08T09:11:12.000+00:00");

filterx_object_unref(obj);
filterx_expr_unref(func_expr);
Expand Down
4 changes: 2 additions & 2 deletions tests/light/functional_tests/filterx/test_filterx.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def test_otel_logrecord_datetime_setter_getter(config, syslog_ng):

assert file_true.get_stats()["processed"] == 1
assert "processed" not in file_false.get_stats()
assert file_true.read_log() == "1701353998.123000+00:00\n"
assert file_true.read_log() == "1701346798.123000+00:00\n"


def test_otel_logrecord_body_string_setter_getter(config, syslog_ng):
Expand Down Expand Up @@ -210,7 +210,7 @@ def test_otel_logrecord_body_datetime_setter_getter(config, syslog_ng):
# does not distinguish int_value and datetime.
assert file_true.get_stats()["processed"] == 1
assert "processed" not in file_false.get_stats()
assert file_true.read_log() == "1701353998123000\n"
assert file_true.read_log() == "1701346798123000\n"


def test_otel_logrecord_body_bytes_setter_getter(config, syslog_ng):
Expand Down

0 comments on commit 964fb28

Please sign in to comment.