fix logs POST query payload parsing (#18722)
Costa Tsaousis committed
Oct 8, 2024 at 17:13 UTC
f57d5e79951a3dae1b7831536d1fd6ce1685069b
1 file changed
+39
-58
src/libnetdata/facets/logs_query_status.h
+39
-58
@@ -16,7 +16,8 @@
16
#define LQS_PARAMETER_DIRECTION "direction"
17
#define LQS_PARAMETER_IF_MODIFIED_SINCE "if_modified_since"
18
#define LQS_PARAMETER_DATA_ONLY "data_only"
19
-#define LQS_PARAMETER_SOURCE "source"
19
+#define LQS_PARAMETER_SOURCE "__logs_sources" // this must never conflict with user fields
20
+#define LQS_PARAMETER_SOURCE_NAME "Logs Sources" // this is how it is shown to users
21
#define LQS_PARAMETER_INFO "info"
22
#define LQS_PARAMETER_SLICE "slice"
23
#define LQS_PARAMETER_DELTA "delta"
@@ -350,59 +351,10 @@ static inline bool lqs_request_parse_json_payload(json_object *jobj, const char
351
JSONC_PARSE_TXT2STRDUPZ_OR_ERROR_AND_RETURN(jobj, path, LQS_PARAMETER_QUERY, rq->query, error, false);
352
JSONC_PARSE_TXT2STRDUPZ_OR_ERROR_AND_RETURN(jobj, path, LQS_PARAMETER_HISTOGRAM, rq->histogram, error, false);
353
353
- json_object *sources;
354
- if (json_object_object_get_ex(jobj, LQS_PARAMETER_SOURCE, &sources)) {
355
- if (json_object_get_type(sources) != json_type_array) {
356
- buffer_sprintf(error, "member '%s' is not an array", LQS_PARAMETER_SOURCE);
357
- // nd_log(NDLS_COLLECTORS, NDLP_ERR, "POST payload: '%s' is not an array", LQS_PARAMETER_SOURCE);
358
- return false;
359
- }
360
-
361
- buffer_json_member_add_array(wb, LQS_PARAMETER_SOURCE);
362
-
363
- CLEAN_BUFFER *sources_list = buffer_create(0, NULL);
364
-
365
- rq->source_type = LQS_SOURCE_TYPE_NONE;
366
-
367
- size_t sources_len = json_object_array_length(sources);
368
- for (size_t i = 0; i < sources_len; i++) {
369
- json_object *src = json_object_array_get_idx(sources, i);
370
-
371
- if (json_object_get_type(src) != json_type_string) {
372
- buffer_sprintf(error, "sources array item %zu is not a string", i);
373
- // nd_log(NDLS_COLLECTORS, NDLP_ERR, "POST payload: sources array item %zu is not a string", i);
374
- return false;
375
- }
376
-
377
- const char *value = json_object_get_string(src);
378
- buffer_json_add_array_item_string(wb, value);
379
-
380
- LQS_SOURCE_TYPE t = LQS_FUNCTION_GET_INTERNAL_SOURCE_TYPE(value);
381
- if(t != LQS_SOURCE_TYPE_NONE) {
382
- rq->source_type |= t;
383
- value = NULL;
384
- }
385
- else {
386
- // else, match the source, whatever it is
387
- if(buffer_strlen(sources_list))
388
- buffer_putc(sources_list, '|');
389
-
390
- buffer_strcat(sources_list, value);
391
- }
392
- }
393
-
394
- if(buffer_strlen(sources_list)) {
395
- simple_pattern_free(rq->sources);
396
- rq->sources = simple_pattern_create(buffer_tostring(sources_list), "|", SIMPLE_PATTERN_EXACT, false);
397
- }
398
-
399
- buffer_json_array_close(wb); // source
400
- }
401
-
354
json_object *fcts;
355
if (json_object_object_get_ex(jobj, LQS_PARAMETER_FACETS, &fcts)) {
404
- if (json_object_get_type(sources) != json_type_array) {
405
- buffer_sprintf(error, "member '%s' is not an array", LQS_PARAMETER_FACETS);
356
+ if (json_object_get_type(fcts) != json_type_array) {
357
+ buffer_sprintf(error, "member '%s' is not an array.", LQS_PARAMETER_FACETS);
358
// nd_log(NDLS_COLLECTORS, NDLP_ERR, "POST payload: '%s' is not an array", LQS_PARAMETER_FACETS);
359
return false;
360
}
@@ -440,7 +392,11 @@ static inline bool lqs_request_parse_json_payload(json_object *jobj, const char
392
393
buffer_json_member_add_object(wb, "selections");
394
395
+ CLEAN_BUFFER *sources_list = buffer_create(0, NULL);
396
+
397
json_object_object_foreach(selections, key, val) {
398
+ if(strcmp(key, "query") == 0) continue;
399
+
400
if (json_object_get_type(val) != json_type_array) {
401
buffer_sprintf(error, "selection '%s' is not an array", key);
402
// nd_log(NDLS_COLLECTORS, NDLP_ERR, "POST payload: selection '%s' is not an array", key);
@@ -449,6 +405,8 @@ static inline bool lqs_request_parse_json_payload(json_object *jobj, const char
405
406
buffer_json_member_add_array(wb, key);
407
408
+ bool is_source = strcmp(key, LQS_PARAMETER_SOURCE) == 0;
409
+
410
size_t values_len = json_object_array_length(val);
411
for (size_t i = 0; i < values_len; i++) {
412
json_object *value_obj = json_object_array_get_idx(val, i);
@@ -461,17 +419,40 @@ static inline bool lqs_request_parse_json_payload(json_object *jobj, const char
419
420
const char *value = json_object_get_string(value_obj);
421
464
- // Call facets_register_facet_id_filter for each value
465
- facets_register_facet_filter(
466
- facets, key, value, FACET_KEY_OPTION_FACET | FACET_KEY_OPTION_FTS | FACET_KEY_OPTION_REORDER);
422
+ if(is_source) {
423
+ // processing sources
424
+ LQS_SOURCE_TYPE t = LQS_FUNCTION_GET_INTERNAL_SOURCE_TYPE(value);
425
+ if(t != LQS_SOURCE_TYPE_NONE) {
426
+ rq->source_type |= t;
427
+ value = NULL;
428
+ }
429
+ else {
430
+ // else, match the source, whatever it is
431
+ if(buffer_strlen(sources_list))
432
+ buffer_putc(sources_list, '|');
433
+
434
+ buffer_strcat(sources_list, value);
435
+ }
436
+ }
437
+ else {
438
+ // Call facets_register_facet_id_filter for each value
439
+ facets_register_facet_filter(
440
+ facets, key, value, FACET_KEY_OPTION_FACET | FACET_KEY_OPTION_FTS | FACET_KEY_OPTION_REORDER);
441
+
442
+ rq->filters++;
443
+ }
444
445
buffer_json_add_array_item_string(wb, value);
469
- rq->filters++;
446
}
447
448
buffer_json_array_close(wb); // key
449
}
450
451
+ if(buffer_strlen(sources_list)) {
452
+ simple_pattern_free(rq->sources);
453
+ rq->sources = simple_pattern_create(buffer_tostring(sources_list), "|", SIMPLE_PATTERN_EXACT, false);
454
+ }
455
+
456
buffer_json_object_close(wb); // selections
457
}
458
@@ -686,8 +667,8 @@ static inline void lqs_info_response(BUFFER *wb, FACETS *facets) {
667
{
668
buffer_json_add_array_item_object(wb);
669
{
689
- buffer_json_member_add_string(wb, "id", "source");
690
- buffer_json_member_add_string(wb, "name", "source");
670
+ buffer_json_member_add_string(wb, "id", LQS_PARAMETER_SOURCE);
671
+ buffer_json_member_add_string(wb, "name", LQS_PARAMETER_SOURCE_NAME);
672
buffer_json_member_add_string(wb, "help", "Select the logs source to query");
673
buffer_json_member_add_string(wb, "type", "multiselect");
674
buffer_json_member_add_array(wb, "options");