[syslog-ng] [PATCH (3.4) 4/4] json-parser: Implement array parsing.

Gergely Nagy algernon at balabit.hu
Tue Jan 10 13:11:09 CET 2012


Arrays are parsed into a $fieldname.$index structure for now.

Signed-off-by: Gergely Nagy <algernon at balabit.hu>
---
 modules/jsonparser/jsonparser.c |  142 +++++++++++++++++++++++----------------
 1 files changed, 85 insertions(+), 57 deletions(-)

diff --git a/modules/jsonparser/jsonparser.c b/modules/jsonparser/jsonparser.c
index cbe07fa..fe45479 100644
--- a/modules/jsonparser/jsonparser.c
+++ b/modules/jsonparser/jsonparser.c
@@ -47,85 +47,113 @@ log_json_parser_set_prefix (LogParser *p, const gchar *prefix)
 static void
 log_json_parser_process_object (struct json_object *jso,
                                 const gchar *prefix,
+                                LogMessage *msg);
+
+static void
+log_json_parser_process_single (struct json_object *jso,
+                                const gchar *prefix,
+                                const gchar *obj_key,
                                 LogMessage *msg)
 {
-  struct json_object_iter itr;
   ScratchBuffer *key, *value;
+  gboolean parsed = FALSE;
 
   key = scratch_buffer_acquire ();
   value = scratch_buffer_acquire ();
 
-  json_object_object_foreachC (jso, itr)
+  switch (json_object_get_type (jso))
     {
-      gboolean parsed = FALSE;
+    case json_type_boolean:
+      parsed = TRUE;
+      if (json_object_get_boolean (jso))
+        g_string_assign (sb_string (value), "true");
+      else
+        g_string_assign (sb_string (value), "false");
+      break;
+    case json_type_double:
+      parsed = TRUE;
+      g_string_printf (sb_string (value), "%f",
+                       json_object_get_double (jso));
+      break;
+    case json_type_int:
+      parsed = TRUE;
+      g_string_printf (sb_string (value), "%i",
+                       json_object_get_int (jso));
+      break;
+    case json_type_string:
+      parsed = TRUE;
+      g_string_assign (sb_string (value),
+                       json_object_get_string (jso));
+      break;
+    case json_type_object:
+      g_string_assign (sb_string (key), prefix);
+      g_string_append (sb_string (key), obj_key);
+      g_string_append_c (sb_string (key), '.');
+      log_json_parser_process_object (jso, sb_string (key)->str, msg);
+      break;
+    case json_type_array:
+      {
+        gint i, plen;
+
+        g_string_assign (sb_string (key), obj_key);
+        g_string_append_c (sb_string (key), '.');
+
+        plen = sb_string (key)->len;
+
+        for (i = 0; i < json_object_array_length (jso); i++)
+          {
+            g_string_truncate (sb_string (key), plen);
+            g_string_append_printf (sb_string (key), "%d", i);
+            log_json_parser_process_single (json_object_array_get_idx (jso, i),
+                                            prefix,
+                                            sb_string (key)->str, msg);
+          }
+        break;
+      }
+    default:
+      msg_error ("JSON parser encountered an unknown type, skipping",
+                 evt_tag_str ("key", obj_key), NULL);
+      break;
+    }
 
-      switch (json_object_get_type (itr.val))
+  if (parsed)
+    {
+      if (prefix)
         {
-        case json_type_boolean:
-          parsed = TRUE;
-          if (json_object_get_boolean (itr.val))
-            g_string_assign (sb_string (value), "true");
-          else
-            g_string_assign (sb_string (value), "false");
-          break;
-        case json_type_double:
-          parsed = TRUE;
-          g_string_printf (sb_string (value), "%f",
-                           json_object_get_double (itr.val));
-          break;
-        case json_type_int:
-          parsed = TRUE;
-          g_string_printf (sb_string (value), "%i",
-                           json_object_get_int (itr.val));
-          break;
-        case json_type_string:
-          parsed = TRUE;
-          g_string_assign (sb_string (value),
-                           json_object_get_string (itr.val));
-          break;
-        case json_type_object:
           g_string_assign (sb_string (key), prefix);
-          g_string_append (sb_string (key), itr.key);
-          g_string_append_c (sb_string (key), '.');
-          log_json_parser_process_object (itr.val, sb_string (key)->str, msg);
-          break;
-        case json_type_array:
-          msg_error ("JSON parser does not support arrays yet, "
-                     "skipping",
-                     evt_tag_str ("key", itr.key), NULL);
-          break;
-        default:
-          msg_error ("JSON parser encountered an unknown type, skipping",
-                     evt_tag_str ("key", itr.key), NULL);
-          break;
-        }
-
-      if (parsed)
-        {
-          if (prefix)
-            {
-              g_string_assign (sb_string (key), prefix);
-              g_string_append (sb_string (key), itr.key);
-              log_msg_set_value (msg,
-                                 log_msg_get_value_handle (sb_string (key)->str),
-                                 sb_string (value)->str, sb_string (value)->len);
-            }
-          else
-            log_msg_set_value (msg,
-                               log_msg_get_value_handle (itr.key),
-                               sb_string (value)->str, sb_string (value)->len);
+          g_string_append (sb_string (key), obj_key);
+          log_msg_set_value (msg,
+                             log_msg_get_value_handle (sb_string (key)->str),
+                             sb_string (value)->str, sb_string (value)->len);
         }
+      else
+        log_msg_set_value (msg,
+                           log_msg_get_value_handle (obj_key),
+                           sb_string (value)->str, sb_string (value)->len);
     }
+
   scratch_buffer_release (key);
   scratch_buffer_release (value);
 }
 
+static void
+log_json_parser_process_object (struct json_object *jso,
+                                const gchar *prefix,
+                                LogMessage *msg)
+{
+  struct json_object_iter itr;
+
+  json_object_object_foreachC (jso, itr)
+    {
+      log_json_parser_process_single (itr.val, prefix, itr.key, msg);
+    }
+}
+
 static gboolean
 log_json_parser_process (LogParser *s, LogMessage *msg, const gchar *input)
 {
   LogJSONParser *self = (LogJSONParser *) s;
   struct json_object *jso;
-  struct json_object_iter itr;
 
   jso = json_tokener_parse (input);
 
-- 
1.7.7.3




More information about the syslog-ng mailing list