diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2009-04-02 12:48:07 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2009-04-02 12:48:07 +0200 |
commit | 3954f2e166c3cbd78c71819c8d6c25120042dbcf (patch) | |
tree | 2c70fa3bb36f763490146e1fa6e205600f5afb34 | |
parent | e4f012eb60f6531f964557ba9eac54048ae2bef8 (diff) | |
download | rsyslog-3954f2e166c3cbd78c71819c8d6c25120042dbcf.tar.gz rsyslog-3954f2e166c3cbd78c71819c8d6c25120042dbcf.tar.xz rsyslog-3954f2e166c3cbd78c71819c8d6c25120042dbcf.zip |
added new "csv" property replacer option
to enable simple creation of CSV-formatted outputs (format
from RFC4180 is used)
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | doc/property_replacer.html | 14 | ||||
-rw-r--r-- | runtime/msg.c | 34 | ||||
-rw-r--r-- | template.c | 5 | ||||
-rw-r--r-- | template.h | 7 |
5 files changed, 58 insertions, 4 deletions
@@ -4,6 +4,8 @@ I only tweaked a very little bit. --------------------------------------------------------------------------- Version 4.1.6 [DEVEL] (rgerhards), 2009-03-?? +- added new "csv" property replacer options to enable simple creation + of CSV-formatted outputs (format from RFC4180 is used) - implemented function support in RainerScript. That means the engine parses and compile functions, as well as executes a few build-in ones. Dynamic loading and registration of functions is not yet diff --git a/doc/property_replacer.html b/doc/property_replacer.html index baf053f2..a6e9b518 100644 --- a/doc/property_replacer.html +++ b/doc/property_replacer.html @@ -314,6 +314,18 @@ case-insensitive. Currently, the following options are defined: <td>convert property text to uppercase only</td> </tr> <tr> +<td valign="top"><b>csv</b></td> +<td>formats the resulting field (after all modifications) in CSV format +as specified in <a href="http://www.ietf.org/rfc/rfc4180.txt">RFC 4180</a>. +Rsyslog will always use double quotes. Note that in order to have full CSV-formatted +text, you need to define a proper template. An example is this one: +<br>$template csvline,"%syslogtag:::csv%,%msg:::csv%" +<br>Most importantly, you need to provide the commas between the fields +inside the template. +<br><i>This feature was introduced in rsyslog 4.1.6.</i> +</td> +</tr> +<tr> <td><b>drop-last-lf</b></td> <td>The last LF in the message (if any), is dropped. Especially useful for PIX.</td> @@ -411,7 +423,7 @@ syntax</a>, this is where you actually use the property replacer.</li> [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p> <p><font size="2">This documentation is part of the <a href="http://www.rsyslog.com/">rsyslog</a> project.<br> -Copyright © 2008 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and +Copyright © 2008, 2009 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and <a href="http://www.adiscon.com/">Adiscon</a>. Released under the GNU GPL version 2 or higher.</font></p> diff --git a/runtime/msg.c b/runtime/msg.c index 9aa2ce84..5d1f21fd 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2405,6 +2405,40 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } } + /* finally, we need to check if the property should be formatted in CSV + * format (we use RFC 4180, and always use double quotes). As of this writing, + * this should be the last action carried out on the property, but in the + * future there may be reasons to change that. -- rgerhards, 2009-04-02 + */ + if(pTpe->data.field.options.bCSV) { + /* we need to obtain a private copy, as we need to at least add the double quotes */ + int iBufLen = strlen(pRes); + char *pBStart; + char *pDst; + char *pSrc; + /* the malloc may be optimized, we currently use the worst case... */ + pBStart = pDst = malloc((2 * iBufLen + 3) * sizeof(char)); + if(pDst == NULL) { + if(*pbMustBeFreed == 1) + free(pRes); + *pbMustBeFreed = 0; + return "**OUT OF MEMORY**"; + } + pSrc = pRes; + *pDst++ = '"'; /* starting quote */ + while(*pSrc) { + if(*pSrc == '"') + *pDst++ = '"'; /* need to add double double quote (see RFC4180) */ + *pDst++ = *pSrc++; + } + *pDst++ = '"'; /* ending quote */ + *pDst = '\0'; + if(*pbMustBeFreed == 1) + free(pRes); + pRes = pBStart; + *pbMustBeFreed = 1; + } + /*dbgprintf("MsgGetProp(\"%s\"): \"%s\"\n", pName, pRes); only for verbose debug logging */ return(pRes); } @@ -460,6 +460,8 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe) pTpe->data.field.options.bSecPathDrop = 1; } else if(!strcmp((char*)Buf, "secpath-replace")) { pTpe->data.field.options.bSecPathReplace = 1; + } else if(!strcmp((char*)Buf, "csv")) { + pTpe->data.field.options.bCSV = 1; } else { dbgprintf("Invalid field option '%s' specified - ignored.\n", Buf); } @@ -1105,6 +1107,9 @@ void tplPrintList(void) if(pTpe->data.field.options.bSPIffNo1stSP) { dbgprintf("[SP iff no first SP] "); } + if(pTpe->data.field.options.bCSV) { + dbgprintf("[format as CSV (RFC4180)]"); + } if(pTpe->data.field.options.bDropLastLF) { dbgprintf("[drop last LF in msg] "); } @@ -94,9 +94,10 @@ struct templateEntry { unsigned bSpaceCC: 1; /* change control characters to spaceescape? */ unsigned bEscapeCC: 1; /* escape control characters? */ unsigned bDropLastLF: 1; /* drop last LF char in msg (PIX!) */ - unsigned bSecPathDrop: 1; /* drop slashes, replace dots, empty string */ - unsigned bSecPathReplace: 1; /* replace slashes, replace dots, empty string */ - unsigned bSPIffNo1stSP: 1; /* replace slashes, replace dots, empty string */ + unsigned bSecPathDrop: 1; /* drop slashes, replace dots, empty string */ + unsigned bSecPathReplace: 1; /* replace slashes, replace dots, empty string */ + unsigned bSPIffNo1stSP: 1; /* replace slashes, replace dots, empty string */ + unsigned bCSV: 1; /* format field in CSV (RFC 4180) format */ } options; /* options as bit fields */ } field; } data; |