Code

Merge remote-tracking branch 'github/pr/2058'
authorFlorian Forster <octo@collectd.org>
Sun, 27 Nov 2016 06:24:55 +0000 (07:24 +0100)
committerFlorian Forster <octo@collectd.org>
Sun, 27 Nov 2016 06:24:55 +0000 (07:24 +0100)
src/amqp.c
src/collectd.conf.in
src/collectd.conf.pod
src/utils_format_graphite.c
src/utils_format_graphite.h
src/utils_format_graphite_test.c
src/write_graphite.c
src/write_kafka.c

index 4089fc321ee5e04510e66fa1f1274a55d450cd2a..b237ba3dedcc1d451e81086e242bda88a038ec2b 100644 (file)
@@ -1015,6 +1015,9 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
         else if ((strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) && publish)
             status = cf_util_get_flag (child, &conf->graphite_flags,
                     GRAPHITE_ALWAYS_APPEND_DS);
+        else if ((strcasecmp ("GraphitePreserveSeparator", child->key) == 0) && publish)
+            status = cf_util_get_flag (child, &conf->graphite_flags,
+                    GRAPHITE_PRESERVE_SEPARATOR);
         else if ((strcasecmp ("GraphitePrefix", child->key) == 0) && publish)
             status = cf_util_get_string (child, &conf->prefix);
         else if ((strcasecmp ("GraphitePostfix", child->key) == 0) && publish)
index 8ad24d600f873c2cd5f0d2bfdfd845394d030154..719010f4b71d4d7f825d726dc3995a5a898bdfa2 100644 (file)
 #    AlwaysAppendDS false
 #    EscapeCharacter "_"
 #    SeparateInstances false
+#    PreserveSeparator false
 #    DropDuplicateFields false
 #  </Node>
 #</Plugin>
index dcf6c36d54861e2c1bd802291f63ccc47e39ebeb..4293abf34b76c5c53bb051e19979d67eefbb9c84 100644 (file)
@@ -555,6 +555,7 @@ B<Synopsis:>
  #   GraphiteEscapeChar "_"
  #   GraphiteSeparateInstances false
  #   GraphiteAlwaysAppendDS false
+ #   GraphitePreserveSeparator false
    </Publish>
 
    # Receive values from an AMQP broker
@@ -729,6 +730,12 @@ If set to B<true>, append the name of the I<Data Source> (DS) to the "metric"
 identifier. If set to B<false> (the default), this is only done when there is
 more than one DS.
 
+=item B<GraphitePreserveSeparator> B<false>|B<true>
+
+If set to B<false> (the default) the C<.> (dot) character is replaced with
+I<GraphiteEscapeChar>. Otherwise, if set to B<true>, the C<.> (dot) character
+is preserved, i.e. passed through.
+
 =back
 
 =head2 Plugin C<apache>
@@ -8014,6 +8021,12 @@ If set to B<true>, append the name of the I<Data Source> (DS) to the "metric"
 identifier. If set to B<false> (the default), this is only done when there is
 more than one DS.
 
+=item B<PreserveSeparator> B<false>|B<true>
+
+If set to B<false> (the default) the C<.> (dot) character is replaced with
+I<EscapeCharacter>. Otherwise, if set to B<true>, the C<.> (dot) character
+is preserved, i.e. passed through.
+
 =item B<DropDuplicateFields> B<false>|B<true>
 
 If set to B<true>, detect and remove duplicate components in Graphite metric
@@ -8416,6 +8429,17 @@ path component, for example C<host.cpu.0.cpu.idle>. If set to B<false> (the
 default), the plugin and plugin instance (and likewise the type and type
 instance) are put into one component, for example C<host.cpu-0.cpu-idle>.
 
+=item B<GraphiteAlwaysAppendDS> B<true>|B<false>
+
+If set to B<true>, append the name of the I<Data Source> (DS) to the "metric"
+identifier. If set to B<false> (the default), this is only done when there is
+more than one DS.
+
+=item B<GraphitePreserveSeparator> B<false>|B<true>
+
+If set to B<false> (the default) the C<.> (dot) character is replaced with
+I<GraphiteEscapeChar>. Otherwise, if set to B<true>, the C<.> (dot) character
+is preserved, i.e. passed through.
 =item B<StoreRates> B<true>|B<false>
 
 If set to B<true> (the default), convert counter values to rates. If set to
