[syslog-ng] [PATCH (3.4)] value-pairs: Implement key transformation functions.

Gergely Nagy algernon at balabit.hu
Fri Jun 10 12:59:35 CEST 2011


This is the implementation of the rekey() mechanism, a way to
transform the keys of a value-pairs() set.

The intended usage is as follows:

value-pairs(
  scope("everything")
  rekey(
    shift(".sdata.*" 1)
    add-prefix(".classification.*" "syslog-ng")
    replace("." "_")
  )
);

This would transform keys beginning with ".sdata." by shifting them
one char, getting rid of the dot. Then it would add a "syslog-ng"
prefix to every key that begins with ".classification.", so
".classification.rule_id" would become
"syslog-ng.classification.rule_id". Finally, it will replace the
leading dot with an underscore on all remaining keys.

Whenever he value-pairs stuff puts a key into the final set, it will
pipe them through the list of registered transformations. Each
transformator needs to have a ->match method, which determines whether
a given key should be transformed or not. If it should be, then the
key will be given to the ->transform function, and the result will be
used as the key, whatever it may be.

Once all keys are inserted, the ->reset function will be called, if it
exists. And when the value-pairs object is deinitializing, that will
call the transformators' ->destroy function aswell.

These functions are mandatory (except for reset), and they're part of
the ValuePairsTransform struct. All transform functions derive from
this one, and extend it with their own state variables.

Currently, three transformation functions exist: the three mentioned
in the example above.

shift() will take a string and an integer, and shift the string by the
given amount of characters (if the amount is 0 or negative, it will
just return the original).

add-prefix() will prepend a prefix.

And replace() will replace the given string with another, but only if
the key begins with the original string-part. It will not replace
patterns inside the key name, only at the beginning.

Signed-off-by: Gergely Nagy <algernon at balabit.hu>
---
 lib/Makefile.am               |    4 +-
 lib/cfg-grammar.y             |   17 +++
 lib/cfg-parser.c              |    4 +
 lib/value-pairs.c             |   56 ++++++++-
 lib/value-pairs.h             |    2 +
 lib/vptransform.c             |  292 +++++++++++++++++++++++++++++++++++++++++
 lib/vptransform.h             |   40 ++++++
 tests/unit/test_value_pairs.c |   44 +++++--
 8 files changed, 443 insertions(+), 16 deletions(-)
 create mode 100644 lib/vptransform.c
 create mode 100644 lib/vptransform.h

diff --git a/lib/Makefile.am b/lib/Makefile.am
index 26c9461..1a95fc2 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -77,7 +77,8 @@ pkginclude_HEADERS = 		\
 	tlscontext.h  		\
 	tlstransport.h		\
 	utils.h			\
-	value-pairs.h
+	value-pairs.h		\
+	vptransform.h
 
 # this is intentionally formatted so conflicts are less likely to arise. one name in every line.
 libsyslog_ng_la_SOURCES = \
@@ -137,6 +138,7 @@ libsyslog_ng_la_SOURCES = \
 	timeutils.c		\
 	utils.c			\
 	value-pairs.c		\
+	vptransform.c		\
 				\
 	cfg-lex.l		\
 	cfg-grammar.y		\
diff --git a/lib/cfg-grammar.y b/lib/cfg-grammar.y
index 994713e..5f032d5 100644
--- a/lib/cfg-grammar.y
+++ b/lib/cfg-grammar.y
@@ -276,6 +276,10 @@
 %token KW_PAIR                        10503
 %token KW_KEY                         10504
 %token KW_SCOPE                       10505
+%token KW_SHIFT                       10506
+%token KW_REKEY                       10507
+%token KW_ADD_PREFIX                  10508
+%token KW_REPLACE                     10509
 
 /* END_DECLS */
 
@@ -851,6 +855,7 @@ vp_option
 	  }
 	| KW_EXCLUDE '(' string ')'	         { value_pairs_add_exclude_glob(last_value_pairs, $3); free($3); }
 	| KW_SCOPE '(' vp_scope_list ')'
+	| KW_REKEY '(' vp_rekey_options ')'
 	;
 
 vp_scope_list
