query engine fixes for alarms and dashboards (#13282)
* fix health alignment to future; fix logs * ensure the query always covers the entire duration requested * better comments
Costa Tsaousis committed
Jun 30, 2022 at 23:33 UTC
beb985d09170aa453d451ae0e28b6258e0ea6351
1 file changed
+52
-29
web/api/queries/query.c
+52
-29
@@ -808,7 +808,11 @@ int rrdr_relative_window_to_absolute(long long *after, long long *before, int up
808
if(after_requested == 0)
809
after_requested = -(points * update_every);
810
811
- after_requested = before_requested + after_requested;
811
+ // since the query engine now returns inclusive timestamps
812
+ // it is awkward to return 6 points when after=-5 is given
813
+ // so for relative queries we add 1 second, to give
814
+ // more predictable results to users.
815
+ after_requested = before_requested + after_requested + 1;
816
absolute_period_requested = 0;
817
}
818
@@ -843,7 +847,7 @@ int rrdr_relative_window_to_absolute(long long *after, long long *before, int up
847
#define query_debug_log_init() BUFFER *debug_log = buffer_create(1000)
848
#define query_debug_log(args...) buffer_sprintf(debug_log, ##args)
849
#define query_debug_log_fin() { \
846
- info("QUERY: chart '%s', after:%lld, before:%lld, points:%ld, res:%ld - wanted => after:%lld, before:%lld, points:%ld, group:%ld, granularity:%ld, resgroup:%ld, resdiv:" NETDATA_DOUBLE_FORMAT_AUTO " %s", st->name, after_requested, before_requested, points_requested, resampling_time_requested, after_wanted, before_wanted, points_wanted, group, query_granularity, resampling_group, resampling_divisor, buffer_tostring(debug_log)); \
850
+ info("QUERY: chart '%s', after:%lld, before:%lld, duration:%lld, points:%ld, res:%ld - wanted => after:%lld, before:%lld, points:%ld, group:%ld, granularity:%ld, resgroup:%ld, resdiv:" NETDATA_DOUBLE_FORMAT_AUTO " %s", st->name, after_requested, before_requested, before_requested - after_requested, points_requested, resampling_time_requested, after_wanted, before_wanted, points_wanted, group, query_granularity, resampling_group, resampling_divisor, buffer_tostring(debug_log)); \
851
buffer_free(debug_log); \
852
debug_log = NULL; \
853
}
@@ -889,6 +893,7 @@ RRDR *rrd2rrdr(
893
bool automatic_natural_points = (points_wanted == 0);
894
bool relative_period_requested = false;
895
bool natural_points = (options & RRDR_OPTION_NATURAL_POINTS) || automatic_natural_points;
896
+ bool before_is_aligned_to_db_end = false;
897
898
query_debug_log_init();
899
@@ -931,6 +936,7 @@ RRDR *rrd2rrdr(
936
937
if (before_wanted == 0) {
938
before_wanted = last_entry_t;
939
+ before_is_aligned_to_db_end = true;
940
query_debug_log(":zero before_wanted %lld", before_wanted);
941
}
942
@@ -1014,6 +1020,21 @@ RRDR *rrd2rrdr(
1020
1021
query_debug_log(":group %ld", group);
1022
1023
+ if(points_wanted * group * query_granularity < duration) {
1024
+ // the grouping we are going to do, is not enough
1025
+ // to cover the entire duration requested, so
1026
+ // we have to change the number of points, to make sure we will
1027
+ // respect the timeframe as closely as possibly
1028
+
1029
+ // let's see how many points are the optimal
1030
+ points_wanted = points_available / group;
1031
+
1032
+ if(points_wanted * group < points_available)
1033
+ points_wanted++;
1034
+
1035
+ query_debug_log(":optimal points %ld", points_wanted);
1036
+ }
1037
+
1038
// resampling_time_requested enforces a certain grouping multiple
1039
NETDATA_DOUBLE resampling_divisor = 1.0;
1040
long resampling_group = 1;
@@ -1042,8 +1063,10 @@ RRDR *rrd2rrdr(
1063
1064
// now that we have group, align the requested timeframe to fit it.
1065
if(aligned && before_wanted % (group * query_granularity)) {
1045
- // alignment has been requested, so align the end timestamp
1046
- before_wanted += (group * query_granularity) - before_wanted % (group * query_granularity);
1066
+ if(before_is_aligned_to_db_end)
1067
+ before_wanted -= before_wanted % (group * query_granularity);
1068
+ else
1069
+ before_wanted += (group * query_granularity) - before_wanted % (group * query_granularity);
1070
query_debug_log(":align before_wanted %lld", before_wanted);
1071
}
1072
@@ -1051,7 +1074,7 @@ RRDR *rrd2rrdr(
1074
query_debug_log(":final after_wanted %lld", after_wanted);
1075
1076
duration = before_wanted - after_wanted;
1054
- query_debug_log(":final duration %ld", duration);
1077
+ query_debug_log(":final duration %ld", duration + 1);
1078
1079
// check the context query based on the starting time of the query
1080
if (context_param_list && !(context_param_list->flags & CONTEXT_FLAGS_ARCHIVE)) {
@@ -1204,45 +1227,45 @@ RRDR *rrd2rrdr(
1227
#ifdef NETDATA_INTERNAL_CHECKS
1228
if (dimensions_used) {
1229
if(r->internal.log)
1207
- rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group, after_wanted,
1208
- after_wanted, before_wanted,
1209
- before_wanted,
1210
- points_wanted, points_wanted, /*after_slot, before_slot,*/ r->internal.log);
1230
+ rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group,
1231
+ after_wanted, after_requested, before_wanted, before_requested,
1232
+ points_requested, points_wanted, /*after_slot, before_slot,*/
1233
+ r->internal.log);
1234
1235
if(r->rows != points_wanted)
1213
- rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group, after_wanted,
1214
- after_wanted, before_wanted,
1215
- before_wanted,
1216
- points_wanted, points_wanted, /*after_slot, before_slot,*/ "got 'points' is not wanted 'points'");
1236
+ rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group,
1237
+ after_wanted, after_requested, before_wanted, before_requested,
1238
+ points_requested, points_wanted, /*after_slot, before_slot,*/
1239
+ "got 'points' is not wanted 'points'");
1240
1241
if(aligned && (r->before % (group * query_granularity)) != 0)
1219
- rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group, after_wanted,
1220
- after_wanted, before_wanted,
1221
- before_wanted,
1222
- points_wanted, points_wanted, /*after_slot, before_slot,*/ "'before' is not aligned but alignment is required");
1242
+ rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group,
1243
+ after_wanted, after_requested, before_wanted,before_wanted,
1244
+ points_requested, points_wanted, /*after_slot, before_slot,*/
1245
+ "'before' is not aligned but alignment is required");
1246
1247
// 'after' should not be aligned, since we start inside the first group
1248
//if(aligned && (r->after % group) != 0)
1249
// rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group, after_wanted, after_requested, before_wanted, before_requested, points_requested, points_wanted, after_slot, before_slot, "'after' is not aligned but alignment is required");
1250
1251
if(r->before != before_wanted)
1229
- rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group, after_wanted,
1230
- after_wanted, before_wanted,
1231
- before_wanted,
1232
- points_wanted, points_wanted, /*after_slot, before_slot,*/ "chart is not aligned to requested 'before'");
1252
+ rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group,
1253
+ after_wanted, after_requested, before_wanted, before_requested,
1254
+ points_requested, points_wanted, /*after_slot, before_slot,*/
1255
+ "chart is not aligned to requested 'before'");
1256
1257
if(r->before != before_wanted)
1235
- rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group, after_wanted,
1236
- after_wanted, before_wanted,
1237
- before_wanted,
1238
- points_wanted, points_wanted, /*after_slot, before_slot,*/ "got 'before' is not wanted 'before'");
1258
+ rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group,
1259
+ after_wanted, after_requested, before_wanted, before_requested,
1260
+ points_requested, points_wanted, /*after_slot, before_slot,*/
1261
+ "got 'before' is not wanted 'before'");
1262
1263
// reported 'after' varies, depending on group
1264
if(r->after != after_wanted)
1242
- rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group, after_wanted,
1243
- after_wanted, before_wanted,
1244
- before_wanted,
1245
- points_wanted, points_wanted, /*after_slot, before_slot,*/ "got 'after' is not wanted 'after'");
1265
+ rrd2rrdr_log_request_response_metadata(r, group_method, aligned, group, resampling_time_requested, resampling_group,
1266
+ after_wanted, after_requested, before_wanted, before_requested,
1267
+ points_requested, points_wanted, /*after_slot, before_slot,*/
1268
+ "got 'after' is not wanted 'after'");
1269
}
1270
#endif
1271