index 69c619f425702ffc6c329738673c6887bdac875a..85f5917c8ea807f849476b29f91f139824f4abdb 100644 (file)
@@ -83,7 +83,7 @@ static int gr_format_values (char *ret, size_t ret_len,
 }
 
 static void gr_copy_escape_part (char *dst, const char *src, size_t dst_len,
-    char escape_char)
+    char escape_char, _Bool preserve_separator)
 {
     memset (dst, 0, dst_len);
 
@@ -98,7 +98,7 @@ static void gr_copy_escape_part (char *dst, const char *src, size_t dst_len,
             break;
         }
 
-        if ((src[i] == '.')
+        if ((!preserve_separator && (src[i] == '.'))
                 || isspace ((int) src[i])
                 || iscntrl ((int) src[i]))
             dst[i] = escape_char;
@@ -130,16 +130,18 @@ static int gr_format_name (char *ret, int ret_len,
     if (postfix == NULL)
         postfix = "";
 
+    _Bool preserve_separator = (flags & GRAPHITE_PRESERVE_SEPARATOR) ? 1 : 0;
+
     gr_copy_escape_part (n_host, vl->host,
-            sizeof (n_host), escape_char);
+            sizeof (n_host), escape_char, preserve_separator);
     gr_copy_escape_part (n_plugin, vl->plugin,
-            sizeof (n_plugin), escape_char);
+            sizeof (n_plugin), escape_char, preserve_separator);
     gr_copy_escape_part (n_plugin_instance, vl->plugin_instance,
-            sizeof (n_plugin_instance), escape_char);
+            sizeof (n_plugin_instance), escape_char, preserve_separator);
     gr_copy_escape_part (n_type, vl->type,
-            sizeof (n_type), escape_char);
+            sizeof (n_type), escape_char, preserve_separator);
     gr_copy_escape_part (n_type_instance, vl->type_instance,
-            sizeof (n_type_instance), escape_char);
+            sizeof (n_type_instance), escape_char, preserve_separator);
 
     if (n_plugin_instance[0] != '\0')
         ssnprintf (tmp_plugin, sizeof (tmp_plugin), "%s%c%s",
index 5165f9e65f113fb5c8c64703afffcd6f8940eec5..ebc50802475f20de6d581ae219676f5422ebbaaa 100644 (file)
@@ -30,6 +30,7 @@
 #define GRAPHITE_SEPARATE_INSTANCES 0x02
 #define GRAPHITE_ALWAYS_APPEND_DS   0x04
 #define GRAPHITE_DROP_DUPE_FIELDS   0x08
+#define GRAPHITE_PRESERVE_SEPARATOR 0x10
 
 int format_graphite (char *buffer,
     size_t buffer_size, const data_set_t *ds,
index 30cdd7a420fc7e1d4d4377d0745e58b7737194f0..f349db1f12362a09440c11c431203159bf198f4c 100644 (file)
@@ -96,6 +96,19 @@ DEF_TEST(metric_name)
       .flags = GRAPHITE_ALWAYS_APPEND_DS,
       .want_name = "example@com.test-foo.single-bar.value",
     },
+    /* flag GRAPHITE_PRESERVE_SEPARATOR */
+    {
+      .plugin_instance = "f.o.o",
+      .type_instance = "b.a.r",
+      .flags = 0,
+      .want_name = "example@com.test-f@o@o.single-b@a@r",
+    },
+    {
+      .plugin_instance = "f.o.o",
+      .type_instance = "b.a.r",
+      .flags = GRAPHITE_PRESERVE_SEPARATOR,
+      .want_name = "example.com.test-f.o.o.single-b.a.r",
+    },
     /* prefix and suffix */
     {
       .prefix = "foo.",
index ad8dfcef487a2e512e4c2e539c8698625c17a105..9feb6b338458f828d0deb4bbacf81a6feb3750d3 100644 (file)
@@ -566,6 +566,9 @@ static int wg_config_node (oconfig_item_t *ci)
         else if (strcasecmp ("AlwaysAppendDS", child->key) == 0)
             cf_util_get_flag (child, &cb->format_flags,
                     GRAPHITE_ALWAYS_APPEND_DS);
+        else if (strcasecmp ("PreserveSeparator", child->key) == 0)
+            cf_util_get_flag (child, &cb->format_flags,
+                    GRAPHITE_PRESERVE_SEPARATOR);
         else if (strcasecmp ("DropDuplicateFields", child->key) == 0)
             cf_util_get_flag (child, &cb->format_flags,
                     GRAPHITE_DROP_DUPE_FIELDS);
index 6018fea05502f511a1ed8794f9f11982810e1a82..a719cd376d18a5cd6fb690117133977ddfff13fd 100644 (file)
@@ -376,6 +376,10 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
             status = cf_util_get_flag (child, &tctx->graphite_flags,
                                        GRAPHITE_ALWAYS_APPEND_DS);
 
+        } else if (strcasecmp ("GraphitePreserveSeparator", child->key) == 0) {
+            status = cf_util_get_flag (child, &tctx->graphite_flags,
+                                       GRAPHITE_PRESERVE_SEPARATOR);
+
         } else if (strcasecmp ("GraphitePrefix", child->key) == 0) {
             status = cf_util_get_string (child, &tctx->prefix);
         } else if (strcasecmp ("GraphitePostfix", child->key) == 0) {