]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
json: append timezone information to ISO 8601 date
authorVincent Bernat <Vincent.Bernat@exoscale.ch>
Fri, 2 Oct 2015 15:00:58 +0000 (17:00 +0200)
committerEric Leblond <eric@regit.org>
Fri, 2 Oct 2015 15:11:04 +0000 (17:11 +0200)
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>
output/ulogd_output_JSON.c

index 36a4d4962a54bc82399140c98628608317fa014a..4d8e3e940a7dd4adb89927c54bcfb5a3fa3f6015 100644 (file)
 #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;
 }