Skip to content

Commit 2691854

Browse files
committed
in_winevtlog: Plug glitches of time offset for DST/STD switches
Signed-off-by: Hiroshi Hatake <[email protected]>
1 parent bd33713 commit 2691854

File tree

1 file changed

+63
-17
lines changed

1 file changed

+63
-17
lines changed

plugins/in_winevtlog/pack.c

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <fluent-bit/flb_utils.h>
2424
#include <fluent-bit/flb_pack.h>
2525
#include <fluent-bit/flb_input_plugin.h>
26+
#include <stdlib.h>
2627
#include <msgpack.h>
2728
#include <sddl.h>
2829
#include <locale.h>
@@ -265,39 +266,84 @@ static int pack_systemtime(struct winevtlog_config *ctx, SYSTEMTIME *st)
265266

266267
static int pack_filetime(struct winevtlog_config *ctx, ULONGLONG filetime)
267268
{
268-
LARGE_INTEGER timestamp;
269+
FILETIME ft;
270+
SYSTEMTIME st_utc;
271+
SYSTEMTIME st_local;
272+
DYNAMIC_TIME_ZONE_INFORMATION dtzi;
269273
CHAR buf[64];
270-
size_t len = 0;
271-
FILETIME ft, ft_local;
272-
SYSTEMTIME st;
274+
size_t len;
275+
LONG bias_minutes;
276+
int offset_hours;
277+
int offset_minutes;
278+
char offset_sign;
273279
_locale_t locale;
280+
DWORD tz_id;
274281

275282
_tzset();
276283

277284
locale = _get_current_locale();
278285
if (locale == NULL) {
279286
return -1;
280287
}
281-
timestamp.QuadPart = filetime;
282-
ft.dwHighDateTime = timestamp.HighPart;
283-
ft.dwLowDateTime = timestamp.LowPart;
284-
FileTimeToLocalFileTime(&ft, &ft_local);
285-
if (FileTimeToSystemTime(&ft_local, &st)) {
286-
struct tm tm = {st.wSecond, st.wMinute, st.wHour, st.wDay, st.wMonth-1, st.wYear-1900, st.wDayOfWeek, 0, -1};
287-
len = _strftime_l(buf, 64, FORMAT_ISO8601, &tm, locale);
288-
if (len == 0) {
289-
flb_errno();
290-
_free_locale(locale);
291-
return -1;
292-
}
288+
289+
ft.dwHighDateTime = (DWORD)(filetime >> 32);
290+
ft.dwLowDateTime = (DWORD)(filetime & 0xFFFFFFFF);
291+
292+
if (!FileTimeToSystemTime(&ft, &st_utc)) {
293+
_free_locale(locale);
294+
return -1;
295+
}
296+
297+
tz_id = GetDynamicTimeZoneInformation(&dtzi);
298+
299+
if (!SystemTimeToTzSpecificLocalTimeEx(&dtzi, &st_utc, &st_local)) {
293300
_free_locale(locale);
301+
return -1;
302+
}
294303

295-
flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len);
304+
/* Determine bias (minutes) */
305+
bias_minutes = dtzi.Bias;
306+
307+
if (tz_id == TIME_ZONE_ID_DAYLIGHT) {
308+
bias_minutes += dtzi.DaylightBias;
309+
}
310+
else if (tz_id == TIME_ZONE_ID_STANDARD) {
311+
bias_minutes += dtzi.StandardBias;
312+
}
313+
314+
/* Windows bias: minutes to add to local to get UTC
315+
ISO8601 offset: inverse sign */
316+
if (bias_minutes > 0) {
317+
offset_sign = '-';
296318
}
297319
else {
320+
offset_sign = '+';
321+
bias_minutes = -bias_minutes;
322+
}
323+
324+
offset_hours = bias_minutes / 60;
325+
offset_minutes = bias_minutes % 60;
326+
327+
len = _snprintf_s(buf, sizeof(buf), _TRUNCATE,
328+
"%04d-%02d-%02d %02d:%02d:%02d %c%02d%02d",
329+
st_local.wYear,
330+
st_local.wMonth,
331+
st_local.wDay,
332+
st_local.wHour,
333+
st_local.wMinute,
334+
st_local.wSecond,
335+
offset_sign,
336+
offset_hours,
337+
offset_minutes);
338+
339+
if (len <= 0) {
340+
_free_locale(locale);
298341
return -1;
299342
}
300343

344+
_free_locale(locale);
345+
346+
flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len);
301347
return 0;
302348
}
303349

0 commit comments

Comments
 (0)