diff options
author | Vincent Bernat <Vincent.Bernat@exoscale.ch> | 2015-10-02 17:00:58 +0200 |
---|---|---|
committer | Eric Leblond <eric@regit.org> | 2015-10-02 17:11:04 +0200 |
commit | b09205b017cef10467e04b3c7ade31cc34577505 (patch) | |
tree | 391729d2bcd73b6c819e0bc5465f909ce8f5f02a /output | |
parent | 0ea23cc7ad69556c71787a791fd8e13942540f16 (diff) |
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 <Vincent.Bernat@exoscale.ch>
Diffstat (limited to 'output')
-rw-r--r-- | output/ulogd_output_JSON.c | 25 |
1 files changed, 20 insertions, 5 deletions
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; } |