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

Reply via email to