write_kafka plugin: Reintroduce the "Key Random" setting.
[collectd.git] / src / write_kafka.c
index 614ce0f..0f28ed0 100644 (file)
  */
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
-#include "utils_cache.h"
 #include "utils_cmd_putval.h"
 #include "utils_format_graphite.h"
 #include "utils_format_json.h"
-#include "utils_crc32.h"
 
 #include <stdint.h>
 #include <librdkafka/rdkafka.h>
-#include <zlib.h>
 #include <errno.h>
 
 struct kafka_topic_context {
@@ -81,6 +78,15 @@ static uint32_t kafka_hash(const char *keydata, size_t keylen)
     return hash;
 }
 
+/* 31 bit -> 4 byte -> 8 byte hex string + null byte */
+#define KAFKA_RANDOM_KEY_SIZE 9
+#define KAFKA_RANDOM_KEY_BUFFER (char[KAFKA_RANDOM_KEY_SIZE]) {""}
+static char *kafka_random_key(char buffer[static KAFKA_RANDOM_KEY_SIZE])
+{
+    ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08lX", (unsigned long) mrand48());
+    return buffer;
+}
+
 static int32_t kafka_partition(const rd_kafka_topic_t *rkt,
                                const void *keydata, size_t keylen,
                                int32_t partition_cnt, void *p, void *m)
@@ -206,11 +212,10 @@ static int kafka_write(const data_set_t *ds, /* {{{ */
         return -1;
     }
 
-    key = ctx->key;
-    if (key != NULL)
-        keylen = strlen (key);
-    else
-        keylen = 0;
+    key = (ctx->key != NULL)
+        ? ctx->key
+        : kafka_random_key(KAFKA_RANDOM_KEY_BUFFER);
+    keylen = strlen (key);
 
     rd_kafka_produce(ctx->topic, RD_KAFKA_PARTITION_UA,
                      RD_KAFKA_MSG_F_COPY, buffer, blen,
@@ -243,13 +248,11 @@ static void kafka_topic_context_free(void *p) /* {{{ */
 static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{ */
 {
     int                          status;
-    int                          i;
     struct kafka_topic_context  *tctx;
     char                        *key = NULL;
     char                        *val;
     char                         callback_name[DATA_MAX_NAME_LEN];
     char                         errbuf[1024];
-    user_data_t                  ud;
     oconfig_item_t              *child;
     rd_kafka_conf_res_t          ret;
 
@@ -295,7 +298,7 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
         goto errout;
     }
 
-    for (i = 0; i < ci->children_num; i++) {
+    for (int i = 0; i < ci->children_num; i++) {
         /*
          * The code here could be simplified but makes room
          * for easy adding of new options later on.
@@ -324,8 +327,12 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
             }
 
         } else if (strcasecmp ("Key", child->key) == 0)  {
-            cf_util_get_string (child, &tctx->key);
-            assert (tctx->key != NULL);
+            if (cf_util_get_string (child, &tctx->key) != 0)
+                continue;
+            if (strcasecmp ("Random", tctx->key) == 0) {
+                sfree(tctx->key);
+                tctx->key = strdup (kafka_random_key (KAFKA_RANDOM_KEY_BUFFER));
+            }
         } else if (strcasecmp ("Format", child->key) == 0) {
             status = cf_util_get_string(child, &key);
             if (status != 0)
@@ -388,8 +395,10 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
     ssnprintf(callback_name, sizeof(callback_name),
               "write_kafka/%s", tctx->topic_name);
 
-    ud.data = tctx;
-    ud.free_func = kafka_topic_context_free;
+    user_data_t ud = {
+        .data = tctx,
+        .free_func = kafka_topic_context_free
+    };
 
     status = plugin_register_write (callback_name, kafka_write, &ud);
     if (status != 0) {
@@ -414,7 +423,6 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
 
 static int kafka_config(oconfig_item_t *ci) /* {{{ */
 {
-    int                          i;
     oconfig_item_t              *child;
     rd_kafka_conf_t             *conf;
     rd_kafka_conf_res_t          ret;
@@ -424,7 +432,7 @@ static int kafka_config(oconfig_item_t *ci) /* {{{ */
         WARNING("cannot allocate kafka configuration.");
         return -1;
     }
-    for (i = 0; i < ci->children_num; i++)  {
+    for (int i = 0; i < ci->children_num; i++)  {
         child = &ci->children[i];
 
         if (strcasecmp("Topic", child->key) == 0) {