diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backends.c | 52 | ||||
-rw-r--r-- | src/backends.h | 3 | ||||
-rw-r--r-- | src/plugin_proc_diskspace.c | 39 | ||||
-rw-r--r-- | src/rrd2json.c | 58 | ||||
-rw-r--r-- | src/rrd2json.h | 4 | ||||
-rw-r--r-- | src/web_api_v1.c | 12 |
6 files changed, 137 insertions, 31 deletions
diff --git a/src/backends.c b/src/backends.c index 58689d2b27..4c817f16a9 100644 --- a/src/backends.c +++ b/src/backends.c @@ -26,10 +26,25 @@ #define BACKEND_SOURCE_DATA_AVERAGE 0x00000002 #define BACKEND_SOURCE_DATA_SUM 0x00000004 +int backend_send_names = 1; // ---------------------------------------------------------------------------- // helper functions for backends +static inline size_t backend_name_copy(char *d, const char *s, size_t usable) { + size_t n; + + for(n = 0; *s && n < usable ; d++, s++, n++) { + char c = *s; + + if(c != '.' && !isalnum(c)) *d = '_'; + else *d = c; + } + *d = '\0'; + + return n; +} + // calculate the SUM or AVERAGE of a dimension, for any timeframe // may return NAN if the database does not have any value in the give timeframe @@ -156,13 +171,18 @@ static inline int format_dimension_collected_graphite_plaintext( (void)before; (void)options; + char chart_name[RRD_ID_LENGTH_MAX + 1]; + char dimension_name[RRD_ID_LENGTH_MAX + 1]; + backend_name_copy(chart_name, (backend_send_names && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); + backend_name_copy(dimension_name, (backend_send_names && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); + buffer_sprintf( b , "%s.%s.%s.%s " COLLECTED_NUMBER_FORMAT " %u\n" , prefix , hostname - , st->id - , rd->id + , chart_name + , dimension_name , rd->last_collected_value , (uint32_t)rd->last_collected_time.tv_sec ); @@ -183,6 +203,11 @@ static inline int format_dimension_stored_graphite_plaintext( ) { (void)host; + char chart_name[RRD_ID_LENGTH_MAX + 1]; + char dimension_name[RRD_ID_LENGTH_MAX + 1]; + backend_name_copy(chart_name, (backend_send_names && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); + backend_name_copy(dimension_name, (backend_send_names && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); + calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options); if(!isnan(value)) { @@ -192,8 +217,8 @@ static inline int format_dimension_stored_graphite_plaintext( , "%s.%s.%s.%s " CALCULATED_NUMBER_FORMAT " %u\n" , prefix , hostname - , st->id - , rd->id + , chart_name + , dimension_name , value , (uint32_t) before ); @@ -227,12 +252,17 @@ static inline int format_dimension_collected_opentsdb_telnet( (void)before; (void)options; + char chart_name[RRD_ID_LENGTH_MAX + 1]; + char dimension_name[RRD_ID_LENGTH_MAX + 1]; + backend_name_copy(chart_name, (backend_send_names && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); + backend_name_copy(dimension_name, (backend_send_names && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); + buffer_sprintf( b , "put %s.%s.%s %u " COLLECTED_NUMBER_FORMAT " host=%s%s%s\n" , prefix - , st->id - , rd->id + , chart_name + , dimension_name , (uint32_t)rd->last_collected_time.tv_sec , rd->last_collected_value , hostname @@ -258,14 +288,19 @@ static inline int format_dimension_stored_opentsdb_telnet( calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options); + char chart_name[RRD_ID_LENGTH_MAX + 1]; + char dimension_name[RRD_ID_LENGTH_MAX + 1]; + backend_name_copy(chart_name, (backend_send_names && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX); + backend_name_copy(dimension_name, (backend_send_names && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX); + if(!isnan(value)) { buffer_sprintf( b , "put %s.%s.%s %u " CALCULATED_NUMBER_FORMAT " host=%s%s%s\n" , prefix - , st->id - , rd->id + , chart_name + , dimension_name , (uint32_t) before , value , hostname @@ -464,6 +499,7 @@ void *backends_main(void *ptr) { int frequency = (int)config_get_number(CONFIG_SECTION_BACKEND, "update every", 10); int buffer_on_failures = (int)config_get_number(CONFIG_SECTION_BACKEND, "buffer on failures", 10); long timeoutms = config_get_number(CONFIG_SECTION_BACKEND, "timeout ms", frequency * 2 * 1000); + backend_send_names = config_get_boolean(CONFIG_SECTION_BACKEND, "send names instead of ids", backend_send_names); charts_pattern = simple_pattern_create(config_get(CONFIG_SECTION_BACKEND, "send charts matching", "*"), SIMPLE_PATTERN_EXACT); diff --git a/src/backends.h b/src/backends.h index 61122a1d07..afd246e6e4 100644 --- a/src/backends.h +++ b/src/backends.h @@ -1,6 +1,7 @@ #ifndef NETDATA_BACKENDS_H #define NETDATA_BACKENDS_H 1 -void *backends_main(void *ptr); +extern int backend_send_names; +extern void *backends_main(void *ptr); #endif /* NETDATA_BACKENDS_H */ diff --git a/src/plugin_proc_diskspace.c b/src/plugin_proc_diskspace.c index 71173306c5..750086a2c2 100644 --- a/src/plugin_proc_diskspace.c +++ b/src/plugin_proc_diskspace.c @@ -125,6 +125,33 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { def_inodes = CONFIG_BOOLEAN_NO; } + // check if the mount point is a directory #2407 + { + struct stat bs; + if(stat(mi->mount_point, &bs) == -1) { + error("DISKSPACE: Cannot stat() mount point '%s' (disk '%s', filesystem '%s', root '%s')." + , mi->mount_point + , disk + , mi->filesystem?mi->filesystem:"" + , mi->root?mi->root:"" + ); + def_space = CONFIG_BOOLEAN_NO; + def_inodes = CONFIG_BOOLEAN_NO; + } + else { + if((bs.st_mode & S_IFMT) != S_IFDIR) { + error("DISKSPACE: Mount point '%s' (disk '%s', filesystem '%s', root '%s') is not a directory." + , mi->mount_point + , disk + , mi->filesystem?mi->filesystem:"" + , mi->root?mi->root:"" + ); + def_space = CONFIG_BOOLEAN_NO; + def_inodes = CONFIG_BOOLEAN_NO; + } + } + } + do_space = config_get_boolean_ondemand(var_name, "space usage", def_space); do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes); @@ -161,7 +188,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { struct statvfs buff_statvfs; if (statvfs(mi->mount_point, &buff_statvfs) < 0) { if(!m->shown_error) { - error("Failed statvfs() for '%s' (disk '%s', filesystem '%s', root '%s')" + error("DISKSPACE: failed to statvfs() mount point '%s' (disk '%s', filesystem '%s', root '%s')" , mi->mount_point , disk , mi->filesystem?mi->filesystem:"" @@ -188,7 +215,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { #ifdef NETDATA_INTERNAL_CHECKS if(unlikely(btotal != bavail + breserved_root + bused)) - error("Disk block statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)btotal, (unsigned long long)bavail, (unsigned long long)breserved_root, (unsigned long long)bused); + error("DISKSPACE: disk block statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)btotal, (unsigned long long)bavail, (unsigned long long)breserved_root, (unsigned long long)bused); #endif // -------------------------------------------------------------------------- @@ -201,7 +228,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { #ifdef NETDATA_INTERNAL_CHECKS if(unlikely(btotal != bavail + breserved_root + bused)) - error("Disk inode statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)ftotal, (unsigned long long)favail, (unsigned long long)freserved_root, (unsigned long long)fused); + error("DISKSPACE: disk inode statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)ftotal, (unsigned long long)favail, (unsigned long long)freserved_root, (unsigned long long)fused); #endif // -------------------------------------------------------------------------- @@ -294,10 +321,10 @@ void *proc_diskspace_main(void *ptr) { info("DISKSPACE thread created with task id %d", gettid()); if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0) - error("Cannot set pthread cancel type to DEFERRED."); + error("DISKSPACE: Cannot set pthread cancel type to DEFERRED."); if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) - error("Cannot set pthread cancel state to ENABLE."); + error("DISKSPACE: Cannot set pthread cancel state to ENABLE."); int vdo_cpu_netdata = config_get_boolean("plugin:proc", "netdata server resources", 1); @@ -334,7 +361,7 @@ void *proc_diskspace_main(void *ptr) { struct mountinfo *mi; for(mi = disk_mountinfo_root; mi; mi = mi->next) { - if(unlikely(mi->flags & (MOUNTINFO_IS_DUMMY | MOUNTINFO_IS_BIND | MOUNTINFO_IS_SAME_DEV | MOUNTINFO_NO_STAT | MOUNTINFO_NO_SIZE))) + if(unlikely(mi->flags & (MOUNTINFO_IS_DUMMY | MOUNTINFO_IS_BIND))) continue; do_disk_space_stats(mi, update_every); diff --git a/src/rrd2json.c b/src/rrd2json.c index ec79cb6172..314c2bc2a1 100644 --- a/src/rrd2json.c +++ b/src/rrd2json.c @@ -176,7 +176,7 @@ static inline size_t prometheus_name_copy(char *d, const char *s, size_t usable) for(n = 0; *s && n < usable ; d++, s++, n++) { register char c = *s; - if(unlikely(!isalnum(c))) *d = '_'; + if(!isalnum(c)) *d = '_'; else *d = c; } *d = '\0'; @@ -184,19 +184,43 @@ static inline size_t prometheus_name_copy(char *d, const char *s, size_t usable) return n; } +static inline size_t prometheus_label_copy(char *d, const char *s, size_t usable) { + size_t n; + + // make sure we can escape one character without overflowing the buffer + usable--; + + for(n = 0; *s && n < usable ; d++, s++, n++) { + register char c = *s; + + if(unlikely(c == '"' || c == '\\' || c == '\n')) { + *d++ = '\\'; + n++; + } + *d = c; + } + *d = '\0'; + + return n; +} + #define PROMETHEUS_ELEMENT_MAX 256 -void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, int help, int types) { +void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, int help, int types, int names) { rrdhost_rdlock(host); char hostname[PROMETHEUS_ELEMENT_MAX + 1]; - prometheus_name_copy(hostname, host->hostname, PROMETHEUS_ELEMENT_MAX); + prometheus_label_copy(hostname, host->hostname, PROMETHEUS_ELEMENT_MAX); // for each chart RRDSET *st; rrdset_foreach_read(st, host) { char chart[PROMETHEUS_ELEMENT_MAX + 1]; - prometheus_name_copy(chart, st->id, PROMETHEUS_ELEMENT_MAX); + + if(unlikely(names && st->name)) + prometheus_name_copy(chart, st->name, PROMETHEUS_ELEMENT_MAX); + else + prometheus_name_copy(chart, st->id, PROMETHEUS_ELEMENT_MAX); buffer_strcat(wb, "\n"); if(rrdset_is_available_for_backends(st)) { @@ -207,7 +231,11 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, in rrddim_foreach_read(rd, st) { if(rd->collections_counter) { char dimension[PROMETHEUS_ELEMENT_MAX + 1]; - prometheus_name_copy(dimension, rd->id, PROMETHEUS_ELEMENT_MAX); + + if(unlikely(names && rd->name)) + prometheus_name_copy(dimension, rd->name, PROMETHEUS_ELEMENT_MAX); + else + prometheus_name_copy(dimension, rd->id, PROMETHEUS_ELEMENT_MAX); const char *t = "gauge", *h = "gives"; if(rd->algorithm == RRD_ALGORITHM_INCREMENTAL || rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) { @@ -216,7 +244,15 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, in } if(unlikely(help)) - buffer_sprintf(wb, "# HELP netdata chart %s, dimension %s, value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n", st->id, rd->id, rd->multiplier, rd->divisor, h, st->units, t); + buffer_sprintf(wb, "# HELP netdata chart %s, dimension %s, value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n" + , (names && st->name)?st->name:st->id + , (names && rd->name)?rd->name:rd->id + , rd->multiplier + , rd->divisor + , h + , st->units + , t + ); if(unlikely(types)) buffer_sprintf(wb, "# TYPE %s_%s %s\n", chart, dimension, t); @@ -238,11 +274,11 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, in rrdhost_unlock(host); } -void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(BUFFER *wb, int help, int types) { +void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(BUFFER *wb, int help, int types, int names) { RRDHOST *host; rrd_rdlock(); rrdhost_foreach_read(host) { - rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, help, types); + rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, help, types, names); } rrd_unlock(); } @@ -275,7 +311,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) { rrdset_foreach_read(st, host) { calculated_number total = 0.0; char chart[SHELL_ELEMENT_MAX + 1]; - shell_name_copy(chart, st->id, SHELL_ELEMENT_MAX); + shell_name_copy(chart, st->name?st->name:st->id, SHELL_ELEMENT_MAX); buffer_sprintf(wb, "\n# chart: %s (name: %s)\n", st->id, st->name); if(rrdset_is_available_for_viewers(st)) { @@ -286,7 +322,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) { rrddim_foreach_read(rd, st) { if(rd->collections_counter) { char dimension[SHELL_ELEMENT_MAX + 1]; - shell_name_copy(dimension, rd->id, SHELL_ELEMENT_MAX); + shell_name_copy(dimension, rd->name?rd->name:rd->id, SHELL_ELEMENT_MAX); calculated_number n = rd->last_stored_value; @@ -314,7 +350,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) { if(!rc->rrdset) continue; char chart[SHELL_ELEMENT_MAX + 1]; - shell_name_copy(chart, rc->rrdset->id, SHELL_ELEMENT_MAX); + shell_name_copy(chart, rc->rrdset->name?rc->rrdset->name:rc->rrdset->id, SHELL_ELEMENT_MAX); char alarm[SHELL_ELEMENT_MAX + 1]; shell_name_copy(alarm, rc->name, SHELL_ELEMENT_MAX); diff --git a/src/rrd2json.h b/src/rrd2json.h index b3daffb47b..9f4a456f95 100644 --- a/src/rrd2json.h +++ b/src/rrd2json.h @@ -67,8 +67,8 @@ extern void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb); extern void rrd_stats_api_v1_charts_allmetrics_json(RRDHOST *host, BUFFER *wb); extern void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb); -extern void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, int help, int types); -extern void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(BUFFER *wb, int help, int types); +extern void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb, int help, int types, int names); +extern void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(BUFFER *wb, int help, int types, int names); extern int rrdset2anything_api_v1(RRDSET *st, BUFFER *out, BUFFER *dimensions, uint32_t format, long points , long long after, long long before, int group_method, uint32_t options diff --git a/src/web_api_v1.c b/src/web_api_v1.c index 8cae798e5b..83a3197ede 100644 --- a/src/web_api_v1.c +++ b/src/web_api_v1.c @@ -208,7 +208,7 @@ inline int web_client_api_request_v1_charts(RRDHOST *host, struct web_client *w, inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client *w, char *url) { int format = ALLMETRICS_SHELL; - int help = 0, types = 0; // prometheus options + int help = 0, types = 0, names = backend_send_names; // prometheus options while(url) { char *value = mystrsep(&url, "?&"); @@ -242,6 +242,12 @@ inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client else types = 0; } + else if(!strcmp(name, "names")) { + if(!strcmp(value, "yes")) + names = 1; + else + names = 0; + } } buffer_flush(w->response.data); @@ -260,12 +266,12 @@ inline int web_client_api_request_v1_allmetrics(RRDHOST *host, struct web_client case ALLMETRICS_PROMETHEUS: w->response.data->contenttype = CT_PROMETHEUS; - rrd_stats_api_v1_charts_allmetrics_prometheus(host, w->response.data, help, types); + rrd_stats_api_v1_charts_allmetrics_prometheus(host, w->response.data, help, types, names); return 200; case ALLMETRICS_PROMETHEUS_ALL_HOSTS: w->response.data->contenttype = CT_PROMETHEUS; - rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(w->response.data, help, types); + rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(w->response.data, help, types, names); return 200; default: |