From b09205b017cef10467e04b3c7ade31cc34577505 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Fri, 2 Oct 2015 17:00:58 +0200 Subject: json: append timezone information to ISO 8601 date While this is not strictly needed for ISO 8601, this is helpful since otherwise, the receiver can't assume anything about the timezone. This uses a GNU extension but as ulogd is quite Linux-specific, this shouldn't be a problem. The POSIX variables (tzname and daylight) are quite difficult to use because daylight handling is incomplete (daylight don't say if DST is now in effect, it just says it is sometimes in effect). A timezone offset is used instead of a timezone since it is usually easier to parse (strptime in glibc is not able to parse a timezone name) and don't require an up-to-date TZ database. Signed-off-by: Vincent Bernat --- output/ulogd_output_JSON.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'output/ulogd_output_JSON.c') diff --git a/output/ulogd_output_JSON.c b/output/ulogd_output_JSON.c index 36a4d49..4d8e3e9 100644 --- a/output/ulogd_output_JSON.c +++ b/output/ulogd_output_JSON.c @@ -36,10 +36,14 @@ #define ULOGD_JSON_DEFAULT_DEVICE "Netfilter" #endif +#define unlikely(x) __builtin_expect((x),0) + struct json_priv { FILE *of; int sec_idx; int usec_idx; + long cached_gmtoff; + char cached_tz[6]; /* eg +0200 */ }; enum json_conf { @@ -94,7 +98,7 @@ static struct config_keyset json_kset = { }, }; -#define MAX_LOCAL_TIME_STRING 32 +#define MAX_LOCAL_TIME_STRING 38 static int json_interp(struct ulogd_pluginstance *upi) { @@ -124,20 +128,29 @@ static int json_interp(struct ulogd_pluginstance *upi) else now = time(NULL); t = localtime_r(&now, &result); + if (unlikely(*opi->cached_tz = '\0' || t->tm_gmtoff != opi->cached_gmtoff)) { + snprintf(opi->cached_tz, sizeof(opi->cached_tz), + "%c%02d%02d", + t->tm_gmtoff > 0 ? '+' : '-', + abs(t->tm_gmtoff) / 60 / 60, + abs(t->tm_gmtoff) / 60 % 60); + } if (pp_is_valid(inp, opi->usec_idx)) { snprintf(timestr, MAX_LOCAL_TIME_STRING, - "%04d-%02d-%02dT%02d:%02d:%02d.%06u", + "%04d-%02d-%02dT%02d:%02d:%02d.%06u%s", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, - ikey_get_u32(&inp[opi->usec_idx])); + ikey_get_u32(&inp[opi->usec_idx]), + opi->cached_tz); } else { snprintf(timestr, MAX_LOCAL_TIME_STRING, - "%04d-%02d-%02dT%02d:%02d:%02d", + "%04d-%02d-%02dT%02d:%02d:%02d%s", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, - t->tm_min, t->tm_sec); + t->tm_min, t->tm_sec, + opi->cached_tz); } if (upi->config_kset->ces[JSON_CONF_EVENTV1].u.value != 0) @@ -278,6 +291,8 @@ static int json_init(struct ulogd_pluginstance *upi) op->usec_idx = i; } + *op->cached_tz = '\0'; + return 0; } -- cgit v1.2.3