[syslog-ng] [PATCH 3/3] tfjson: Template function for outputting JSON.
Gergely Nagy
algernon at balabit.hu
Sun Apr 24 11:30:45 CEST 2011
The template function implementation below is a port of Balint Kovacs'
format_json work, from syslog-ng 3.2 to 3.3, and to json-c and
value-pairs().
The usage is as simple as:
destination d_json {
file("/tmp/messages.json" template("$(format_json --scope selected_macros --scope nv_pairs)"));
};
Signed-off-by: Gergely Nagy <algernon at balabit.hu>
---
configure.in | 26 ++++++++++
modules/Makefile.am | 2 +-
modules/tfjson/Makefile.am | 11 ++++
modules/tfjson/tfjson.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 147 insertions(+), 1 deletions(-)
create mode 100644 modules/tfjson/Makefile.am
create mode 100644 modules/tfjson/tfjson.c
diff --git a/configure.in b/configure.in
index 16f70c1..284b33d 100644
--- a/configure.in
+++ b/configure.in
@@ -26,6 +26,7 @@ OPENSSL_MIN_VERSION="0.9.8"
LIBDBI_MIN_VERSION="0.8.0"
IVYKIS_MIN_VERSION="0.18"
PCRE_MIN_VERSION="6.1"
+JSON_C_MIN_VERSION="0.9"
dnl ***************************************************************************
dnl Initial setup
@@ -162,6 +163,10 @@ AC_ARG_WITH(ivykis,
Link against the system supplied or the builting ivykis library.]
,,with_ivykis="internal")
+AC_ARG_ENABLE(json,
+ [ --enable-json Enable support for JSON template formatting (default: auto)]
+ ,,enable_json="auto")
+
dnl ***************************************************************************
dnl Checks for programs.
AC_PROG_CC
@@ -537,6 +542,23 @@ if test "x$linking_mode" != "xdynamic" -a "x$blb_cv_static_glib" = "xno"; then
fi
dnl ***************************************************************************
+dnl json-glib headers/libraries
+dnl ***************************************************************************
+if test "x$enable_json" = "xyes" -o "x$enable_json" = "xauto"; then
+ PKG_CHECK_MODULES(JSON, json >= $JSON_C_MIN_VERSION,,JSON_LIBS="")
+ if test -z "$JSON_LIBS"; then
+ if test "x$enable_json" = "xyes"; then
+ AC_MSG_ERROR(Cannot find json >= $JSON_C_MIN_VERSION.)
+ else
+ AC_MSG_WARN(Cannot find json >= $JSON_C_MIN_VERSION.)
+ fi
+ enable_json="no"
+ else
+ enable_json="yes"
+ fi
+fi
+
+dnl ***************************************************************************
dnl pcre headers/libraries
dnl ***************************************************************************
@@ -893,6 +915,7 @@ AM_CONDITIONAL(ENABLE_SQL, [test "$enable_sql" = "yes"])
AM_CONDITIONAL(ENABLE_SUN_STREAMS, [test "$enable_sun_streams" = "yes"])
AM_CONDITIONAL(ENABLE_PACCT, [test "$enable_pacct" = "yes"])
AM_CONDITIONAL(ENABLE_MONGODB, [test "$enable_mongodb" = "yes"])
+AM_CONDITIONAL(ENABLE_JSON, [test "$enable_json" = "yes"])
# substitution into manual pages
expanded_sysconfdir=[`patheval $sysconfdir | sed -e 's/-/\\\\-/g'`]
@@ -953,6 +976,7 @@ AC_OUTPUT(dist.conf
modules/pacctformat/Makefile
modules/basicfuncs/Makefile
modules/convertfuncs/Makefile
+ modules/tfjson/Makefile
scripts/Makefile
scripts/update-patterndb
doc/Makefile
@@ -1000,4 +1024,6 @@ echo " SSL support (module) : ${enable_ssl:=no}"
echo " SQL support (module) : ${enable_sql:=no}"
echo " PACCT module (EXPERIMENTAL) : ${enable_pacct:=no}"
echo " MongoDB destination (module): ${enable_mongodb:=no}"
+echo " JSON support (module) : ${enable_json:=no}"
+
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 38cde6b..46de2b8 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -1 +1 @@
-SUBDIRS = afsocket afsql afstreams affile afprog afuser afmongodb csvparser confgen syslogformat pacctformat basicfuncs convertfuncs dbparser dummy
+SUBDIRS = afsocket afsql afstreams affile afprog afuser afmongodb csvparser confgen syslogformat pacctformat basicfuncs convertfuncs dbparser tfjson dummy
diff --git a/modules/tfjson/Makefile.am b/modules/tfjson/Makefile.am
new file mode 100644
index 0000000..8b30f83
--- /dev/null
+++ b/modules/tfjson/Makefile.am
@@ -0,0 +1,11 @@
+moduledir = @moduledir@
+export top_srcdir
+
+if ENABLE_JSON
+AM_CPPFLAGS = -I$(top_srcdir)/lib -I../../lib @JSON_CFLAGS@
+module_LTLIBRARIES = libtfjson.la
+
+libtfjson_la_SOURCES = tfjson.c
+libtfjson_la_LIBADD = ../../lib/libsyslog-ng.la @JSON_LIBS@
+libtfjson_la_LDFLAGS = -avoid-version
+endif
diff --git a/modules/tfjson/tfjson.c b/modules/tfjson/tfjson.c
new file mode 100644
index 0000000..f23b2ac
--- /dev/null
+++ b/modules/tfjson/tfjson.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2002-2011 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011 Balint Kovacs <blint at balabit.hu>
+ * Copyright (c) 2011 Gergely Nagy <algernon at balabit.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, 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
+ *
+ */
+
+#include "plugin.h"
+#include "templates.h"
+#include "filter.h"
+#include "filter-expr-parser.h"
+#include "cfg.h"
+
+#include <json.h>
+
+static gboolean
+tf_json_prepare(LogTemplateFunction *self, LogTemplate *parent,
+ gint argc, gchar *argv[],
+ gpointer *state, GDestroyNotify *state_destroy,
+ GError **error)
+{
+ ValuePairs *vp;
+
+ vp = value_pairs_new_from_cmdline (parent->cfg, argc, argv, error);
+ if (!vp)
+ return FALSE;
+
+ *state = vp;
+ *state_destroy = (GDestroyNotify) value_pairs_free;
+
+ return TRUE;
+}
+
+static gboolean
+tf_json_foreach (const gchar *name, const gchar *value, gpointer user_data)
+{
+ json_object *root = (json_object *)user_data;
+ json_object *this;
+
+ this = json_object_new_string (value);
+ json_object_object_add (root, name, this);
+
+ return FALSE;
+}
+
+static json_object *
+tf_json_format_message(ValuePairs *vp, LogMessage *msg)
+{
+ json_object *root;
+
+ root = json_object_new_object();
+ value_pairs_foreach (vp, tf_json_foreach, msg, 0, root);
+
+ return root;
+}
+
+static void
+tf_json_call(LogTemplateFunction *self, gpointer state, GPtrArray *arg_bufs,
+ LogMessage **messages, gint num_messages, LogTemplateOptions *opts,
+ gint tz, gint seq_num, const gchar *context_id, GString *result)
+{
+ gint i;
+ ValuePairs *vp = (ValuePairs *)state;
+
+ for (i = 0; i < num_messages; i++)
+ {
+ LogMessage *msg = messages[i];
+ json_object *json;
+
+ json = tf_json_format_message(vp, msg);
+ g_string_append(result, json_object_to_json_string (json));
+ json_object_put(json);
+ }
+}
+
+static void
+tf_json_eval (LogTemplateFunction *self, gpointer state, GPtrArray *arg_bufs,
+ LogMessage **messages, gint num_messages, LogTemplateOptions *opts,
+ gint tz, gint seq_num)
+{
+ return;
+}
+
+TEMPLATE_FUNCTION(tf_json, tf_json_prepare, tf_json_eval, tf_json_call, NULL);
+
+static Plugin builtin_tmpl_func_plugins[] =
+ {
+ TEMPLATE_FUNCTION_PLUGIN(tf_json, "format_json"),
+ };
+
+gboolean
+tfjson_module_init(GlobalConfig *cfg, CfgArgs *args)
+{
+ plugin_register(cfg, builtin_tmpl_func_plugins, G_N_ELEMENTS(builtin_tmpl_func_plugins));
+ return TRUE;
+}
--
1.7.2.5
More information about the syslog-ng
mailing list