void rrd_stats_api_v1_chart_with_data(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used)
{
- pthread_rwlock_rdlock(&st->rwlock);
+ rrdset_rdlock(st);
buffer_sprintf(wb,
"\t\t{\n"
size_t dimensions = 0;
RRDDIM *rd;
- for(rd = st->dimensions; rd ; rd = rd->next) {
+ rrddim_foreach_read(rd, st) {
if(rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)) continue;
memory += rd->memsize;
"\n\t\t}"
);
- pthread_rwlock_unlock(&st->rwlock);
+ rrdset_unlock(st);
}
void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb) {
",\n\t\"charts\": {"
, host->hostname
, program_version
- , os_type
+ , host->os
, host->rrd_update_every
, host->rrd_history_entries
);
- pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
- for(st = host->rrdset_root, c = 0; st ; st = st->next) {
+ c = 0;
+ rrdhost_rdlock(host);
+ rrdset_foreach_read(st, host) {
if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
if(c) buffer_strcat(wb, ",");
buffer_strcat(wb, "\n\t\t\"");
if(rc->rrdset)
alarms++;
}
- pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+ rrdhost_unlock(host);
buffer_sprintf(wb, "\n\t}"
",\n\t\"charts_count\": %zu"
",\n\t\"dimensions_count\": %zu"
",\n\t\"alarms_count\": %zu"
",\n\t\"rrd_memory_bytes\": %zu"
- "\n}\n"
+ ",\n\t\"hosts_count\": %zu"
+ ",\n\t\"hosts\": ["
, c
, dimensions
, alarms
, memory
+ , rrd_hosts_available
);
+
+ if(unlikely(rrd_hosts_available > 1)) {
+ rrd_rdlock();
+ RRDHOST *h;
+ rrdhost_foreach_read(h)
+ buffer_sprintf(wb,
+ "%s\n\t\t{"
+ "\n\t\t\t\"hostname\": \"%s\""
+ "\n\t\t}"
+ , (h != localhost)?",":""
+ , h->hostname
+ );
+ rrd_unlock();
+ }
+ else {
+ buffer_sprintf(wb,
+ "\n\t\t{"
+ "\n\t\t\t\"hostname\": \"%s\""
+ "\n\t\t}"
+ , host->hostname
+ );
+ }
+
+ buffer_sprintf(wb, "\n\t]\n}\n");
}
// ----------------------------------------------------------------------------
#define PROMETHEUS_ELEMENT_MAX 256
void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb) {
- pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
+ rrdhost_rdlock(host);
char hostname[PROMETHEUS_ELEMENT_MAX + 1];
- prometheus_name_copy(hostname, config_get("global", "hostname", "localhost"), PROMETHEUS_ELEMENT_MAX);
+ prometheus_name_copy(hostname, host->hostname, PROMETHEUS_ELEMENT_MAX);
// for each chart
RRDSET *st;
- for(st = host->rrdset_root; st ; st = st->next) {
+ rrdset_foreach_read(st, host) {
char chart[PROMETHEUS_ELEMENT_MAX + 1];
prometheus_name_copy(chart, st->id, PROMETHEUS_ELEMENT_MAX);
buffer_strcat(wb, "\n");
if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
- pthread_rwlock_rdlock(&st->rwlock);
+ rrdset_rdlock(st);
// for each dimension
RRDDIM *rd;
- for(rd = st->dimensions; rd ; rd = rd->next) {
- if(rd->counter) {
+ rrddim_foreach_read(rd, st) {
+ if(rd->collections_counter) {
char dimension[PROMETHEUS_ELEMENT_MAX + 1];
prometheus_name_copy(dimension, rd->id, PROMETHEUS_ELEMENT_MAX);
}
}
- pthread_rwlock_unlock(&st->rwlock);
+ rrdset_unlock(st);
}
}
- pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+ rrdhost_unlock(host);
}
// ----------------------------------------------------------------------------
#define SHELL_ELEMENT_MAX 100
void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
- pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
+ rrdhost_rdlock(host);
// for each chart
RRDSET *st;
- for(st = host->rrdset_root; st ; st = st->next) {
+ 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);
buffer_sprintf(wb, "\n# chart: %s (name: %s)\n", st->id, st->name);
if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
- pthread_rwlock_rdlock(&st->rwlock);
+ rrdset_rdlock(st);
// for each dimension
RRDDIM *rd;
- for(rd = st->dimensions; rd ; rd = rd->next) {
- if(rd->counter) {
+ rrddim_foreach_read(rd, st) {
+ if(rd->collections_counter) {
char dimension[SHELL_ELEMENT_MAX + 1];
shell_name_copy(dimension, rd->id, SHELL_ELEMENT_MAX);
total = roundl(total);
buffer_sprintf(wb, "NETDATA_%s_VISIBLETOTAL=\"%0.0Lf\" # %s\n", chart, total, st->units);
- pthread_rwlock_unlock(&st->rwlock);
+ rrdset_unlock(st);
}
}
buffer_sprintf(wb, "NETDATA_ALARM_%s_%s_STATUS=\"%s\"\n", chart, alarm, rrdcalc_status2string(rc->status));
}
- pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+ rrdhost_unlock(host);
}
// ----------------------------------------------------------------------------
{
time_t now = now_realtime_sec();
- pthread_rwlock_rdlock(&st->rwlock);
+ rrdset_rdlock(st);
buffer_sprintf(wb,
"\t\t{\n"
unsigned long memory = st->memsize;
RRDDIM *rd;
- for(rd = st->dimensions; rd ; rd = rd->next) {
+ rrddim_foreach_read(rd, st) {
memory += rd->memsize;
, memory
);
- pthread_rwlock_unlock(&st->rwlock);
+ rrdset_unlock(st);
return memory;
}
void rrd_stats_all_json(RRDHOST *host, BUFFER *wb)
{
unsigned long memory = 0;
- long c;
+ long c = 0;
RRDSET *st;
buffer_strcat(wb, RRD_GRAPH_JSON_HEADER);
- pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
- for(st = host->rrdset_root, c = 0; st ; st = st->next) {
+ rrdhost_rdlock(host);
+ rrdset_foreach_read(st, host) {
if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
if(c) buffer_strcat(wb, ",\n");
memory += rrd_stats_one_json(st, NULL, wb);
c++;
}
}
- pthread_rwlock_unlock(&host->rrdset_root_rwlock);
+ rrdhost_unlock(host);
buffer_sprintf(wb, "\n\t],\n"
"\t\"hostname\": \"%s\",\n"
*/
void rrdr_disable_not_selected_dimensions(RRDR *r, uint32_t options, const char *dims) {
+ rrdset_check_rdlock(r->st);
+
if(unlikely(!dims || !*dims)) return;
char b[strlen(dims) + 1];
uint32_t rrdr_check_options(RRDR *r, uint32_t options, const char *dims)
{
+ rrdset_check_rdlock(r->st);
+
(void)dims;
if(options & RRDR_OPTION_NONZERO) {
void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, uint32_t options, int string_value)
{
+ rrdset_check_rdlock(r->st);
+
long rows = rrdr_rows(r);
long c, i;
RRDDIM *rd;
static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
{
+ rrdset_check_rdlock(r->st);
+
//info("RRD2JSON(): %s: BEGIN", r->st->id);
int row_annotations = 0, dates, dates_with_new = 0;
char kq[2] = "", // key quote
static void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t options, const char *startline, const char *separator, const char *endline, const char *betweenlines)
{
+ rrdset_check_rdlock(r->st);
+
//info("RRD2CSV(): %s: BEGIN", r->st->id);
long c, i;
RRDDIM *d;
}
inline static calculated_number rrdr2value(RRDR *r, long i, uint32_t options, int *all_values_are_null) {
+ rrdset_check_rdlock(r->st);
+
long c;
RRDDIM *d;
return;
}
- pthread_rwlock_rdlock(&r->st->rwlock);
+ rrdset_rdlock(r->st);
r->has_st_lock = 1;
}
}
if(likely(r->has_st_lock)) {
- pthread_rwlock_unlock(&r->st->rwlock);
+ rrdset_unlock(r->st);
r->has_st_lock = 0;
}
}
rrdr_lock_rrdset(r);
RRDDIM *rd;
- for(rd = st->dimensions ; rd ; rd = rd->next) r->d++;
+ rrddim_foreach_read(rd, st) r->d++;
r->n = n;
// initialize them
RRDDIM *rd;
long c;
+ rrdset_check_rdlock(st);
for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
last_values[c] = 0;
group_values[c] = (group_method == GROUP_MAX || group_method == GROUP_MIN)?NAN:0;
time_t rrd_stats_json(int type, RRDSET *st, BUFFER *wb, long points, long group, int group_method, time_t after, time_t before, int only_non_zero)
{
int c;
- pthread_rwlock_rdlock(&st->rwlock);
+ rrdset_rdlock(st);
// -------------------------------------------------------------------------
int dimensions = 0;
RRDDIM *rd;
- for( rd = st->dimensions ; rd ; rd = rd->next) dimensions++;
+ rrddim_foreach_read(rd, st) dimensions++;
if(!dimensions) {
- pthread_rwlock_unlock(&st->rwlock);
+ rrdset_unlock(st);
buffer_strcat(wb, "No dimensions yet.");
return 0;
}
debug(D_RRD_STATS, "RRD_STATS_JSON: %s total %zu bytes", st->name, wb->len);
- pthread_rwlock_unlock(&st->rwlock);
+ rrdset_unlock(st);
return last_timestamp;
}