[syslog-ng] [PATCH 3/3] tfjson: Template function for outputting JSON.

Balazs Scheidler bazsi at balabit.hu
Sun May 1 00:07:37 CEST 2011


Hi,

I've integrated this patch into 3.3 as agreed, it needed some slight
modifications, but I've done that while integrating.

Thanks.

On Sun, 2011-04-24 at 11:30 +0200, Gergely Nagy wrote:
> 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;
> +}

-- 
Bazsi




More information about the syslog-ng mailing list