diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2013-03-29 16:09:19 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2013-03-29 16:09:19 +0100 |
commit | 7b45d0b4d2caa27df4835ca59617bd869ee34442 (patch) | |
tree | d30fbc00ca571f050c60eeede91a62fab8684136 | |
parent | 1b2f93da31d0331244aa7c72068f4ec324e2cb71 (diff) | |
parent | 474877b9d7912a3d2abc2a350dbc41e4c3b050e4 (diff) | |
download | rsyslog-7b45d0b4d2caa27df4835ca59617bd869ee34442.tar.gz rsyslog-7b45d0b4d2caa27df4835ca59617bd869ee34442.tar.bz2 rsyslog-7b45d0b4d2caa27df4835ca59617bd869ee34442.zip |
Merge branch 'v7-stable-info'
Conflicts:
ChangeLog
template.c
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | doc/property_replacer.html | 6 | ||||
-rw-r--r-- | doc/rsyslog_conf_templates.html | 2 | ||||
-rw-r--r-- | runtime/msg.c | 17 | ||||
-rw-r--r-- | template.c | 44 | ||||
-rw-r--r-- | template.h | 1 |
6 files changed, 56 insertions, 15 deletions
@@ -1,6 +1,7 @@ --------------------------------------------------------------------------- Version 7.3.10 [devel] 2013-04-?? - added RainerScript re_extract() function +- templates now permit substring extraction relative to end-of-string - bugfix: imuxsock aborted under some conditions regression from ratelimiting enhancements --------------------------------------------------------------------------- diff --git a/doc/property_replacer.html b/doc/property_replacer.html index c7624b2d..13ff41c3 100644 --- a/doc/property_replacer.html +++ b/doc/property_replacer.html @@ -413,6 +413,12 @@ option when forwarding to remote hosts - they may treat the date as invalid <td>just the subseconds of a timestamp (always 0 for a low precision timestamp)</td> </tr> <tr> +<td>pos-end-relative</td> + <td>the from and to position is relative to the end of the string + instead of the usual start of string. (available since rsyslog v7.3.10) + </td> +</tr> +<tr> <td><b>ControlCharacters</b></td> <td>Option values for how to process control characters</td> </tr> diff --git a/doc/rsyslog_conf_templates.html b/doc/rsyslog_conf_templates.html index 0c189100..9a6e1619 100644 --- a/doc/rsyslog_conf_templates.html +++ b/doc/rsyslog_conf_templates.html @@ -134,6 +134,8 @@ csv-data is generated, "json", which formats proper json content (but without a header) and "jsonf", which formats as a complete json field. <li>position.from - obtain substring starting from this position (1 is the first position) <li>position.to - obtain substring up to this position +<li>position.relativeToEnd - the from and to position is relative to the end of the string + instead of the usual start of string. (available since rsyslog v7.3.10) <li>field.number - obtain this field match <li>field.delimiter - decimal value of delimiter character for field extraction <li>regex.expression - expression to use diff --git a/runtime/msg.c b/runtime/msg.c index c302a050..1e61e632 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -3230,13 +3230,20 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, uchar *pSb; iFrom = pTpe->data.field.iFromPos; iTo = pTpe->data.field.iToPos; - /* need to zero-base to and from (they are 1-based!) */ - if(iFrom > 0) - --iFrom; - if(iTo > 0) - --iTo; if(bufLen == -1) bufLen = ustrlen(pRes); +dbgprintf("DDDD: orginal iFrom %u, iTo %u, len %u\n", iFrom, iTo, bufLen); + if(pTpe->data.field.options.bFromPosEndRelative) { + iFrom = (bufLen < iFrom) ? 0 : bufLen - iFrom; + iTo = (bufLen < iTo)? 0 : bufLen - iTo; +dbgprintf("DDDD: now iFrom %u, iTo %u\n", iFrom, iTo); + } else { + /* need to zero-base to and from (they are 1-based!) */ + if(iFrom > 0) + --iFrom; + if(iTo > 0) + --iTo; + } if(iFrom == 0 && iTo >= bufLen) { /* in this case, the requested string is a superset of what we already have, * so there is no need to do any processing. This is a frequent case for size-limited @@ -79,6 +79,7 @@ static struct cnfparamdescr cnfparamdescrProperty[] = { { "format", eCmdHdlrString, 0 }, { "position.from", eCmdHdlrInt, 0 }, { "position.to", eCmdHdlrInt, 0 }, + { "position.relativetoend", eCmdHdlrBinary, 0 }, { "field.number", eCmdHdlrInt, 0 }, { "field.delimiter", eCmdHdlrInt, 0 }, { "regex.expression", eCmdHdlrString, 0 }, @@ -712,6 +713,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, "pos-end-relative")) { + pTpe->data.field.options.bFromPosEndRelative = 1; } else if(!strcmp((char*)Buf, "csv")) { if(pTpe->data.field.options.bJSON || pTpe->data.field.options.bJSONf) { errmsg.LogError(0, NO_ERRCODE, "error: can only specify " @@ -1057,18 +1060,27 @@ do_Parameter(uchar **pp, struct template *pTpl) #endif /* #ifdef FEATURE_REGEXP */ } - if(pTpe->data.field.iToPos < pTpe->data.field.iFromPos) { - iNum = pTpe->data.field.iToPos; - pTpe->data.field.iToPos = pTpe->data.field.iFromPos; - pTpe->data.field.iFromPos = iNum; - } - /* check options */ if(*p == ':') { ++p; /* eat ':' */ doOptions(&p, pTpe); } + if(pTpe->data.field.options.bFromPosEndRelative) { + if(pTpe->data.field.iToPos > pTpe->data.field.iFromPos) { + iNum = pTpe->data.field.iToPos; + pTpe->data.field.iToPos = pTpe->data.field.iFromPos; + pTpe->data.field.iFromPos = iNum; + } + } else { + if(pTpe->data.field.iToPos < pTpe->data.field.iFromPos) { + iNum = pTpe->data.field.iToPos; + pTpe->data.field.iToPos = pTpe->data.field.iFromPos; + pTpe->data.field.iFromPos = iNum; + } + } + + /* check field name */ if(*p == ':') { ++p; /* eat ':' */ @@ -1356,6 +1368,7 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o) int re_matchToUse = 0; int re_submatchToUse = 0; int bComplexProcessing = 0; + int bPosRelativeToEnd = 0; char *re_expr = NULL; struct cnfparamvals *pvals = NULL; enum {F_NONE, F_CSV, F_JSON, F_JSONF} formatType = F_NONE; @@ -1395,6 +1408,8 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o) } else if(!strcmp(pblkProperty.descr[i].name, "position.to")) { topos = pvals[i].val.d.n; bComplexProcessing = 1; + } else if(!strcmp(pblkProperty.descr[i].name, "position.relativetoend")) { + bPosRelativeToEnd = pvals[i].val.d.n; } else if(!strcmp(pblkProperty.descr[i].name, "field.number")) { fieldnum = pvals[i].val.d.n; bComplexProcessing = 1; @@ -1537,10 +1552,18 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o) topos = 2000000000; /* large enough ;) */ if(frompos == -1 && topos != -1) frompos = 0; - if(topos < frompos) { - errmsg.LogError(0, RS_RET_ERR, "position.to=%d is lower than postion.from=%d\n", - topos, frompos); - ABORT_FINALIZE(RS_RET_ERR); + if(bPosRelativeToEnd) { + if(topos > frompos) { + errmsg.LogError(0, RS_RET_ERR, "position.to=%d is higher than postion.from=%d in 'relativeToEnd' mode\n", + topos, frompos); + ABORT_FINALIZE(RS_RET_ERR); + } + } else { + if(topos < frompos) { + errmsg.LogError(0, RS_RET_ERR, "position.to=%d is lower than postion.from=%d\n", + topos, frompos); + ABORT_FINALIZE(RS_RET_ERR); + } } if(fieldnum != -1 && re_expr != NULL) { errmsg.LogError(0, RS_RET_ERR, "both field extraction and regex extraction " @@ -1613,6 +1636,7 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o) if(frompos != -1) { pTpe->data.field.iFromPos = frompos; pTpe->data.field.iToPos = topos; + pTpe->data.field.options.bFromPosEndRelative = bPosRelativeToEnd; } if(re_expr != NULL) { rsRetVal iRetLocal; @@ -119,6 +119,7 @@ struct templateEntry { unsigned bJSON: 1; /* format field JSON escaped */ unsigned bJSONf: 1; /* format field JSON *field* (n/v pair) */ unsigned bMandatory: 1; /* mandatory field - emit even if empty */ + unsigned bFromPosEndRelative: 1;/* is From/To-Pos relative to end of string? */ } options; /* options as bit fields */ } field; } data; |