From: usev6 Date: Fri, 23 Nov 2018 23:35:39 +0000 (+0100) Subject: write_graphite plugin: Add option to reverse host X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=3accc892f047146145d93791ec1246515fe308ba;p=collectd.git write_graphite plugin: Add option to reverse host --- diff --git a/src/collectd.conf.in b/src/collectd.conf.in index b7c1b278..8bae3b67 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -1696,6 +1696,7 @@ # SeparateInstances false # PreserveSeparator false # DropDuplicateFields false +# ReverseHost false # # diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 03b163ef..5098fbe0 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -9445,6 +9445,7 @@ Synopsis: LogSendErrors true Prefix "collectd" UseTags false + ReverseHost false @@ -9556,6 +9557,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.c b/src/utils_format_graphite.c index de3f0c2e..41337d23 100644 --- a/src/utils_format_graphite.c +++ b/src/utils_format_graphite.c @@ -34,6 +34,37 @@ /* 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) { + char t; + for (int i = 0; i < len / 2; i++) { + int j = len - i - 1; + 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 +151,14 @@ 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) { + int len_host = strlen(vl->host); + char r_host[len_host + 1]; + 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 +236,16 @@ 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) { + int len_host = strlen(vl->host); + char r_host[len_host + 1]; + 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.h b/src/utils_format_graphite.h index 60b89ae7..4df7db3d 100644 --- a/src/utils_format_graphite.h +++ b/src/utils_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 7624e243..3d0a854b 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 {