@@ -858,6 +863,18 @@ vp_scope_list
 	|
 	;
 
+vp_rekey_options
+	: vp_rekey_option vp_rekey_options
+	|
+	;
+
+vp_rekey_option
+	: KW_SHIFT '(' string LL_NUMBER ')' { value_pairs_add_transform(last_value_pairs, value_pairs_new_transform_shift($3, $4)); free($3); }
+	| KW_SHIFT '(' string ':' LL_NUMBER ')' { value_pairs_add_transform(last_value_pairs, value_pairs_new_transform_shift($3, $5)); free($3); }
+	| KW_ADD_PREFIX '(' string string ')' { value_pairs_add_transform(last_value_pairs, value_pairs_new_transform_add_prefix($3, $4)); free($3); free($4); }
+	| KW_REPLACE '(' string string ')' { value_pairs_add_transform(last_value_pairs, value_pairs_new_transform_replace($3, $4)); free($3); free($4); }
+	;
+
 /* END_RULES */
 
 
diff --git a/lib/cfg-parser.c b/lib/cfg-parser.c
index 589206a..bd5c76d 100644
--- a/lib/cfg-parser.c
+++ b/lib/cfg-parser.c
@@ -60,6 +60,10 @@ static CfgLexerKeyword main_keywords[] = {
   { "pair",               KW_PAIR, 0x0303 },
   { "key",                KW_KEY, 0x0303 },
   { "scope",              KW_SCOPE, 0x0303 },
+  { "rekey",              KW_REKEY, 0x0303 },
+  { "shift",              KW_SHIFT, 0x0303 },
+  { "add_prefix",         KW_ADD_PREFIX, 0x0303 },
+  { "replace",            KW_REPLACE, 0x0303 },
 
   /* option items */
   { "flags",              KW_FLAGS },
diff --git a/lib/value-pairs.c b/lib/value-pairs.c
index 484cb58..4f4ddc5 100644
--- a/lib/value-pairs.c
+++ b/lib/value-pairs.c
@@ -23,6 +23,7 @@
  */
 
 #include "value-pairs.h"
+#include "vptransform.h"
 #include "logmsg.h"
 #include "templates.h"
 #include "cfg-parser.h"
@@ -30,11 +31,11 @@
 
 #include <string.h>
 
-
 struct _ValuePairs
 {
   GPatternSpec **excludes;
   GHashTable *vpairs;
+  GList *transforms;
 
   /* guint32 as CfgFlagHandler only supports 32 bit integers */
   guint32 scopes;
@@ -141,6 +142,26 @@ value_pairs_add_pair(ValuePairs *vp, GlobalConfig *cfg, const gchar *key, const
   g_hash_table_insert(vp->vpairs, g_strdup(key), t);
 }
 
+static gchar *
+vp_transform_apply (ValuePairs *vp, gchar *key)
+{
+  GList *l;
+  gchar *ckey = key;
+
+  if (!vp->transforms)
+    return ckey;
+
+  l = vp->transforms;
+  while (l)
+    {
+      ValuePairsTransform *t = (ValuePairsTransform *)l->data;
+      ckey = value_pairs_transform_apply(t, ckey);
+      l = g_list_next (l);
+    }
+
+  return ckey;
+}
+
 /* runs over the name-value pairs requested by the user (e.g. with value_pairs_add_pair) */
 static void
 vp_pairs_foreach(gpointer key, gpointer value, gpointer user_data)
@@ -157,7 +178,7 @@ vp_pairs_foreach(gpointer key, gpointer value, gpointer user_data)
   if (!vp->res->str[0])
     return;
 
-  g_hash_table_insert(scope_set, key, vp->res->str);
+  g_hash_table_insert(scope_set, vp_transform_apply (vp, key), vp->res->str);
   g_string_steal(vp->res);
 }
 
@@ -183,7 +204,7 @@ vp_msg_nvpairs_foreach(NVHandle handle, gchar *name,
         }
 
       /* NOTE: the key is a borrowed reference in the hash, and value is freed */
-      g_hash_table_insert(scope_set, name, g_strndup(value, value_len));
+      g_hash_table_insert(scope_set, vp_transform_apply(vp, name), g_strndup(value, value_len));
     }
 
   return FALSE;
