@cryptotaxi247 / netdata-1 / commits / f57d5e799

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");