added API option "unaligned" to allow getting unaligned data for any timeframe, fixes #253
Costa Tsaousis (ktsaou) committed
Jun 5, 2016 at 11:14 UTC
57a7171e38949ca7334ca92b49b167e81250c803
4 files changed
+16
-21
src/rrd2json.c
+9
-9
@@ -1224,7 +1224,7 @@ cleanup:
1224
return NULL;
1225
}
1226
1227
-RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int group_method)
1227
+RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int group_method, int aligned)
1228
{
1229
int debug = st->debug;
1230
int absolute_period_requested = -1;
@@ -1253,10 +1253,10 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1253
absolute_period_requested = 1;
1254
1255
// make sure they are within our timeframe
1256
- if(before > last_entry_t) before = last_entry_t;
1256
+ if(before > last_entry_t) before = last_entry_t;
1257
if(before < first_entry_t) before = first_entry_t;
1258
1259
- if(after > last_entry_t) after = last_entry_t;
1259
+ if(after > last_entry_t) after = last_entry_t;
1260
if(after < first_entry_t) after = first_entry_t;
1261
1262
// check if they are upside down
@@ -1285,13 +1285,13 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1285
// round group to the closest integer
1286
if(available_points % points > points / 2) group++;
1287
1288
- time_t after_new = after - (after % (group * st->update_every));
1289
- time_t before_new = before - (before % (group * st->update_every));
1290
- long points_new = (before_new - after_new) / st->update_every / group;
1288
+ time_t after_new = (aligned) ? (after - (after % (group * st->update_every))) : after;
1289
+ time_t before_new = (aligned) ? (before - (before % (group * st->update_every))) : before;
1290
+ long points_new = (before_new - after_new) / st->update_every / group;
1291
1292
// find the starting and ending slots in our round robin db
1293
long start_at_slot = rrdset_time2slot(st, before_new),
1294
- stop_at_slot = rrdset_time2slot(st, after_new);
1294
+ stop_at_slot = rrdset_time2slot(st, after_new);
1295
1296
#ifdef NETDATA_INTERNAL_CHECKS
1297
if(after_new < first_entry_t) {
@@ -1532,7 +1532,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1532
1533
int rrd2value(RRDSET *st, BUFFER *wb, calculated_number *n, BUFFER *dimensions, long points, long long after, long long before, int group_method, uint32_t options, time_t *latest_timestamp, int *value_is_null)
1534
{
1535
- RRDR *r = rrd2rrdr(st, points, after, before, group_method);
1535
+ RRDR *r = rrd2rrdr(st, points, after, before, group_method, !(options & RRDR_OPTION_NOT_ALIGNED));
1536
if(!r) {
1537
if(value_is_null) *value_is_null = 1;
1538
return 500;
@@ -1566,7 +1566,7 @@ int rrd2value(RRDSET *st, BUFFER *wb, calculated_number *n, BUFFER *dimensions,
1566
1567
int rrd2format(RRDSET *st, BUFFER *wb, BUFFER *dimensions, uint32_t format, long points, long long after, long long before, int group_method, uint32_t options, time_t *latest_timestamp)
1568
{
1569
- RRDR *r = rrd2rrdr(st, points, after, before, group_method);
1569
+ RRDR *r = rrd2rrdr(st, points, after, before, group_method, !(options & RRDR_OPTION_NOT_ALIGNED));
1570
if(!r) {
1571
buffer_strcat(wb, "Cannot generate output with these parameters on this chart.");
1572
return 500;
src/rrd2json.h
+2
-1
@@ -42,7 +42,7 @@ extern char *hostname;
42
#define RRDR_OPTION_NONZERO 0x00000001 // don't output dimensions will just zero values
43
#define RRDR_OPTION_REVERSED 0x00000002 // output the rows in reverse order (oldest to newest)
44
#define RRDR_OPTION_ABSOLUTE 0x00000004 // values positive, for DATASOURCE_SSV before summing
45
-#define RRDR_OPTION_MIN2MAX 0x00000008 // for DATASOURCE_SSV, out max - min, instead of sum
45
+#define RRDR_OPTION_MIN2MAX 0x00000008 // when adding dimensions, use max - min, instead of sum
46
#define RRDR_OPTION_SECONDS 0x00000010 // output seconds, instead of dates
47
#define RRDR_OPTION_MILLISECONDS 0x00000020 // output milliseconds, instead of dates
48
#define RRDR_OPTION_NULL2ZERO 0x00000040 // do not show nulls, convert them to zeros
@@ -51,6 +51,7 @@ extern char *hostname;
51
#define RRDR_OPTION_JSON_WRAP 0x00000200 // wrap the response in a JSON header with info about the result
52
#define RRDR_OPTION_LABEL_QUOTES 0x00000400 // in CSV output, wrap header labels in double quotes
53
#define RRDR_OPTION_PERCENTAGE 0x00000800 // give values as percentage of total
54
+#define RRDR_OPTION_NOT_ALIGNED 0x00001000 // do not align charts for persistant timeframes
55
56
extern void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb);
57
extern void rrd_stats_api_v1_charts(BUFFER *wb);
src/web_client.c
+3
-1
@@ -559,6 +559,8 @@ uint32_t web_client_api_request_v1_data_options(char *o)
559
ret |= RRDR_OPTION_GOOGLE_JSON;
560
else if(!strcmp(tok, "percentage"))
561
ret |= RRDR_OPTION_PERCENTAGE;
562
+ else if(!strcmp(tok, "unaligned"))
563
+ ret |= RRDR_OPTION_NOT_ALIGNED;
564
}
565
566
return ret;
@@ -802,7 +804,7 @@ int web_client_api_v1_badge(struct web_client *w, char *url) {
804
ret = 500;
805
806
// if the collected value is too old, don't calculate its value
805
- if(st->last_updated.tv_sec >= (time(NULL) - (st->update_every * st->gap_when_lost_iterations_above)))
807
+ if(rrdset_last_entry_t(st) >= (time(NULL) - (st->update_every * st->gap_when_lost_iterations_above)))
808
ret = rrd2value(st, w->response.data, &n, dimensions, points, after, before, group, options, &latest_timestamp, &value_is_null);
809
810
// if the value cannot be calculated, show empty badge
web/netdata-swagger.yaml
+2
-10
@@ -110,7 +110,7 @@ paths:
110
type: array
111
items:
112
type: string
113
- enum: [ 'nonzero', 'flip', 'jsonwrap', 'min2max', 'seconds', 'milliseconds', 'abs', 'absolute', 'absolute-sum', 'null2zero', 'objectrows', 'google_json', 'percentage' ]
113
+ enum: [ 'nonzero', 'flip', 'jsonwrap', 'min2max', 'seconds', 'milliseconds', 'abs', 'absolute', 'absolute-sum', 'null2zero', 'objectrows', 'google_json', 'percentage', 'unaligned' ]
114
collectionFormat: pipes
115
default: [seconds, jsonwrap]
116
allowEmptyValue: false
@@ -182,14 +182,6 @@ paths:
182
type: number
183
format: integer
184
default: 0
185
- - name: points
186
- in: query
187
- description: 'The number of points to be returned. If not given, or it is <= 0, or it is bigger than the points stored in the round robin database for this chart for the given duration, all the available collected values for the given duration are returned.'
188
- required: true
189
- type: number
190
- format: integer
191
- allowEmptyValue: false
192
- default: 20
185
- name: group
186
in: query
187
description: 'The grouping method. If multiple collected values are to be grouped in order to return fewer points, this parameters defines the method of grouping. Two methods are supported, "max" and "average". "max" is actually calculated on the absolute value collected (so it works for both positive and negative dimesions to return the most extreme value in either direction).'
@@ -205,7 +197,7 @@ paths:
197
type: array
198
items:
199
type: string
208
- enum: [ 'nonzero', 'flip', 'abs', 'absolute', 'absolute-sum', 'null2zero', 'percentage' ]
200
+ enum: [ 'abs', 'absolute', 'absolute-sum', 'null2zero', 'percentage', 'unaligned' ]
201
collectionFormat: pipes
202
default: ['absolute']
203
allowEmptyValue: true