@@ -231,7 +252,7 @@ vp_merge_set(ValuePairs *vp, LogMessage *msg, gint32 seq_num, ValuePairSpec *set
       if (!vp->res->str[0])
 	continue;
 
-      g_hash_table_insert(dest, set[i].name, vp->res->str);
+      g_hash_table_insert(dest, vp_transform_apply(vp, set[i].name), vp->res->str);
       g_string_steal(vp->res);
     }
 }
@@ -274,6 +295,17 @@ value_pairs_foreach (ValuePairs *vp, VPForeachFunc func,
   g_hash_table_foreach(scope_set, (GHFunc)func, user_data);
 
   g_hash_table_destroy(scope_set);
+
+  if (vp->transforms)
+    {
+      GList *l = vp->transforms;
+
+      do
+	{
+	  value_pairs_transform_reset((ValuePairsTransform *)l->data);
+	}
+      while ((l = g_list_next (l)) != NULL);
+    }
 }
 
 
@@ -349,6 +381,7 @@ void
 value_pairs_free (ValuePairs *vp)
 {
   gint i;
+  GList *l;
 
   g_hash_table_destroy(vp->vpairs);
 
@@ -356,9 +389,24 @@ value_pairs_free (ValuePairs *vp)
     g_pattern_spec_free(vp->excludes[i]);
   g_free(vp->excludes);
   g_string_free(vp->res, TRUE);
+
+  l = vp->transforms;
+  while (l)
+    {
+      value_pairs_transform_free((ValuePairsTransform *)l->data);
+
+      l = g_list_delete_link (l, l);
+    }
+  
   g_free(vp);
 }
 
