From: Pavel Rochnyak Date: Tue, 30 Apr 2019 07:54:53 +0000 (+0700) Subject: Merge pull request #3001 from usev6/write_graphite_reverse_host X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=1009f2630e9a4a22df9d4b046f22065dbbf8b1b2;hp=d1c056161220ce78dedefccf90c876cbea64e9d4 Merge pull request #3001 from usev6/write_graphite_reverse_host write_graphite plugin: Add option to reverse host --- diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 9e7a28b6..a282244d 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -1701,6 +1701,7 @@ # SeparateInstances false # PreserveSeparator false # DropDuplicateFields false +# ReverseHost false # # diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 2976f6df..ce7f725e 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -9594,6 +9594,7 @@ Synopsis: LogSendErrors true Prefix "collectd" UseTags false + ReverseHost false @@ -9705,6 +9706,30 @@ are not used. Default value: B. +=item B B|B + +If set to B, the (dot separated) parts of the B field of the +I will be rewritten in reverse order. The rewrite happens I +special characters are replaced with the B. + +This option might be convenient if the metrics are presented with Graphite in a +DNS like tree structure (probably without replacing dots in hostnames). + +Example: + Hostname "node3.cluster1.example.com" + LoadPlugin "cpu" + LoadPlugin "write_graphite" + + + EscapeCharacter "." + ReverseHost true + + + + result on the wire: com.example.cluster1.node3.cpu-0.cpu-idle 99.900993 1543010932 + +Default value: B. + =back =head2 Plugin C diff --git a/src/utils/format_graphite/format_graphite.c b/src/utils/format_graphite/format_graphite.c index d0e047ff..ffef3e2f 100644 --- a/src/utils/format_graphite/format_graphite.c +++ b/src/utils/format_graphite/format_graphite.c @@ -34,6 +34,35 @@ /* Utils functions to format data sets in graphite format. * Largely taken from write_graphite.c as it remains the same formatting */ +/* helper function for reverse_hostname */ +void reverse_string(char *r_host, int len) { + for (int i = 0, j = len - 1; i < j; i++, j--) { + char t = r_host[i]; + r_host[i] = r_host[j]; + r_host[j] = t; + } +} + +void reverse_hostname(char *r_host, char const *orig_host) { + int len_host = strlen(orig_host); + + /* put reversed hostname into working copy */ + for (int i = 0; i < len_host; i++) + r_host[i] = orig_host[len_host - 1 - i]; + r_host[len_host] = '\0'; + + /* reverse labels (except last) */ + int p = 0; + for (int i = 0; i < len_host; i++) + if (r_host[i] == '.') { + reverse_string(&r_host[p], i - p); + p = i + 1; + } + + /* reverse last label */ + reverse_string(&r_host[p], len_host - p); +} + static int gr_format_values(char *ret, size_t ret_len, int ds_num, const data_set_t *ds, const value_list_t *vl, gauge_t const *rates) { @@ -120,7 +149,13 @@ static int gr_format_name_tagged(char *ret, int ret_len, value_list_t const *vl, if (postfix == NULL) postfix = ""; - gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char, 1); + if (flags & GRAPHITE_REVERSE_HOST) { + char r_host[DATA_MAX_NAME_LEN]; + reverse_hostname(r_host, vl->host); + gr_copy_escape_part(n_host, r_host, sizeof(n_host), escape_char, 1); + } else { + gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char, 1); + } gr_copy_escape_part(n_plugin, vl->plugin, sizeof(n_plugin), escape_char, 1); gr_copy_escape_part(n_plugin_instance, vl->plugin_instance, sizeof(n_plugin_instance), escape_char, 1); @@ -198,8 +233,15 @@ static int gr_format_name(char *ret, int ret_len, value_list_t const *vl, bool preserve_separator = (flags & GRAPHITE_PRESERVE_SEPARATOR); - gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char, - preserve_separator); + if (flags & GRAPHITE_REVERSE_HOST) { + char r_host[DATA_MAX_NAME_LEN]; + reverse_hostname(r_host, vl->host); + gr_copy_escape_part(n_host, r_host, sizeof(n_host), escape_char, + preserve_separator); + } else { + gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char, + preserve_separator); + } gr_copy_escape_part(n_plugin, vl->plugin, sizeof(n_plugin), escape_char, preserve_separator); gr_copy_escape_part(n_plugin_instance, vl->plugin_instance, diff --git a/src/utils/format_graphite/format_graphite.h b/src/utils/format_graphite/format_graphite.h index 60b89ae7..4df7db3d 100644 --- a/src/utils/format_graphite/format_graphite.h +++ b/src/utils/format_graphite/format_graphite.h @@ -32,6 +32,7 @@ #define GRAPHITE_DROP_DUPE_FIELDS 0x08 #define GRAPHITE_PRESERVE_SEPARATOR 0x10 #define GRAPHITE_USE_TAGS 0x20 +#define GRAPHITE_REVERSE_HOST 0x40 int format_graphite(char *buffer, size_t buffer_size, const data_set_t *ds, const value_list_t *vl, const char *prefix, diff --git a/src/write_graphite.c b/src/write_graphite.c index 000b62ed..cb6793dd 100644 --- a/src/write_graphite.c +++ b/src/write_graphite.c @@ -29,7 +29,7 @@ * Based on the write_http plugin. **/ -/* write_graphite plugin configuation example +/* write_graphite plugin configuration example * * * @@ -39,6 +39,7 @@ * LogSendErrors true * Prefix "collectd" * UseTags true + * ReverseHost false * * */ @@ -521,6 +522,8 @@ static int wg_config_node(oconfig_item_t *ci) { cf_util_get_flag(child, &cb->format_flags, GRAPHITE_DROP_DUPE_FIELDS); else if (strcasecmp("UseTags", child->key) == 0) cf_util_get_flag(child, &cb->format_flags, GRAPHITE_USE_TAGS); + else if (strcasecmp("ReverseHost", child->key) == 0) + cf_util_get_flag(child, &cb->format_flags, GRAPHITE_REVERSE_HOST); else if (strcasecmp("EscapeCharacter", child->key) == 0) config_set_char(&cb->escape_char, child); else {