summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Bernat <Vincent.Bernat@exoscale.ch>2015-10-02 17:00:58 +0200
committerEric Leblond <eric@regit.org>2015-10-02 17:11:04 +0200
commitb09205b017cef10467e04b3c7ade31cc34577505 (patch)
tree391729d2bcd73b6c819e0bc5465f909ce8f5f02a
parent0ea23cc7ad69556c71787a791fd8e13942540f16 (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>
-rw-r--r--output/ulogd_output_JSON.c25
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;
}