Hi,
I am going to use the pm_pattern module to filter/parse tens to
hundreds types of messages, so I made another patch, which allows to
define pattern hierarchies: the <pattern> element can be nested now
(to arbitrary level).
I found this extremely useful: before matching the inner (child)
<pattern>s, the code applies all the capturedfield/set/exec rules from
the "parent" <pattern>, so the children can test the already partially
parsed message. Not only it simplifies the XML code: the pattern
hierarchy, when properly designed, can speed up the whole module a
lot. Real XML examples upon request ;-) Now you already know what was
the previous "external XML entity support" userful for...
The patch should not influence current behavior: if you do not nest
patterns, the module works like before. In particular, when group's
<matchfield>s match, but none of its _first-level_ patterns matches,
the code continues to evaluate next groups. [If any of first-level
patterns matches, no more groups are evaluated].
The attached patch does not contain the generated file
patterndb_parser.c (so this message fits in the mailing list limit).
Milan
diff -Naur nxlog-ce-2.8.1248.old/src/modules/processor/pattern/patterndb.c nxlog-ce-2.8.1248/src/modules/processor/pattern/patterndb.c
--- nxlog-ce-2.8.1248.old/src/modules/processor/pattern/patterndb.c 2016-01-10 18:46:45.359879681 +0100
+++ nxlog-ce-2.8.1248/src/modules/processor/pattern/patterndb.c 2016-01-10 18:48:32.514254640 +0100
@@ -3,6 +3,8 @@
* See the file LICENSE in the source root for licensing terms.
* Website: http://nxlog.org
* Author: Botond Botyanszki <botond.botyans...@nxlog.org>
+ * Modified: Milan Krcmar <milan.krc...@gmail.com> Sun, 10 Jan 2016
+ * - recursive (nested) <pattern> elements
*/
#include "patterndb.h"
@@ -81,17 +83,16 @@
-void nx_patterngroup_add_pattern(nx_patterngroup_t *group, nx_pattern_t *pattern)
+void nx_patterns_add_pattern(nx_patterns_t *patterns, nx_pattern_t *pattern)
{
- ASSERT(group != NULL);
+ ASSERT(patterns != NULL);
ASSERT(pattern != NULL);
if ( NX_DLIST_FIRST(pattern->matchfields) == NULL )
{
throw_msg("pattern has no matchfields");
}
- pattern->group = group;
- NX_DLIST_INSERT_TAIL(group->patterns, pattern, link);
+ NX_DLIST_INSERT_TAIL(patterns, pattern, link);
}
@@ -585,24 +586,103 @@
+static nx_logdata_t *nx_patterndb_match_patterns(nx_module_t *module,
+ nx_logdata_t *logdata,
+ nx_patterns_t *patterns,
+ const nx_pattern_t **matched)
+{
+ nx_pattern_t *pattern, *tmppattern;
+ nx_logdata_field_list_t addfields;
+ nx_logdata_field_t *field;
+
+ ASSERT(module != NULL);
+ ASSERT(logdata != NULL);
+ ASSERT(patterns != NULL);
+ ASSERT(matched != NULL);
+
+ NX_DLIST_INIT(&addfields, nx_logdata_field_t, link);
+
+ for ( pattern = NX_DLIST_FIRST(patterns);
+ pattern != NULL;
+ pattern = NX_DLIST_NEXT(pattern, link) )
+
+ {
+ //log_debug("matching pattern '%ld'", pattern->id);
+
+ if ( nx_patterndb_match_matchfields(logdata, pattern->matchfields, &addfields, FALSE, pattern->name) == TRUE )
+ { // if we get here all fields matched, i.e. the pattern matches
+ while ( (field = NX_DLIST_FIRST(&addfields)) != NULL )
+ { // now add captured fields
+ NX_DLIST_REMOVE(&addfields, field, link);
+ nx_logdata_set_field(logdata, field);
+ }
+
+ (pattern->matchcnt)++;
+ if ( ((tmppattern = NX_DLIST_PREV(pattern, link)) != NULL) &&
+ (tmppattern->matchcnt < pattern->matchcnt) )
+ { // advance pattern in list for optimized matching
+ NX_DLIST_REMOVE(patterns, pattern, link);
+ NX_DLIST_INSERT_BEFORE(patterns, tmppattern, pattern, link);
+ }
+
+ // add SET fields to logdata
+ if ( pattern->setfields != NULL )
+ {
+ for ( field = NX_DLIST_FIRST(pattern->setfields);
+ field != NULL;
+ field = NX_DLIST_NEXT(field, link) )
+ {
+ //log_debug("setting %s (type: %s)", setfield->key, nx_value_type_to_string(setfield->value->type));
+ nx_logdata_set_field_value(logdata, field->key,
+ nx_value_clone(NULL, field->value));
+ }
+ }
+
+ if ( pattern->exec != NULL )
+ {
+ logdata = nx_patterndb_pattern_exec(module, logdata, pattern);
+ if ( logdata == NULL ) { //drop()
+ *matched = pattern;
+ break;
+ }
+ }
+
+ if ( pattern->subpatterns != NULL )
+ {
+ logdata = nx_patterndb_match_patterns(module, logdata, pattern->subpatterns, matched);
+ if ( *matched != NULL )
+ break;
+ }
+
+ nx_logdata_set_integer(logdata, "PatternID", pattern->id);
+ nx_logdata_set_string(logdata, "PatternName", pattern->name);
+ *matched = pattern;
+
+ break;
+ }
+
+ while ( (field = NX_DLIST_FIRST(&addfields)) != NULL )
+ { // clear all setfields
+ NX_DLIST_REMOVE(&addfields, field, link);
+ nx_logdata_field_free(field);
+ }
+ }
+
+ return ( logdata );
+}
+
nx_logdata_t *nx_patterndb_match_logdata(nx_module_t *module,
nx_logdata_t *logdata,
nx_patterndb_t *patterndb,
const nx_pattern_t **matched)
{
- nx_pattern_t *pattern, *prevpattern;
nx_patterngroup_t *group;
- nx_logdata_field_t *tmpfield;
- nx_logdata_field_list_t addfields;
- nx_logdata_field_t *setfield;
ASSERT(module != NULL);
ASSERT(logdata != NULL);
ASSERT(patterndb != NULL);
ASSERT(matched != NULL);
- NX_DLIST_INIT(&addfields, nx_logdata_field_t, link);
-
for ( group = NX_DLIST_FIRST(patterndb->groups);
group != NULL;
group = NX_DLIST_NEXT(group, link) )
@@ -614,58 +694,11 @@
continue;
}
- for ( pattern = NX_DLIST_FIRST(group->patterns);
- pattern != NULL;
- pattern = NX_DLIST_NEXT(pattern, link) )
- {
- //log_debug("matching pattern '%ld'", pattern->id);
-
- if ( nx_patterndb_match_matchfields(logdata, pattern->matchfields, &addfields, FALSE, pattern->name) == TRUE )
- { // if we get here all fields matched, i.e. the pattern matches
- *matched = pattern;
- while ( (tmpfield = NX_DLIST_FIRST(&addfields)) != NULL )
- { // now add captured fields
- NX_DLIST_REMOVE(&addfields, tmpfield, link);
- nx_logdata_set_field(logdata, tmpfield);
- }
-
- (pattern->matchcnt)++;
- if ( ((prevpattern = NX_DLIST_PREV(pattern, link)) != NULL) &&
- (prevpattern->matchcnt < pattern->matchcnt) )
- { // advance pattern in list for optimized matching
- NX_DLIST_REMOVE(group->patterns, pattern, link);
- NX_DLIST_INSERT_BEFORE(group->patterns, prevpattern, pattern, link);
- }
-
- nx_logdata_set_integer(logdata, "PatternID", pattern->id);
- nx_logdata_set_string(logdata, "PatternName", pattern->name);
-
- // add SET fields to logdata
- if ( pattern->setfields != NULL )
- {
- for ( setfield = NX_DLIST_FIRST(pattern->setfields);
- setfield != NULL;
- setfield = NX_DLIST_NEXT(setfield, link) )
- {
- //log_debug("setting %s (type: %s)", setfield->key, nx_value_type_to_string(setfield->value->type));
- nx_logdata_set_field_value(logdata, setfield->key,
- nx_value_clone(NULL, setfield->value));
- }
- }
-
- if ( pattern->exec != NULL )
- {
- logdata = nx_patterndb_pattern_exec(module, logdata, pattern);
- }
- return ( logdata );
- }
-
- while ( (tmpfield = NX_DLIST_FIRST(&addfields)) != NULL )
- { // clear all setfields
- NX_DLIST_REMOVE(&addfields, tmpfield, link);
- nx_logdata_field_free(tmpfield);
- }
- }
+ logdata = nx_patterndb_match_patterns(module, logdata, group->patterns, matched);
+ if ( *matched != NULL )
+ {
+ break;
+ }
}
return ( logdata );
diff -Naur nxlog-ce-2.8.1248.old/src/modules/processor/pattern/patterndb.h nxlog-ce-2.8.1248/src/modules/processor/pattern/patterndb.h
--- nxlog-ce-2.8.1248.old/src/modules/processor/pattern/patterndb.h 2016-01-10 18:46:45.359879681 +0100
+++ nxlog-ce-2.8.1248/src/modules/processor/pattern/patterndb.h 2016-01-10 18:47:37.027096015 +0100
@@ -3,6 +3,8 @@
* See the file LICENSE in the source root for licensing terms.
* Website: http://nxlog.org
* Author: Botond Botyanszki <botond.botyans...@nxlog.org>
+ * Modified: Milan Krcmar <milan.krc...@gmail.com> Sun, 10 Jan 2016
+ * - recursive (nested) <pattern> elements
*/
#ifndef __NX_PATTERNDB_H
@@ -71,9 +73,9 @@
int64_t id;
nx_pattern_matchfields_t *matchfields;
int64_t matchcnt;
- nx_patterngroup_t *group; ///< pointer to the group this belongs to
nx_logdata_field_list_t *setfields;
nx_expr_statement_list_t *exec; ///< Statement blocks to execute
+ nx_patterns_t *subpatterns;
};
@@ -113,7 +115,7 @@
nx_patterngroup_t *nx_patterngroup_new(nx_patterndb_t *patterndb);
nx_pattern_t *nx_pattern_new(nx_patterndb_t *patterndb);
nx_pattern_matchfield_t *nx_pattern_matchfield_new(nx_patterndb_t *patterndb);
-void nx_patterngroup_add_pattern(nx_patterngroup_t *group, nx_pattern_t *pattern);
+void nx_patterns_add_pattern(nx_patterns_t *patterns, nx_pattern_t *pattern);
void nx_patterndb_add_group(nx_patterndb_t *patterndb, nx_patterngroup_t *group);
void nx_pattern_add_matchfield(apr_pool_t *pool,
nx_pattern_t *pattern,
diff -Naur nxlog-ce-2.8.1248.old/src/modules/processor/pattern/patterndb_parser.xcc nxlog-ce-2.8.1248/src/modules/processor/pattern/patterndb_parser.xcc
--- nxlog-ce-2.8.1248.old/src/modules/processor/pattern/patterndb_parser.xcc 2016-01-10 18:46:45.363879620 +0100
+++ nxlog-ce-2.8.1248/src/modules/processor/pattern/patterndb_parser.xcc 2016-01-10 18:47:37.047095726 +0100
@@ -9,6 +9,8 @@
* Modified: Milan Krcmar <milan.krc...@gmail.com> Sat, 09 Jan 2016
* - add line numbers to exception handler's output
* - allow the parsed XML to reference external system entities
+ * Modified: Milan Krcmar <milan.krc...@gmail.com> Sun, 10 Jan 2016
+ * - recursive (nested) <pattern> elements
*/
#include "patterndb.h"
@@ -126,7 +128,7 @@
<child name="description" maxOccurs="1"/>
<child name="pattern">
<![CDATA[
- nx_patterngroup_add_pattern($$, $?);
+ nx_patterns_add_pattern($$->patterns, $?);
]]>
</child>
<child name="matchfield">
@@ -165,6 +167,15 @@
xcc_get_linenum($X), 1); //TODO linepos
]]>
</child>
+ <child name="pattern">
+ <![CDATA[
+ if ( $$->subpatterns == NULL ) {
+ $$->subpatterns = apr_pcalloc(XCC_GET_PATTERNDB_POOL($X), sizeof(nx_patterns_t));
+ NX_DLIST_INIT($$->subpatterns, nx_patterns_t, link);
+ }
+ nx_patterns_add_pattern($$->subpatterns, $?);
+ ]]>
+ </child>
<child name="testcase">
<![CDATA[
//FIXME
------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
nxlog-ce-users mailing list
nxlog-ce-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nxlog-ce-users