summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-05-30 15:18:03 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2008-05-30 15:18:03 +0200
commit6a815063f37e7126f63fa00038f2d050574a6d52 (patch)
tree236a11b836b3a591dcb72056d56888875ef521d2
parent99f18190a1f911224d45ca61706ae3fbc9ad7a80 (diff)
downloadrsyslog-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--ChangeLog3
-rw-r--r--doc/property_replacer.html13
-rw-r--r--runtime/msg.c31
-rw-r--r--template.c25
-rw-r--r--template.h5
5 files changed, 59 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index cbb150ad..f4de7554 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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,&lt;regexp-type&gt;,&lt;submatch&gt;
+<p>R,&lt;regexp-type&gt;,&lt;submatch&gt;,&lt;nomatch&gt;
<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;
diff --git a/template.c b/template.c
index bccc6516..2b336ba9 100644
--- a/template.c
+++ b/template.c
@@ -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 */
diff --git a/template.h b/template.h
index daeeb5fd..dff06583 100644
--- a/template.h
+++ b/template.h
@@ -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 */