Merge branch 'collectd-5.7' into collectd-5.8
[collectd.git] / src / write_log.c
index b0dc6f1..fdc99ef 100644 (file)
 #include "plugin.h"
 
 #include "utils_format_graphite.h"
+#include "utils_format_json.h"
 
 #include <netdb.h>
 
-#define WL_BUF_SIZE 8192
+#define WL_BUF_SIZE 16384
 
-static int wl_write_messages (const data_set_t *ds, const value_list_t *vl)
-{
-    char buffer[WL_BUF_SIZE] = { 0 };
-    int status;
-
-    if (0 != strcmp (ds->type, vl->type))
-    {
-        ERROR ("write_log plugin: DS type does not match "
-                "value list type");
-        return -1;
-    }
+#define WL_FORMAT_GRAPHITE 1
+#define WL_FORMAT_JSON 2
 
-    status = format_graphite (buffer, sizeof (buffer), ds, vl,
-                              NULL, NULL, '_', 0);
-    if (status != 0) /* error message has been printed already. */
-        return (status);
+/* Plugin:WriteLog has to also operate without a config, so use a global. */
+int wl_format = WL_FORMAT_GRAPHITE;
 
-    INFO ("write_log values:\n%s", buffer);
+static int wl_write_graphite(const data_set_t *ds, const value_list_t *vl) {
+  char buffer[WL_BUF_SIZE] = {0};
+  int status;
 
-    return (0);
-} /* int wl_write_messages */
+  if (0 != strcmp(ds->type, vl->type)) {
+    ERROR("write_log plugin: DS type does not match value list type");
+    return -1;
+  }
 
-static int wl_write (const data_set_t *ds, const value_list_t *vl,
-        __attribute__ ((unused)) user_data_t *user_data)
-{
-    int status;
+  status = format_graphite(buffer, sizeof(buffer), ds, vl, NULL, NULL, '_', 0);
+  if (status != 0) /* error message has been printed already. */
+    return status;
+
+  INFO("write_log values:\n%s", buffer);
+
+  return 0;
+} /* int wl_write_graphite */
+
+static int wl_write_json(const data_set_t *ds, const value_list_t *vl) {
+  char buffer[WL_BUF_SIZE] = {0};
+  size_t bfree = sizeof(buffer);
+  size_t bfill = 0;
+
+  if (0 != strcmp(ds->type, vl->type)) {
+    ERROR("write_log plugin: DS type does not match value list type");
+    return -1;
+  }
+
+  format_json_initialize(buffer, &bfill, &bfree);
+  format_json_value_list(buffer, &bfill, &bfree, ds, vl,
+                         /* store rates = */ 0);
+  format_json_finalize(buffer, &bfill, &bfree);
+
+  INFO("write_log values:\n%s", buffer);
+
+  return 0;
+} /* int wl_write_json */
 
-    status = wl_write_messages (ds, vl);
+static int wl_write(const data_set_t *ds, const value_list_t *vl,
+                    __attribute__((unused)) user_data_t *user_data) {
+  int status = 0;
 
-    return (status);
+  if (wl_format == WL_FORMAT_GRAPHITE) {
+    status = wl_write_graphite(ds, vl);
+  } else if (wl_format == WL_FORMAT_JSON) {
+    status = wl_write_json(ds, vl);
+  }
+
+  return status;
 }
 
-void module_register (void)
+static int wl_config(oconfig_item_t *ci) /* {{{ */
 {
-    plugin_register_write ("write_log", wl_write, NULL);
-}
+  _Bool format_seen = 0;
+
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp("Format", child->key) == 0) {
+      char str[16];
+
+      if (cf_util_get_string_buffer(child, str, sizeof(str)) != 0)
+        continue;
 
-/* vim: set sw=4 ts=4 sts=4 tw=78 et : */
+      if (format_seen) {
+        WARNING("write_log plugin: Redefining option `%s'.", child->key);
+      }
+      format_seen = 1;
+
+      if (strcasecmp("Graphite", str) == 0)
+        wl_format = WL_FORMAT_GRAPHITE;
+      else if (strcasecmp("JSON", str) == 0)
+        wl_format = WL_FORMAT_JSON;
+      else {
+        ERROR("write_log plugin: Unknown format `%s' for option `%s'.", str,
+              child->key);
+        return -EINVAL;
+      }
+    } else {
+      ERROR("write_log plugin: Invalid configuration option: `%s'.",
+            child->key);
+      return -EINVAL;
+    }
+  }
+
+  return 0;
+} /* }}} int wl_config */
+
+void module_register(void) {
+  plugin_register_complex_config("write_log", wl_config);
+  /* If config is supplied, the global wl_format will be set. */
+  plugin_register_write("write_log", wl_write, NULL);
+}