master
c 110 lines 3.63 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "libnetdata/libnetdata.h"
4 #include "csv.h"
5
6 void rrdr2csv(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS options, const char *startline, const char *separator, const char *endline, const char *betweenlines) {
7 //netdata_log_info("RRD2CSV(): %s: BEGIN", r->st->id);
8 long c, i;
9 const long used = (long)r->d;
10
11 // print the csv header
12 for(c = 0, i = 0; c < used ; c++) {
13 if(!rrdr_dimension_should_be_exposed(r->od[c], options))
14 continue;
15
16 if(!i) {
17 buffer_strcat(wb, startline);
18 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
19 buffer_strcat(wb, "time");
20 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
21 }
22 buffer_strcat(wb, separator);
23 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
24 buffer_strcat(wb, string2str(r->dn[c]));
25 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
26 i++;
27 }
28
29 if(!i) {
30 // no dimensions present
31 return;
32 }
33
34 buffer_strcat(wb, endline);
35
36 if(format == DATASOURCE_CSV_MARKDOWN) {
37 // print the --- line after header
38 for(c = 0, i = 0; c < used ;c++) {
39 if(!rrdr_dimension_should_be_exposed(r->od[c], options))
40 continue;
41
42 if(!i) {
43 buffer_strcat(wb, startline);
44 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
45 buffer_strcat(wb, ":---:");
46 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
47 }
48 buffer_strcat(wb, separator);
49 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
50 buffer_strcat(wb, ":---:");
51 if(options & RRDR_OPTION_LABEL_QUOTES) buffer_strcat(wb, "\"");
52 i++;
53 }
54 buffer_strcat(wb, endline);
55 }
56
57 long start = 0, end = rrdr_rows(r), step = 1;
58 if(!(options & RRDR_OPTION_REVERSED)) {
59 start = rrdr_rows(r) - 1;
60 end = -1;
61 step = -1;
62 }
63
64 // for each line in the array
65 for(i = start; i != end ;i += step) {
66 NETDATA_DOUBLE *cn = &r->v[ i * r->d ];
67 RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ];
68
69 buffer_strcat(wb, betweenlines);
70 buffer_strcat(wb, startline);
71
72 time_t now = r->t[i];
73
74 if((options & RRDR_OPTION_SECONDS) || (options & RRDR_OPTION_MILLISECONDS)) {
75 // print the timestamp of the line
76 buffer_print_netdata_double(wb, (NETDATA_DOUBLE) now);
77 // in ms
78 if(options & RRDR_OPTION_MILLISECONDS) buffer_strcat(wb, "000");
79 }
80 else {
81 // generate the local date time
82 struct tm tmbuf, *tm = localtime_r(&now, &tmbuf);
83 if(!tm) {
84 netdata_log_error("localtime() failed."); continue; }
85 buffer_date(wb, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
86 }
87
88 // for each dimension
89 for(c = 0; c < used ;c++) {
90 if(!rrdr_dimension_should_be_exposed(r->od[c], options))
91 continue;
92
93 buffer_strcat(wb, separator);
94
95 NETDATA_DOUBLE n = cn[c];
96
97 if(co[c] & RRDR_VALUE_EMPTY) {
98 if(options & RRDR_OPTION_NULL2ZERO)
99 buffer_strcat(wb, "0");
100 else
101 buffer_strcat(wb, "null");
102 }
103 else
104 buffer_print_netdata_double(wb, n);
105 }
106
107 buffer_strcat(wb, endline);
108 }
109 //netdata_log_info("RRD2CSV(): %s: END", r->st->id);
110 }