+void
+value_pairs_add_transform(ValuePairs *vp, gpointer *vpt)
+{
+  vp->transforms = g_list_append(vp->transforms, vpt);
+}
+
 /* parse a value-pair specification from a command-line like environment */
 static gboolean
 vp_cmdline_parse_scope(const gchar *option_name, const gchar *value,
diff --git a/lib/value-pairs.h b/lib/value-pairs.h
index da26763..0a10423 100644
--- a/lib/value-pairs.h
+++ b/lib/value-pairs.h
@@ -35,6 +35,8 @@ gboolean value_pairs_add_scope(ValuePairs *vp, const gchar *scope);
 void value_pairs_add_exclude_glob(ValuePairs *vp, const gchar *pattern);
 void value_pairs_add_pair(ValuePairs *vp, GlobalConfig *cfg, const gchar *key, const gchar *value);
 
+void value_pairs_add_transform(ValuePairs *vp, gpointer *vpt);
+
 void value_pairs_foreach(ValuePairs *vp, VPForeachFunc func,
                          LogMessage *msg, gint32 seq_num,
                          gpointer user_data);
diff --git a/lib/vptransform.c b/lib/vptransform.c
new file mode 100644
index 0000000..1309092
--- /dev/null
+++ b/lib/vptransform.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2002-2011 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011 Gergely Nagy <algernon at balabit.hu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * As an additional exemption you are allowed to compile & link against the
+ * OpenSSL libraries as published by the OpenSSL project. See the file
+ * COPYING for details.
+ *
+ */
+
+#include "value-pairs.h"
+#include "vptransform.h"
+#include "templates.h"
+#include "cfg-parser.h"
+#include "misc.h"
+
+#include <string.h>
+
+typedef gboolean (*VPTransMatchFunc)(ValuePairsTransform *t, gchar *name);
+typedef gchar *(*VPTransFunc)(ValuePairsTransform *t, gchar *name);
+typedef void (*VPTransResetFunc)(ValuePairsTransform *t);
+typedef void (*VPTransDestroyFunc)(ValuePairsTransform *t);
+
+struct _ValuePairsTransform
+{
+  VPTransMatchFunc match;
+  VPTransFunc transform;
+  VPTransResetFunc reset;
+  VPTransDestroyFunc destroy;
+};
+
+typedef struct
+{
+  ValuePairsTransform super;
+
+  GPatternSpec *pattern;
+  gint amount;
+} VPTransShift;
+
+typedef struct
+{
+  ValuePairsTransform super;
+
+  GPatternSpec *pattern;
+  gchar *prefix;
+
+  GHashTable *cache;
+} VPTransAddPrefix;
+
+typedef struct
+{
+  ValuePairsTransform super;
+
+  gchar *old_prefix;
+  gchar *new_prefix;
+  gint new_prefix_len;
+  gint old_prefix_len;
+
+  GHashTable *cache;
+} VPTransReplace;
+
+static void
+vp_trans_init(ValuePairsTransform *t,
+	      VPTransMatchFunc match, VPTransFunc trans,
+	      VPTransResetFunc reset, VPTransDestroyFunc dest)
+{
+  if (!t)
+    return;
+
+  t->match = match;
+  t->transform = trans;
+  t->reset = reset;
+  t->destroy = dest;
+}
+
+void
+value_pairs_transform_reset(ValuePairsTransform *t)
+{
+  if (t->reset)
+    t->reset(t);
+}
+
+void
+value_pairs_transform_free(ValuePairsTransform *t)
+{
+  if (t->destroy)
+    t->destroy(t);
+  g_free(t);
+}
+
+gchar *
+value_pairs_transform_apply(ValuePairsTransform *t, gchar *key)
+{
+  if (t->match(t, key))
+    return t->transform(t, key);
+  return key;
+}
+
+/* add_prefix() */
+
+static gchar *
+vp_trans_add_prefix(ValuePairsTransform *t, gchar *name)
+{
+  VPTransAddPrefix *self = (VPTransAddPrefix *)t;
+  gpointer r;
+
+  r = g_hash_table_lookup(self->cache, name);
+  if (!r)
+    {
+      r = (gpointer)g_strconcat(self->prefix, name, NULL);
+      g_hash_table_insert(self->cache, g_strdup(name), r);
+    }
+  return r;
+}
+
+static void
+vp_trans_add_prefix_destroy(ValuePairsTransform *t)
+{
+  VPTransAddPrefix *self = (VPTransAddPrefix *)t;
+
+  g_pattern_spec_free(self->pattern);
+  g_hash_table_destroy(self->cache);
+  g_free(self->prefix);
+}
+
+static gboolean
+vp_trans_add_prefix_match(ValuePairsTransform *t, gchar *key)
+{
+  VPTransAddPrefix *self = (VPTransAddPrefix *)t;
+
+  return g_pattern_match_string(self->pattern, key);
+}
+
+static void
+vp_trans_add_prefix_reset(ValuePairsTransform *t)
+{
+  VPTransAddPrefix *self = (VPTransAddPrefix *)t;
+
+  if (self->cache)
+    g_hash_table_destroy(self->cache);
+
+  self->cache = g_hash_table_new_full(g_str_hash, g_str_equal,
+				      g_free, g_free);
+}
+
+ValuePairsTransform *
+value_pairs_new_transform_add_prefix (const gchar *glob, const gchar *prefix)
+{
+  VPTransAddPrefix *vpt;
+
+  vpt = g_new(VPTransAddPrefix, 1);
+  vp_trans_init((ValuePairsTransform *)vpt,
+		vp_trans_add_prefix_match, vp_trans_add_prefix,
+		vp_trans_add_prefix_reset, vp_trans_add_prefix_destroy);
+  vpt->pattern = g_pattern_spec_new(glob);
+  vpt->prefix = g_strdup(prefix);
+  vpt->cache = NULL;
+
+  vp_trans_add_prefix_reset((ValuePairsTransform *)vpt);
+
+  return (ValuePairsTransform *)vpt;
+}
+
+/* shift() */
+
+static gchar *
+vp_trans_shift(ValuePairsTransform *t, gchar* name)
+{
+  VPTransShift *self = (VPTransShift *)t;
+
+  if (self->amount <= 0)
+    return name;
+  return name + self->amount;
+}
+
+static void
+vp_trans_shift_destroy(ValuePairsTransform *t)
+{
+  VPTransShift *self = (VPTransShift *)t;
+
+  g_pattern_spec_free(self->pattern);
+}
+
+static gboolean
+vp_trans_shift_match(ValuePairsTransform *t, gchar *key)
+{
+  VPTransShift *self = (VPTransShift *)t;
+
+  return g_pattern_match_string(self->pattern, key);
+}
+
+ValuePairsTransform *
+value_pairs_new_transform_shift (const gchar *glob, gint amount)
+{
+  VPTransShift *vpt;
+
+  vpt = g_new(VPTransShift, 1);
+  vp_trans_init((ValuePairsTransform *)vpt,
+		vp_trans_shift_match, vp_trans_shift,
+		NULL, vp_trans_shift_destroy);
+
+  vpt->pattern = g_pattern_spec_new(glob);
+  vpt->amount = amount;
+
+  return (ValuePairsTransform *)vpt;
+}
+
+/* replace() */
+
+static gchar *
+vp_trans_replace(ValuePairsTransform *t, gchar *name)
+{
+  VPTransReplace *self = (VPTransReplace *)t;
+  gpointer r;
+
+  r = g_hash_table_lookup(self->cache, name);
+  if (!r)
+    {
+      r = g_malloc(strlen(name) - self->old_prefix_len + self->new_prefix_len + 1);
+
+      memcpy (r, self->new_prefix, self->new_prefix_len);
+      memcpy (r + self->new_prefix_len, name + self->old_prefix_len,
+	      strlen(name) - self->old_prefix_len + 1);
+      g_hash_table_insert(self->cache, g_strdup(name), r);
+    }
+  return r;
+}
+
+static void
+vp_trans_replace_destroy(ValuePairsTransform *t)
+{
+  VPTransReplace *self = (VPTransReplace *)t;
+
+  g_hash_table_destroy(self->cache);
+  g_free(self->old_prefix);
+  g_free(self->new_prefix);
+}
+
+static void
+vp_trans_replace_reset(ValuePairsTransform *t)
+{
+  VPTransReplace *self = (VPTransReplace *)t;
+
+  if (self->cache)
+    g_hash_table_destroy(self->cache);
+  self->cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+}
+
+static gboolean
+vp_trans_replace_match(ValuePairsTransform *t, gchar *key)
+{
+  VPTransReplace *self = (VPTransReplace *)t;
+
+  if (strncmp (self->old_prefix, key, self->old_prefix_len) == 0)
+    return TRUE;
+  return FALSE;
+}
+
+ValuePairsTransform *
+value_pairs_new_transform_replace(const gchar *prefix, const gchar *new_prefix)
+{
+  VPTransReplace *vpt;
+
+  vpt = g_new(VPTransReplace, 1);
+  vp_trans_init((ValuePairsTransform *)vpt,
+		vp_trans_replace_match, vp_trans_replace,
+		vp_trans_replace_reset, vp_trans_replace_destroy);
+
+  vpt->old_prefix = g_strdup(prefix);
+  vpt->old_prefix_len = strlen(prefix);
+  vpt->new_prefix = g_strdup(new_prefix);
+  vpt->new_prefix_len = strlen(vpt->new_prefix);
+  vpt->cache = NULL;
+
+  vp_trans_replace_reset ((ValuePairsTransform *)vpt);
+
+  return (ValuePairsTransform *)vpt;
+}
diff --git a/lib/vptransform.h b/lib/vptransform.h
new file mode 100644
index 0000000..6ede457
--- /dev/null
+++ b/lib/vptransform.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2011 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011 Gergely Nagy <algernon at balabit.hu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * As an additional exemption you are allowed to compile & link against the
+ * OpenSSL libraries as published by the OpenSSL project. See the file
+ * COPYING for details.
+ *
+ */
+
+#ifndef VPTRANSFORM_INCLUDED
+#define VPTRANSFORM_INCLUDED 1
+
+#include "value-pairs.h"
+
+typedef struct _ValuePairsTransform ValuePairsTransform;
+
+ValuePairsTransform *value_pairs_new_transform_add_prefix (const gchar *glob, const gchar *prefix);
+ValuePairsTransform *value_pairs_new_transform_shift (const gchar *glob, gint amount);
+ValuePairsTransform *value_pairs_new_transform_replace(const gchar *prefix, const gchar *new_prefix);
+
+void value_pairs_transform_free(ValuePairsTransform *t);
+gchar *value_pairs_transform_apply(ValuePairsTransform *t, gchar *key);
+void value_pairs_transform_reset(ValuePairsTransform *t);
+
+#endif
diff --git a/tests/unit/test_value_pairs.c b/tests/unit/test_value_pairs.c
index 67f933a..aeb1f32 100644
--- a/tests/unit/test_value_pairs.c
+++ b/tests/unit/test_value_pairs.c
@@ -1,4 +1,5 @@
 #include "value-pairs.h"
+#include "vptransform.h"
 #include "logmsg.h"
 #include "apphook.h"
 #include "cfg.h"
@@ -46,7 +47,7 @@ create_message(void)
 }
 
 void
