Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
bshifter committed Jan 24, 2025

Verified

This commit was signed with the committer’s verified signature.
1 parent b41e1eb commit 3f7875e
Showing 3 changed files with 9 additions and 7 deletions.
2 changes: 2 additions & 0 deletions lib/filterx/object-datetime.c
Original file line number Diff line number Diff line change
@@ -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);
}

@@ -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
6 changes: 3 additions & 3 deletions lib/filterx/tests/test_object_datetime.c
Original file line number Diff line number Diff line change
@@ -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);
@@ -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);
8 changes: 4 additions & 4 deletions tests/light/functional_tests/filterx/test_filterx.py
Original file line number Diff line number Diff line change
@@ -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):
@@ -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):
@@ -1211,15 +1211,15 @@ def test_strptime_success_result(config, syslog_ng):
def test_strftime_success_result(config, syslog_ng):
(file_true, file_false) = create_config(
config, """
datetime = strptime("2000-01-01T00:00:00 +0200", "%Y-%m-%dT%H:%M:%S %z");
datetime = strptime("2000-01-01T02:00:00 +0200", "%Y-%m-%dT%H:%M:%S %z");
$MSG = strftime("%Y-%m-%dT%H:%M:%S %z", datetime);
""",
)
syslog_ng.start(config)

assert file_true.get_stats()["processed"] == 1
assert "processed" not in file_false.get_stats()
assert file_true.read_log() == "2000-01-01T00:00:00 +0200\n"
assert file_true.read_log() == "2000-01-01T00:00:00 +0000\n"


def test_strptime_guess_missing_year(config, syslog_ng):

0 comments on commit 3f7875e

Please sign in to comment.