diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-06-06 17:33:58 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-06-06 17:33:58 +0200 |
commit | 2687d0010ca0ec691235a69c9da021719b61e8cd (patch) | |
tree | d8275d258253ed44fce7d163b2f5f1448fd8a7d4 | |
parent | 6343cf730acbb454765d0593d68032aebcb3d15c (diff) | |
download | rsyslog-2687d0010ca0ec691235a69c9da021719b61e8cd.tar.gz rsyslog-2687d0010ca0ec691235a69c9da021719b61e8cd.tar.xz rsyslog-2687d0010ca0ec691235a69c9da021719b61e8cd.zip |
added new property replacer option "time-subseconds"
enables to query just the subsecond part of a high-precision timestamp
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | doc/property_replacer.html | 4 | ||||
-rw-r--r-- | runtime/datetime.c | 40 | ||||
-rw-r--r-- | runtime/datetime.h | 3 | ||||
-rw-r--r-- | runtime/msg.c | 26 | ||||
-rw-r--r-- | runtime/msg.h | 2 | ||||
-rw-r--r-- | template.c | 2 | ||||
-rw-r--r-- | template.h | 3 |
8 files changed, 80 insertions, 2 deletions
@@ -1,5 +1,7 @@ --------------------------------------------------------------------------- Version 3.19.7 (rgerhards), 2008-06-?? +- added new property replacer option "time-subseconds" that enables + to query just the subsecond part of a high-precision timestamp --------------------------------------------------------------------------- Version 3.19.6 (rgerhards), 2008-06-06 - enhanced property replacer to support multiple regex matches diff --git a/doc/property_replacer.html b/doc/property_replacer.html index 86d28274..2675e8fb 100644 --- a/doc/property_replacer.html +++ b/doc/property_replacer.html @@ -284,6 +284,10 @@ Especially useful for PIX.</td> <td>format as RFC 3339 date</td> </tr> <tr> +<td><b>date-subseconds</b></td> +<td>just the subseconds of a timestamp (always 0 for a low precision timestamp)</td> +</tr> +<tr> <td><b>escape-cc</b></td> <td>replace control characters (ASCII value 127 and values less then 32) with an escape sequence. The sequnce is diff --git a/runtime/datetime.c b/runtime/datetime.c index d72cac3c..5211b78a 100644 --- a/runtime/datetime.c +++ b/runtime/datetime.c @@ -492,6 +492,45 @@ int formatTimestampToPgSQL(struct syslogTime *ts, char *pDst, size_t iLenDst) ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second)); } + +/** + * Format a syslogTimestamp to just the fractional seconds. + * The caller must provide the timestamp as well as a character + * buffer that will receive the resulting string. The function + * returns the size of the timestamp written in bytes (without + * the string terminator). If 0 is returend, an error occured. + * The buffer must be at least 10 bytes large. + * rgerhards, 2008-06-06 + */ +int formatTimestampSecFrac(struct syslogTime *ts, char* pBuf, size_t iLenBuf) +{ + int lenRet; + char szFmtStr[64]; + + assert(ts != NULL); + assert(pBuf != NULL); + assert(iLenBuf >= 10); + + if(ts->secfracPrecision > 0) + { /* We must look at + * the precision specified. For example, if we have millisec precision (3 digits), a + * secFrac value of 12 is not equivalent to ".12" but ".012". Obviously, this + * is a huge difference ;). To avoid this, we first create a format string with + * the specific precision and *then* use that format string to do the actual formating. + */ + /* be careful: there is ONE actual %d in the format string below ;) */ + snprintf(szFmtStr, sizeof(szFmtStr), "%%0%dd", ts->secfracPrecision); + lenRet = snprintf(pBuf, iLenBuf, szFmtStr, ts->secfrac); + } else { + pBuf[0] = '0'; + pBuf[1] = '1'; + lenRet = 1; + } + + return(lenRet); +} + + /** * Format a syslogTimestamp to a RFC3339 timestamp string (as * specified in syslog-protocol). @@ -610,6 +649,7 @@ CODESTARTobjQueryInterface(datetime) pIf->ParseTIMESTAMP3164 = ParseTIMESTAMP3164; pIf->formatTimestampToMySQL = formatTimestampToMySQL; pIf->formatTimestampToPgSQL = formatTimestampToPgSQL; + pIf->formatTimestampSecFrac = formatTimestampSecFrac; pIf->formatTimestamp3339 = formatTimestamp3339; pIf->formatTimestamp3164 = formatTimestamp3164; finalize_it: diff --git a/runtime/datetime.h b/runtime/datetime.h index fcb78172..1012ccc1 100644 --- a/runtime/datetime.h +++ b/runtime/datetime.h @@ -43,8 +43,9 @@ BEGINinterface(datetime) /* name must also be changed in ENDinterface macro! */ int (*formatTimestampToPgSQL)(struct syslogTime *ts, char *pDst, size_t iLenDst); int (*formatTimestamp3339)(struct syslogTime *ts, char* pBuf, size_t iLenBuf); int (*formatTimestamp3164)(struct syslogTime *ts, char* pBuf, size_t iLenBuf); + int (*formatTimestampSecFrac)(struct syslogTime *ts, char* pBuf, size_t iLenBuf); ENDinterface(datetime) -#define datetimeCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ +#define datetimeCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(datetime); diff --git a/runtime/msg.c b/runtime/msg.c index f195d3bd..e2d0b54c 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -279,6 +279,8 @@ CODESTARTobjDestruct(msg) free(pThis->pszRcvdAt3164); if(pThis->pszRcvdAt3339 != NULL) free(pThis->pszRcvdAt3339); + if(pThis->pszRcvdAt_SecFrac != NULL) + free(pThis->pszRcvdAt_SecFrac); if(pThis->pszRcvdAt_MySQL != NULL) free(pThis->pszRcvdAt_MySQL); if(pThis->pszRcvdAt_PgSQL != NULL) @@ -287,6 +289,8 @@ CODESTARTobjDestruct(msg) free(pThis->pszTIMESTAMP3164); if(pThis->pszTIMESTAMP3339 != NULL) free(pThis->pszTIMESTAMP3339); + if(pThis->pszTIMESTAMP_SecFrac != NULL) + free(pThis->pszTIMESTAMP_SecFrac); if(pThis->pszTIMESTAMP_MySQL != NULL) free(pThis->pszTIMESTAMP_MySQL); if(pThis->pszTIMESTAMP_PgSQL != NULL) @@ -738,6 +742,17 @@ char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt) } MsgUnlock(pM); return(pM->pszTIMESTAMP3339); + case tplFmtSecFrac: + MsgLock(pM); + if(pM->pszTIMESTAMP_SecFrac == NULL) { + if((pM->pszTIMESTAMP_SecFrac = malloc(10)) == NULL) { + MsgUnlock(pM); + return ""; /* TODO: check this: can it cause a free() of constant memory?) */ + } + datetime.formatTimestampSecFrac(&pM->tTIMESTAMP, pM->pszTIMESTAMP3339, 10); + } + MsgUnlock(pM); + return(pM->pszTIMESTAMP_SecFrac); } return "INVALID eFmt OPTION!"; } @@ -803,6 +818,17 @@ char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt) } MsgUnlock(pM); return(pM->pszRcvdAt3339); + case tplFmtSecFrac: + MsgLock(pM); + if(pM->pszRcvdAt_SecFrac == NULL) { + if((pM->pszRcvdAt_SecFrac = malloc(10)) == NULL) { + MsgUnlock(pM); + return ""; /* TODO: check this: can it cause a free() of constant memory?) */ + } + datetime.formatTimestampSecFrac(&pM->tRcvdAt, pM->pszRcvdAt_SecFrac, 10); + } + MsgUnlock(pM); + return(pM->pszRcvdAt_SecFrac); } return "INVALID eFmt OPTION!"; } diff --git a/runtime/msg.h b/runtime/msg.h index 084123b7..c428237a 100644 --- a/runtime/msg.h +++ b/runtime/msg.h @@ -100,6 +100,7 @@ struct msg { struct syslogTime tRcvdAt;/* time the message entered this program */ char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 charcters) */ char *pszRcvdAt3339; /* time as RFC3164 formatted string (32 charcters at most) */ + char *pszRcvdAt_SecFrac;/* time just as fractional seconds (6 charcters) */ char *pszRcvdAt_MySQL; /* rcvdAt as MySQL formatted string (always 14 charcters) */ char *pszRcvdAt_PgSQL; /* rcvdAt as PgSQL formatted string (always 21 characters) */ struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */ @@ -107,6 +108,7 @@ struct msg { char *pszTIMESTAMP3339; /* TIMESTAMP as RFC3339 formatted string (32 charcters at most) */ char *pszTIMESTAMP_MySQL;/* TIMESTAMP as MySQL formatted string (always 14 charcters) */ char *pszTIMESTAMP_PgSQL;/* TIMESTAMP as PgSQL formatted string (always 21 characters) */ + char *pszTIMESTAMP_SecFrac;/* TIMESTAMP fractional seconds (always 6 characters) */ int msgFlags; /* flags associated with this message */ }; @@ -440,6 +440,8 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe) pTpe->data.field.eDateFormat = tplFmtRFC3164Date; } else if(!strcmp((char*)Buf, "date-rfc3339")) { pTpe->data.field.eDateFormat = tplFmtRFC3339Date; + } else if(!strcmp((char*)Buf, "date-subseconds")) { + pTpe->data.field.eDateFormat = tplFmtSecFrac; } else if(!strcmp((char*)Buf, "lowercase")) { pTpe->data.field.eCaseConv = tplCaseConvLower; } else if(!strcmp((char*)Buf, "uppercase")) { @@ -47,7 +47,8 @@ struct template { enum EntryTypes { UNDEFINED = 0, CONSTANT = 1, FIELD = 2 }; enum tplFormatTypes { tplFmtDefault = 0, tplFmtMySQLDate = 1, - tplFmtRFC3164Date = 2, tplFmtRFC3339Date = 3, tplFmtPgSQLDate = 4 }; + tplFmtRFC3164Date = 2, tplFmtRFC3339Date = 3, tplFmtPgSQLDate = 4, + tplFmtSecFrac = 5}; enum tplFormatCaseConvTypes { tplCaseConvNo = 0, tplCaseConvUpper = 1, tplCaseConvLower = 2 }; #include "msg.h" |