diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-05-30 15:18:03 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-05-30 15:18:03 +0200 |
commit | 6a815063f37e7126f63fa00038f2d050574a6d52 (patch) | |
tree | 236a11b836b3a591dcb72056d56888875ef521d2 | |
parent | 99f18190a1f911224d45ca61706ae3fbc9ad7a80 (diff) | |
download | rsyslog-6a815063f37e7126f63fa00038f2d050574a6d52.tar.gz rsyslog-6a815063f37e7126f63fa00038f2d050574a6d52.tar.xz rsyslog-6a815063f37e7126f63fa00038f2d050574a6d52.zip |
capability for replacement text in no match regex case added
implemented in property replacer: if a regular expression does not match,
it can now either return "**NO MATCH** (default, as before), a blank
property or the full original property text
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | doc/property_replacer.html | 13 | ||||
-rw-r--r-- | runtime/msg.c | 31 | ||||
-rw-r--r-- | template.c | 25 | ||||
-rw-r--r-- | template.h | 5 |
5 files changed, 59 insertions, 18 deletions
@@ -4,6 +4,9 @@ Version 3.19.5 (rgerhards), 2008-05-?? (previously BRE was permitted only) - provided ability to specify that a regular expression submatch shall be used inside the property replacer +- implemented in property replacer: if a regular expression does not match, + it can now either return "**NO MATCH** (default, as before), a blank + property or the full original property text --------------------------------------------------------------------------- Version 3.19.4 (rgerhards), 2008-05-27 - implemented x509/certvalid gtls auth mode diff --git a/doc/property_replacer.html b/doc/property_replacer.html index 992bf8e0..b6eaae0f 100644 --- a/doc/property_replacer.html +++ b/doc/property_replacer.html @@ -207,16 +207,23 @@ sequence with a regular expression is: "%msg:R:.*Sev:. \(.*\) \[.*--end%"</p> <p>It is possible to specify some parametes after the "R". These are comma-separated. They are: -<p>R,<regexp-type>,<submatch> +<p>R,<regexp-type>,<submatch>,<nomatch> <p>regexp-type is either "BRE" for Posix basic regular expressions or "ERE" for extended ones. The string must be given in upper case. The default is "BRE" to be consistent with earlier versions of rsyslog that did not support ERE. The submatch identifies the submatch to be used with the result. A single digit is supported. Match 0 is the full match, while 1 to 9 are the acutal submatches. +<p>nomatch is either "DFLT", "BLANK" or "FIELD" (all upper case!). It tells +what to use if no match is found. With "DFLT", the strig "**NO MATCH**" is +used. This was the only supported value up to rsyslog 3.19.5. With "BLANK" +a blank text is used (""). Finally, "FIELD" uses the full property text +instead of the expression. Some folks have requested that, so it seems +to be useful. <p>The following is a sample of an ERE expression that takes the first -submatch from the message string: -<p>%msg:R,ERE,1:for (vlan[0-9]*):--end% +submatch from the message string and replaces the expression with +the full field if no match is found: +<p>%msg:R,ERE,1,FIELD:for (vlan[0-9]*):--end% <p><b>Also, extraction can be done based on so-called "fields"</b>. To do so, place a "F" into FromChar. A field in its current definition is anything that is delimited by a delimiter diff --git a/runtime/msg.c b/runtime/msg.c index 2798b7be..a90416ff 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -1844,25 +1844,30 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, if(objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { if (0 != regexp.regexec(&pTpe->data.field.re, pRes, nmatch, pmatch, 0)) { /* we got no match! */ - if (*pbMustBeFreed == 1) { - free(pRes); - *pbMustBeFreed = 0; + if(pTpe->data.field.nomatchAction != TPL_REGEX_NOMATCH_USE_WHOLE_FIELD) { + if (*pbMustBeFreed == 1) { + free(pRes); + *pbMustBeFreed = 0; + } + if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR) + return "**NO MATCH**"; + else + return ""; } - return "**NO MATCH**"; } else { -{int i; for(i = 0 ; i < 10 ; ++i) { -dbgprintf("rqtd regex match (nmatch %d) # %d, idx %d: so %d, eo %d\n", nmatch, pTpe->data.field.iMatchToUse, i, -pmatch[i].rm_so, -pmatch[i].rm_eo); -}} /* Match- but did it match the one we wanted? */ /* we got no match! */ if(pmatch[pTpe->data.field.iMatchToUse].rm_so == -1) { - if (*pbMustBeFreed == 1) { - free(pRes); - *pbMustBeFreed = 0; + if(pTpe->data.field.nomatchAction != TPL_REGEX_NOMATCH_USE_WHOLE_FIELD) { + if (*pbMustBeFreed == 1) { + free(pRes); + *pbMustBeFreed = 0; + } + if(pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR) + return "**NO MATCH**"; + else + return ""; } - return "**NO MATCH**"; } /* OK, we have a usable match - we now need to malloc pB */ int iLenBuf; @@ -521,10 +521,10 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl) /* first come the regex type */ if(*p == ',') { ++p; /* eat ',' */ - if(*p == 'B' && *(p+1) == 'R' && *(p+2) == 'E' && *(p+3) == ',') { + if(p[0] == 'B' && p[1] == 'R' && p[2] == 'E' && (p[3] == ',' || p[3] == ':')) { pTpe->data.field.typeRegex = TPL_REGEX_BRE; p += 3; /* eat indicator sequence */ - } else if(*p == 'E' && *(p+1) == 'R' && *(p+2) == 'E' && *(p+3) == ',') { + } else if(p[0] == 'E' && p[1] == 'R' && p[2] == 'E' && (p[3] == ',' || p[3] == ':')) { pTpe->data.field.typeRegex = TPL_REGEX_ERE; p += 3; /* eat indicator sequence */ } else { @@ -546,6 +546,27 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl) } } + /* now pull what to do if we do not find a match */ + if(*p == ',') { + ++p; /* eat ',' */ + if(p[0] == 'D' && p[1] == 'F' && p[2] == 'L' && p[3] == 'T' + && (p[4] == ',' || p[4] == ':')) { + pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_DFLTSTR; + p += 4; /* eat indicator sequence */ + } else if(p[0] == 'B' && p[1] == 'L' && p[2] == 'A' && p[3] == 'N' && p[4] == 'K' + && (p[5] == ',' || p[5] == ':')) { + pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_BLANK; + p += 5; /* eat indicator sequence */ + } else if(p[0] == 'F' && p[1] == 'I' && p[2] == 'E' && p[3] == 'L' && p[4] == 'D' + && (p[5] == ',' || p[5] == ':')) { + pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_WHOLE_FIELD; + p += 5; /* eat indicator sequence */ + } else { + errmsg.LogError(NO_ERRCODE, "error: invalid regular expression type, rest of line %s", + (char*) p); + } + } + if(*p != ':') { /* There is something more than an R , this is invalid ! */ /* Complain on extra characters */ @@ -73,6 +73,11 @@ struct templateEntry { TPL_REGEX_BRE = 0, /* posix BRE */ TPL_REGEX_ERE = 1 /* posix ERE */ } typeRegex; + enum { + TPL_REGEX_NOMATCH_USE_DFLTSTR = 0, /* use the (old style) default "**NO MATCH**" string */ + TPL_REGEX_NOMATCH_USE_BLANK = 1, /* use a blank string */ + TPL_REGEX_NOMATCH_USE_WHOLE_FIELD = 2 /* use the full field contents that we were searching in*/ + } nomatchAction; /**< what to do if we do not have a match? */ #endif unsigned has_fields; /* support for field-counting: field to extract */ |