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)
# AlwaysAppendDS false
# EscapeCharacter "_"
# SeparateInstances false
+# PreserveSeparator false
# DropDuplicateFields false
# </Node>
#</Plugin>
# GraphiteEscapeChar "_"
# GraphiteSeparateInstances false
# GraphiteAlwaysAppendDS false
+ # GraphitePreserveSeparator false
</Publish>
# Receive values from an AMQP broker
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>
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
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
}
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);
break;
}
- if ((src[i] == '.')
+ if ((!preserve_separator && (src[i] == '.'))
|| isspace ((int) src[i])
|| iscntrl ((int) src[i]))
dst[i] = escape_char;
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",
#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,
.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.",
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);
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) {