Viewing file: csv.c (5 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// 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 calculated_number total = 1; for(i = start; i != end ;i += step) { calculated_number *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, (calculated_number)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) { calculated_number 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);
calculated_number 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); }
|