-testcase(const gchar *scope, const gchar *exclude, const gchar *expected)
+testcase(const gchar *scope, const gchar *exclude, const gchar *expected, GPtrArray *transformers)
 {
   ValuePairs *vp;
   GList *vp_keys_list = NULL;
@@ -63,6 +64,14 @@ testcase(const gchar *scope, const gchar *exclude, const gchar *expected)
     value_pairs_add_exclude_glob(vp, exclude);
   value_pairs_add_pair(vp, configuration, "test.key", "$MESSAGE");
 
+  if (transformers)
+    {
+      gint i;
+
+      for (i = 0; i < transformers->len; i++)
+	value_pairs_add_transform(vp, g_ptr_array_index(transformers, i));
+    }
+
   args[0] = &vp_keys_list;
   args[1] = &test_key_found;
   value_pairs_foreach(vp, vp_keys_foreach, msg, 11, args);
@@ -88,6 +97,8 @@ testcase(const gchar *scope, const gchar *exclude, const gchar *expected)
 int
 main(int argc, char *argv[])
 {
+  GPtrArray *transformers;
+
   app_startup();
   putenv("TZ=MET-1METDST");
   tzset();
@@ -98,26 +109,37 @@ main(int argc, char *argv[])
   msg_format_options_init(&parse_options, configuration);
   parse_options.flags |= LP_SYSLOG_PROTOCOL;
 
-  testcase("rfc3164", NULL, "DATE,FACILITY,HOST,MESSAGE,PID,PRIORITY,PROGRAM");
-  testcase("rfc5424", NULL, "DATE,FACILITY,HOST,MESSAGE,MSGID,PID,PRIORITY,PROGRAM");
-  testcase("selected-macros", NULL, "DATE,FACILITY,HOST,MESSAGE,PID,PRIORITY,PROGRAM,SEQNUM,SOURCEIP,TAGS");
+  testcase("rfc3164", NULL, "DATE,FACILITY,HOST,MESSAGE,PID,PRIORITY,PROGRAM", NULL);
+  testcase("rfc5424", NULL, "DATE,FACILITY,HOST,MESSAGE,MSGID,PID,PRIORITY,PROGRAM", NULL);
+  testcase("selected-macros", NULL, "DATE,FACILITY,HOST,MESSAGE,PID,PRIORITY,PROGRAM,SEQNUM,SOURCEIP,TAGS", NULL);
 
-  testcase("nv-pairs", NULL, "HOST,MESSAGE,MSGID,PID,PROGRAM");
-  testcase("dot-nv-pairs", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip");
+  testcase("nv-pairs", NULL, "HOST,MESSAGE,MSGID,PID,PROGRAM", NULL);
+  testcase("dot-nv-pairs", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip", NULL);
 
-  testcase("sdata", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip");
+  testcase("sdata", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip", NULL);
 
-  testcase("all-nv-pairs", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip,HOST,MESSAGE,MSGID,PID,PROGRAM");
+  testcase("all-nv-pairs", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip,HOST,MESSAGE,MSGID,PID,PROGRAM", NULL);
 
-  testcase("everything", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip,BSDTAG,DATE,DAY,FACILITY,FACILITY_NUM,FULLDATE,HOST,HOUR,ISODATE,LEVEL,LEVEL_NUM,LOGHOST,MESSAGE,MIN,MONTH,MONTH_ABBREV,MONTH_NAME,MONTH_WEEK,MSG,MSGHDR,MSGID,PID,PRI,PRIORITY,PROGRAM,R_DATE,R_DAY,R_FULLDATE,R_HOUR,R_ISODATE,R_MIN,R_MONTH,R_MONTH_ABBREV,R_MONTH_NAME,R_MONTH_WEEK,R_SEC,R_STAMP,R_TZ,R_TZOFFSET,R_UNIXTIME,R_WEEK,R_WEEKDAY,R_WEEK_DAY,R_WEEK_DAY_ABBREV,R_WEEK_DAY_NAME,R_YEAR,R_YEAR_DAY,SDATA,SEC,SEQNUM,SOURCEIP,STAMP,S_DATE,S_DAY,S_FULLDATE,S_HOUR,S_ISODATE,S_MIN,S_MONTH,S_MONTH_ABBREV,S_MONTH_NAME,S_MONTH_WEEK,S_SEC,S_STAMP,S_TZ,S_TZOFFSET,S_UNIXTIME,S_WEEK,S_WEEKDAY,S_WEEK_DAY,S_WEEK_DAY_ABBREV,S_WEEK_DAY_NAME,S_YEAR,S_YEAR_DAY,TAG,TAGS,TZ,TZOFFSET,UNIXTIME,WEEK,WEEKDAY,WEEK_DAY,WEEK_DAY_ABBREV,WEEK_DAY_NAME,YEAR,YEAR_DAY");
+  testcase("everything", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip,BSDTAG,DATE,DAY,FACILITY,FACILITY_NUM,FULLDATE,HOST,HOUR,ISODATE,LEVEL,LEVEL_NUM,LOGHOST,MESSAGE,MIN,MONTH,MONTH_ABBREV,MONTH_NAME,MONTH_WEEK,MSG,MSGHDR,MSGID,PID,PRI,PRIORITY,PROGRAM,R_DATE,R_DAY,R_FULLDATE,R_HOUR,R_ISODATE,R_MIN,R_MONTH,R_MONTH_ABBREV,R_MONTH_NAME,R_MONTH_WEEK,R_SEC,R_STAMP,R_TZ,R_TZOFFSET,R_UNIXTIME,R_WEEK,R_WEEKDAY,R_WEEK_DAY,R_WEEK_DAY_ABBREV,R_WEEK_DAY_NAME,R_YEAR,R_YEAR_DAY,SDATA,SEC,SEQNUM,SOURCEIP,STAMP,S_DATE,S_DAY,S_FULLDATE,S_HOUR,S_ISODATE,S_MIN,S_MONTH,S_MONTH_ABBREV,S_MONTH_NAME,S_MONTH_WEEK,S_SEC,S_STAMP,S_TZ,S_TZOFFSET,S_UNIXTIME,S_WEEK,S_WEEKDAY,S_WEEK_DAY,S_WEEK_DAY_ABBREV,S_WEEK_DAY_NAME,S_YEAR,S_YEAR_DAY,TAG,TAGS,TZ,TZOFFSET,UNIXTIME,WEEK,WEEKDAY,WEEK_DAY,WEEK_DAY_ABBREV,WEEK_DAY_NAME,YEAR,YEAR_DAY", NULL);
 
-  testcase("nv-pairs", ".SDATA.*", "HOST,MESSAGE,MSGID,PID,PROGRAM");
+  testcase("nv-pairs", ".SDATA.*", "HOST,MESSAGE,MSGID,PID,PROGRAM", NULL);
 
   /* tests that the exclude patterns do not affect explicitly added
    * keys. The testcase function adds a "test.key" and then checks if
    * it is indeed present. Even if it would be excluded it still has
    * to be in the result set. */
-  testcase("rfc3164", "test.*", "DATE,FACILITY,HOST,MESSAGE,PID,PRIORITY,PROGRAM");
+  testcase("rfc3164", "test.*", "DATE,FACILITY,HOST,MESSAGE,PID,PRIORITY,PROGRAM", NULL);
+
+  /* test the value-pair transformators */
+  transformers = g_ptr_array_new();
+  g_ptr_array_add(transformers, value_pairs_new_transform_add_prefix("S_*", "__"));
+  g_ptr_array_add(transformers, value_pairs_new_transform_shift("__*", 2));
+  g_ptr_array_add(transformers, value_pairs_new_transform_replace("S_", "_PRIV_SOURCE_"));
+  g_ptr_array_add(transformers, value_pairs_new_transform_replace("R_", "_PRIV_REMOTE_"));
+
+  testcase("everything", NULL, ".SDATA.EventData at 18372.4.Data,.SDATA.Keywords at 18372.4.Keyword,.SDATA.meta.sequenceId,.SDATA.meta.sysUpTime,.SDATA.origin.ip,BSDTAG,DATE,DAY,FACILITY,FACILITY_NUM,FULLDATE,HOST,HOUR,ISODATE,LEVEL,LEVEL_NUM,LOGHOST,MESSAGE,MIN,MONTH,MONTH_ABBREV,MONTH_NAME,MONTH_WEEK,MSG,MSGHDR,MSGID,PID,PRI,PRIORITY,PROGRAM,SDATA,SEC,SEQNUM,SOURCEIP,STAMP,TAG,TAGS,TZ,TZOFFSET,UNIXTIME,WEEK,WEEKDAY,WEEK_DAY,WEEK_DAY_ABBREV,WEEK_DAY_NAME,YEAR,YEAR_DAY,_PRIV_REMOTE_DATE,_PRIV_REMOTE_DAY,_PRIV_REMOTE_FULLDATE,_PRIV_REMOTE_HOUR,_PRIV_REMOTE_ISODATE,_PRIV_REMOTE_MIN,_PRIV_REMOTE_MONTH,_PRIV_REMOTE_MONTH_ABBREV,_PRIV_REMOTE_MONTH_NAME,_PRIV_REMOTE_MONTH_WEEK,_PRIV_REMOTE_SEC,_PRIV_REMOTE_STAMP,_PRIV_REMOTE_TZ,_PRIV_REMOTE_TZOFFSET,_PRIV_REMOTE_UNIXTIME,_PRIV_REMOTE_WEEK,_PRIV_REMOTE_WEEKDAY,_PRIV_REMOTE_WEEK_DAY,_PRIV_REMOTE_WEEK_DAY_ABBREV,_PRIV_REMOTE_WEEK_DAY_NAME,_PRIV_REMOTE_YEAR,_PRIV_REMOTE_YEAR_DAY,_PRIV_SOURCE_DATE,_PRIV_SOURCE_DAY,_PRIV_SOURCE_FULLDATE,_PRIV
 _SOURCE_HOUR,_PRIV_SOURCE_ISODATE,_PRIV_SOURCE_MIN,_PRIV_SOURCE_MONTH,_PRIV_SOURCE_MONTH_ABBREV,_PRIV_SOURCE_MONTH_NAME,_PRIV_SOURCE_MONTH_WEEK,_PRIV_SOURCE_SEC,_PRIV_SOURCE_STAMP,_PRIV_SOURCE_TZ,_PRIV_SOURCE_TZOFFSET,_PRIV_SOURCE_UNIXTIME,_PRIV_SOURCE_WEEK,_PRIV_SOURCE_WEEKDAY,_PRIV_SOURCE_WEEK_DAY,_PRIV_SOURCE_WEEK_DAY_ABBREV,_PRIV_SOURCE_WEEK_DAY_NAME,_PRIV_SOURCE_YEAR,_PRIV_SOURCE_YEAR_DAY", transformers);
+
+  g_ptr_array_free(transformers, FALSE);
 
   app_shutdown();
   if (success)
-- 
1.7.0.4



More information about the syslog-ng mailing list