mirror of
https://github.com/netdata/netdata.git
synced 2025-04-22 20:42:33 +00:00

* netdata doubles * fix cmocka test * fix cmocka test again * fix left-overs of long double to NETDATA_DOUBLE * RRDDIM detached from disk representation; db settings in [db] section of netdata.conf * update the memory before saving * rrdset is now detached from file structures too * on memory mode map, update the memory mapped structures on every iteration * allow RRD_ID_LENGTH_MAX to be changed * granularity secs, back to update every * fix formatting * more formatting
143 lines
5 KiB
C
143 lines
5 KiB
C
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
#include "libnetdata/libnetdata.h"
|
|
#include "csv.h"
|
|
|
|
void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const char *startline, const char *separator, const char *endline, const char *betweenlines, RRDDIM *temp_rd) {
|
|
rrdset_check_rdlock(r->st);
|
|
|
|
//info("RRD2CSV(): %s: BEGIN", r->st->id);
|
|
long c, i;
|
|
RRDDIM *d;
|
|
|
|
// print the csv header
|
|
for(c = 0, i = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
|
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
|
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
|
|
|
if(!i) {
|
|
buffer_strcat(wb, startline);
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
buffer_strcat(wb, "time");
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
}
|
|
buffer_strcat(wb, separator);
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
buffer_strcat(wb, d->name);
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
i++;
|
|
}
|
|
buffer_strcat(wb, endline);
|
|
|
|
if(format == DATASOURCE_CSV_MARKDOWN) {
|
|
// print the --- line after header
|
|
for(c = 0, i = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
|
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
|
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
|
|
|
if(!i) {
|
|
buffer_strcat(wb, startline);
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
buffer_strcat(wb, ":---:");
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
}
|
|
buffer_strcat(wb, separator);
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
buffer_strcat(wb, ":---:");
|
|
if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
|
|
i++;
|
|
}
|
|
buffer_strcat(wb, endline);
|
|
}
|
|
|
|
if(!i) {
|
|
// no dimensions present
|
|
return;
|
|
}
|
|
|
|
long start = 0, end = rrdr_rows(r), step = 1;
|
|
if(!(options & RRDR_OPTION_REVERSED)) {
|
|
start = rrdr_rows(r) - 1;
|
|
end = -1;
|
|
step = -1;
|
|
}
|
|
|
|
// for each line in the array
|
|
NETDATA_DOUBLE total = 1;
|
|
for(i = start; i != end ;i += step) {
|
|
NETDATA_DOUBLE *cn = &r->v[ i * r->d ];
|
|
RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ];
|
|
|
|
buffer_strcat(wb, betweenlines);
|
|
buffer_strcat(wb, startline);
|
|
|
|
time_t now = r->t[i];
|
|
|
|
if((options & RRDR_OPTION_SECONDS) || (options & RRDR_OPTION_MILLISECONDS)) {
|
|
// print the timestamp of the line
|
|
buffer_rrd_value(wb, (NETDATA_DOUBLE)now);
|
|
// in ms
|
|
if(options & RRDR_OPTION_MILLISECONDS) buffer_strcat(wb, "000");
|
|
}
|
|
else {
|
|
// generate the local date time
|
|
struct tm tmbuf, *tm = localtime_r(&now, &tmbuf);
|
|
if(!tm) { error("localtime() failed."); continue; }
|
|
buffer_date(wb, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
}
|
|
|
|
int set_min_max = 0;
|
|
if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
|
|
total = 0;
|
|
for(c = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
|
NETDATA_DOUBLE n = cn[c];
|
|
|
|
if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
|
|
n = -n;
|
|
|
|
total += n;
|
|
}
|
|
// prevent a division by zero
|
|
if(total == 0) total = 1;
|
|
set_min_max = 1;
|
|
}
|
|
|
|
// for each dimension
|
|
for(c = 0, d = temp_rd?temp_rd:r->st->dimensions; d && c < r->d ;c++, d = d->next) {
|
|
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
|
|
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
|
|
|
|
buffer_strcat(wb, separator);
|
|
|
|
NETDATA_DOUBLE n = cn[c];
|
|
|
|
if(co[c] & RRDR_VALUE_EMPTY) {
|
|
if(options & RRDR_OPTION_NULL2ZERO)
|
|
buffer_strcat(wb, "0");
|
|
else
|
|
buffer_strcat(wb, "null");
|
|
}
|
|
else {
|
|
if(unlikely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
|
|
n = -n;
|
|
|
|
if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
|
|
n = n * 100 / total;
|
|
|
|
if(unlikely(set_min_max)) {
|
|
r->min = r->max = n;
|
|
set_min_max = 0;
|
|
}
|
|
|
|
if(n < r->min) r->min = n;
|
|
if(n > r->max) r->max = n;
|
|
}
|
|
|
|
buffer_rrd_value(wb, n);
|
|
}
|
|
}
|
|
|
|
buffer_strcat(wb, endline);
|
|
}
|
|
//info("RRD2CSV(): %s: END", r->st->id);
|
|
}
|