diff options
-rw-r--r-- | plugins/ommongodb/ommongodb.c | 29 | ||||
-rw-r--r-- | runtime/datetime.c | 30 | ||||
-rw-r--r-- | runtime/datetime.h | 1 |
3 files changed, 47 insertions, 13 deletions
diff --git a/plugins/ommongodb/ommongodb.c b/plugins/ommongodb/ommongodb.c index 5591b693..267f98a1 100644 --- a/plugins/ommongodb/ommongodb.c +++ b/plugins/ommongodb/ommongodb.c @@ -191,6 +191,17 @@ getLumberjackLevel(short severity) } +/* small helper: get integer power of 10 */ +static inline int +i10pow(int exp) +{ + int r = 1; + while(exp > 0) { + r *= 10; + exp--; + } + return r; +} /* write to mongodb in MSG passing mode, that is without a template. * In this mode, we use the standard document format, which is somewhat * aligned to cee (as described in project lumberjack). Note that this is @@ -204,7 +215,8 @@ rsRetVal writeMongoDB_msg(msg_t *pMsg, instanceData *pData) uchar *pid; short unsigned pid_free; size_t pid_len; uchar *sys; short unsigned sys_free; size_t sys_len; uchar *msg; short unsigned msg_free; size_t msg_len; - char timestamp[64]; + gint64 timestamp; + int secfrac; DEFiRet; /* see if we are ready to proceed */ @@ -216,10 +228,21 @@ rsRetVal writeMongoDB_msg(msg_t *pMsg, instanceData *pData) pid = MsgGetProp(pMsg, NULL, PROP_PROCID, NULL, &pid_len, &pid_free); sys = MsgGetProp(pMsg, NULL, PROP_HOSTNAME, NULL, &sys_len, &sys_free); msg = MsgGetProp(pMsg, NULL, PROP_MSG, NULL, &msg_len, &msg_free); - datetime.formatTimestamp3339(&pMsg->tTIMESTAMP, timestamp); + timestamp = (gint64) datetime.syslogTime2time_t(&pMsg->tTIMESTAMP) * 1000; /* ms! */ +dbgprintf("ommongodb: timestamp is %lld\n", (long long) timestamp); +dbgprintf("ommongodb: secfrac is %d, precision %d\n", pMsg->tTIMESTAMP.secfrac, pMsg->tTIMESTAMP.secfracPrecision); + if(pMsg->tTIMESTAMP.secfracPrecision > 3) { + secfrac = pMsg->tTIMESTAMP.secfrac / i10pow(pMsg->tTIMESTAMP.secfracPrecision - 3); + } else if(pMsg->tTIMESTAMP.secfracPrecision < 3) { + secfrac = pMsg->tTIMESTAMP.secfrac * i10pow(3 - pMsg->tTIMESTAMP.secfracPrecision); + } else { + secfrac = pMsg->tTIMESTAMP.secfrac; + } + timestamp += secfrac; +dbgprintf("ommongodb: normalized secfrac is %d, final timestamp %lld\n", secfrac, (long long) timestamp); doc = bson_build(BSON_TYPE_STRING, "sys", sys, sys_len, - BSON_TYPE_STRING, "time", timestamp, -1, + BSON_TYPE_UTC_DATETIME, "time", timestamp, BSON_TYPE_STRING, "msg", msg, msg_len, BSON_TYPE_STRING, "procid", procid, procid_len, BSON_TYPE_STRING, "pid", pid, pid_len, diff --git a/runtime/datetime.c b/runtime/datetime.c index 830c67e3..10ab3c64 100644 --- a/runtime/datetime.c +++ b/runtime/datetime.c @@ -851,16 +851,9 @@ int formatTimestamp3164(struct syslogTime *ts, char* pBuf, int bBuggyDay) /** - * format a timestamp as a UNIX timestamp; subsecond resolution is - * discarded. - * Note that this code can use some refactoring. I decided to use it - * because mktime() requires an upfront TZ update as it works on local - * time. In any case, it is worth reconsidering to move to mktime() or - * some other method. - * Important: pBuf must point to a buffer of at least 11 bytes. - * rgerhards, 2012-03-29 + * convert syslog timestamp to time_t */ -int formatTimestampUnix(struct syslogTime *ts, char *pBuf) +time_t syslogTime2time_t(struct syslogTime *ts) { long MonthInDays, NumberOfYears, NumberOfDays, i; int utcOffset; @@ -956,7 +949,23 @@ int formatTimestampUnix(struct syslogTime *ts, char *pBuf) if(ts->OffsetMode == '+') utcOffset *= -1; /* if timestamp is ahead, we need to "go back" to UTC */ TimeInUnixFormat += utcOffset; - snprintf(pBuf, 11, "%u", (unsigned) TimeInUnixFormat); + return TimeInUnixFormat; +} + + +/** + * format a timestamp as a UNIX timestamp; subsecond resolution is + * discarded. + * Note that this code can use some refactoring. I decided to use it + * because mktime() requires an upfront TZ update as it works on local + * time. In any case, it is worth reconsidering to move to mktime() or + * some other method. + * Important: pBuf must point to a buffer of at least 11 bytes. + * rgerhards, 2012-03-29 + */ +int formatTimestampUnix(struct syslogTime *ts, char *pBuf) +{ + snprintf(pBuf, 11, "%u", (unsigned) syslogTime2time_t(ts)); return 11; } @@ -986,6 +995,7 @@ CODESTARTobjQueryInterface(datetime) pIf->formatTimestamp3339 = formatTimestamp3339; pIf->formatTimestamp3164 = formatTimestamp3164; pIf->formatTimestampUnix = formatTimestampUnix; + pIf->syslogTime2time_t = syslogTime2time_t; finalize_it: ENDobjQueryInterface(datetime) diff --git a/runtime/datetime.h b/runtime/datetime.h index bb5e5292..9f3611e1 100644 --- a/runtime/datetime.h +++ b/runtime/datetime.h @@ -46,6 +46,7 @@ BEGINinterface(datetime) /* name must also be changed in ENDinterface macro! */ void (*timeval2syslogTime)(struct timeval *tp, struct syslogTime *t); /* v7, 2012-03-29 */ int (*formatTimestampUnix)(struct syslogTime *ts, char*pBuf); + time_t (*syslogTime2time_t)(struct syslogTime *ts); ENDinterface(datetime) #define datetimeCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */ /* interface changes: |