From 4ed5dbe97dd4a473dec9a7ca98f857d5a4e26cd5 Mon Sep 17 00:00:00 2001 From: Alec Holmes Date: Thu, 8 May 2025 17:48:41 -0700 Subject: [PATCH 1/6] engine: expose internal logging call counts as internal metrics Internal logger calls increment a new v2 metric exposed by the HTTP server Prometheus scrape endpoint. There is one time series per log message type. Signed-off-by: Alec Holmes --- include/fluent-bit/flb_config.h | 1 + include/fluent-bit/flb_log.h | 12 ++ src/flb_config.c | 13 ++ src/flb_log.c | 113 ++++++++++++++-- src/flb_metrics_exporter.c | 9 ++ src/flb_sds.c | 6 +- tests/runtime/CMakeLists.txt | 1 + tests/runtime/core_internal_logger.c | 184 +++++++++++++++++++++++++++ 8 files changed, 328 insertions(+), 11 deletions(-) create mode 100644 tests/runtime/core_internal_logger.c diff --git a/include/fluent-bit/flb_config.h b/include/fluent-bit/flb_config.h index c2b7efdbc0a..f69a0ebfcd5 100644 --- a/include/fluent-bit/flb_config.h +++ b/include/fluent-bit/flb_config.h @@ -164,6 +164,7 @@ struct flb_config { /* Logging */ char *log_file; struct flb_log *log; + struct flb_log_metrics *log_metrics_ctx; /* Global metrics for logging calls */ /* Parser Conf */ char *parsers_file; diff --git a/include/fluent-bit/flb_log.h b/include/fluent-bit/flb_log.h index 32647824e9e..3cb3f06e88e 100644 --- a/include/fluent-bit/flb_log.h +++ b/include/fluent-bit/flb_log.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -92,6 +94,14 @@ struct flb_log_cache { struct mk_list entries; /* list for entries */ }; +/* Global metrics for logging calls. */ +struct flb_log_metrics { + struct cmt *cmt; + + /* cmetrics */ + struct cmt_counter *logs_total_counter; /* total number of logs (by message type) */ +}; + /* * This function is used by plugins interface to check if an incoming log message * should be logged or not based in the log levels defined. @@ -232,6 +242,8 @@ static inline int flb_log_suppress_check(int log_suppress_interval, const char * int flb_log_worker_init(struct flb_worker *worker); int flb_log_worker_destroy(struct flb_worker *worker); int flb_errno_print(int errnum, const char *file, int line); +struct flb_log_metrics *flb_log_metrics_create(); +void flb_log_metrics_destroy(struct flb_log_metrics *ctx); #ifdef WIN32 int flb_wsa_get_last_error_print(int errnum, const char *file, int line); #endif diff --git a/src/flb_config.c b/src/flb_config.c index 1c61a4296c2..382e80dc504 100644 --- a/src/flb_config.c +++ b/src/flb_config.c @@ -400,6 +400,14 @@ struct flb_config *flb_config_init() flb_regex_init(); #endif + /* Create internal logger metrics */ + config->log_metrics_ctx = flb_log_metrics_create(); + if (!config->log_metrics_ctx) { + flb_error("[engine] could not create log metrics"); + flb_config_exit(config); + return NULL; + } + return config; } @@ -570,6 +578,11 @@ void flb_config_exit(struct flb_config *config) flb_config_task_map_resize(config, 0); flb_routes_empty_mask_destroy(config); + /* Destroy internal logger metrics */ + if (config->log_metrics_ctx) { + flb_log_metrics_destroy(config->log_metrics_ctx); + } + flb_free(config); } diff --git a/src/flb_log.c b/src/flb_log.c index 851793216d4..fb9e8b259bb 100644 --- a/src/flb_log.c +++ b/src/flb_log.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #ifdef WIN32 #include @@ -564,6 +566,28 @@ struct flb_log *flb_log_create(struct flb_config *config, int type, return log; } +static inline char *flb_log_message_type_str(int type) +{ + switch (type) { + case FLB_LOG_HELP: + return "help"; + case FLB_LOG_INFO: + return "info"; + case FLB_LOG_WARN: + return "warn"; + case FLB_LOG_ERROR: + return "error"; + case FLB_LOG_DEBUG: + return "debug"; + case FLB_LOG_IDEBUG: + return "debug"; + case FLB_LOG_TRACE: + return "trace"; + default: + return NULL; + } +} + int flb_log_construct(struct log_message *msg, int *ret_len, int type, const char *file, int line, const char *fmt, va_list *args) { @@ -573,7 +597,7 @@ int flb_log_construct(struct log_message *msg, int *ret_len, int total; time_t now; const char *header_color = NULL; - const char *header_title = NULL; + const char *header_title = flb_log_message_type_str(type); const char *bold_color = ANSI_BOLD; const char *reset_color = ANSI_RESET; struct tm result; @@ -581,31 +605,24 @@ int flb_log_construct(struct log_message *msg, int *ret_len, switch (type) { case FLB_LOG_HELP: - header_title = "help"; header_color = ANSI_CYAN; break; case FLB_LOG_INFO: - header_title = "info"; header_color = ANSI_GREEN; break; case FLB_LOG_WARN: - header_title = "warn"; header_color = ANSI_YELLOW; break; case FLB_LOG_ERROR: - header_title = "error"; header_color = ANSI_RED; break; case FLB_LOG_DEBUG: - header_title = "debug"; header_color = ANSI_YELLOW; break; case FLB_LOG_IDEBUG: - header_title = "debug"; header_color = ANSI_CYAN; break; case FLB_LOG_TRACE: - header_title = "trace"; header_color = ANSI_BLUE; break; } @@ -704,8 +721,11 @@ void flb_log_print(int type, const char *file, int line, const char *fmt, ...) int ret; struct log_message msg = {0}; va_list args; + char *msg_type_str = flb_log_message_type_str(type); + uint64_t ts = cfl_time_now(); struct flb_worker *w; + struct flb_config *config; va_start(args, fmt); ret = flb_log_construct(&msg, &len, type, file, line, fmt, &args); @@ -717,6 +737,11 @@ void flb_log_print(int type, const char *file, int line, const char *fmt, ...) w = flb_worker_get(); if (w) { + config = w->config; + if (config && config->log_metrics_ctx) { + cmt_counter_inc(config->log_metrics_ctx->logs_total_counter, ts, 1, (char *[]) {msg_type_str}); // Ignoring inc error + } + n = flb_pipe_write_all(w->log[1], &msg, sizeof(msg)); if (n == -1) { @@ -780,3 +805,75 @@ int flb_log_destroy(struct flb_log *log, struct flb_config *config) return 0; } + +/* + * Create and register cmetrics for the runtime logger. + * The caller must free the returned struct using flb_log_metrics_destroy. + */ +struct flb_log_metrics *flb_log_metrics_create() +{ + struct flb_log_metrics *lm; + int i; + char *message_type_str; + uint64_t ts; + + lm = flb_calloc(1, sizeof(struct flb_log_metrics)); + if (!lm) { + flb_errno(); + goto error; + } + + lm->cmt = cmt_create(); + if (!lm->cmt) { + goto error; + } + + lm->logs_total_counter = cmt_counter_create(lm->cmt, + "fluentbit", "logger", "logs_total", + "Total number of logs", + 1, (char *[]) {"message_type"}); + if (!lm->logs_total_counter) { + goto error; + } + + /* + * Initialize counters for all log message types to 0. + * This assumes types are contiguous starting at 1 (FLB_LOG_ERROR). + */ + i = 1; + ts = cfl_time_now(); + for (i = 1; ; i++) { + message_type_str = flb_log_message_type_str(i); + if (!message_type_str) { + break; + } + + if (cmt_counter_set(lm->logs_total_counter, ts, 0, 1, (char *[]) {message_type_str}) == -1) { + goto error; + } + } + + return lm; + +error: + if (lm && lm->logs_total_counter) { + cmt_counter_destroy(lm->logs_total_counter); + } + + if (lm && lm->cmt) { + cmt_destroy(lm->cmt); + } + + if (lm) { + flb_free(lm); + } + + return NULL; +} + +void flb_log_metrics_destroy(struct flb_log_metrics *lm) +{ + cmt_counter_destroy(lm->logs_total_counter); + cmt_destroy(lm->cmt); + flb_free(lm); +} diff --git a/src/flb_metrics_exporter.c b/src/flb_metrics_exporter.c index 31a6dcf902b..89e9f61ccdb 100644 --- a/src/flb_metrics_exporter.c +++ b/src/flb_metrics_exporter.c @@ -299,6 +299,15 @@ struct cmt *flb_me_get_cmetrics(struct flb_config *ctx) } } + if (ctx->log_metrics_ctx) { + ret = cmt_cat(cmt, ctx->log_metrics_ctx->cmt); + if (ret == -1) { + flb_error("[metrics exporter] could not append global log_metrics_ctx"); + cmt_destroy(cmt); + return NULL; + } + } + /* Pipeline metrics: input, filters, outputs */ mk_list_foreach(head, &ctx->inputs) { i = mk_list_entry(head, struct flb_input_instance, _head); diff --git a/src/flb_sds.c b/src/flb_sds.c index 4ac36ad22e8..44e830cd2c8 100644 --- a/src/flb_sds.c +++ b/src/flb_sds.c @@ -33,7 +33,7 @@ #include #include -static flb_sds_t sds_alloc(size_t size) +static flb_sds_t flb_sds_alloc_internal(size_t size) { void *buf; flb_sds_t s; @@ -60,7 +60,7 @@ flb_sds_t flb_sds_create_len(const char *str, int len) flb_sds_t s; struct flb_sds *head; - s = sds_alloc(len); + s = flb_sds_alloc_internal(len); if (!s) { return NULL; } @@ -91,7 +91,7 @@ flb_sds_t flb_sds_create(const char *str) flb_sds_t flb_sds_create_size(size_t size) { - return sds_alloc(size); + return flb_sds_alloc_internal(size); } /* Increase SDS buffer size 'len' bytes */ diff --git a/tests/runtime/CMakeLists.txt b/tests/runtime/CMakeLists.txt index 34db83e0a17..37617bcb6ea 100644 --- a/tests/runtime/CMakeLists.txt +++ b/tests/runtime/CMakeLists.txt @@ -25,6 +25,7 @@ endmacro() # Core FLB_RT_CORE_TEST(FLB_COROUTINE_TIMEOUT "core-timeout.c") +FLB_RT_CORE_TEST(FLB_INTERNAL_LOGGER "core_internal_logger.c") FLB_RT_TEST(FLB_CHUNK_TRACE "core_chunk_trace.c") diff --git a/tests/runtime/core_internal_logger.c b/tests/runtime/core_internal_logger.c new file mode 100644 index 00000000000..48992e239c3 --- /dev/null +++ b/tests/runtime/core_internal_logger.c @@ -0,0 +1,184 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include +#include +#include +#include +#include + +#include "flb_tests_runtime.h" + +struct http_client_ctx { + struct flb_upstream *u; + struct flb_connection *u_conn; + struct flb_config *config; + struct mk_event_loop *evl; +}; + +struct http_client_ctx *http_client_ctx_create() +{ + struct http_client_ctx *ret_ctx = NULL; + struct mk_event_loop *evl = NULL; + + ret_ctx = flb_calloc(1, sizeof(struct http_client_ctx)); + if (!TEST_CHECK(ret_ctx != NULL)) { + flb_errno(); + TEST_MSG("flb_calloc(http_client_ctx) failed"); + return NULL; + } + + evl = mk_event_loop_create(16); + if (!TEST_CHECK(evl != NULL)) { + TEST_MSG("mk_event_loop failed"); + flb_free(ret_ctx); + return NULL; + } + ret_ctx->evl = evl; + flb_engine_evl_init(); + flb_engine_evl_set(evl); + + ret_ctx->config = flb_config_init(); + if (!TEST_CHECK(ret_ctx->config != NULL)) { + TEST_MSG("flb_config_init failed"); + mk_event_loop_destroy(evl); + flb_free(ret_ctx); + return NULL; + } + + ret_ctx->u = flb_upstream_create(ret_ctx->config, "127.0.0.1", 2020, 0, NULL); + if (!TEST_CHECK(ret_ctx->u != NULL)) { + TEST_MSG("flb_upstream_create failed"); + flb_config_exit(ret_ctx->config); + mk_event_loop_destroy(evl); + flb_free(ret_ctx); + return NULL; + } + + ret_ctx->u_conn = flb_upstream_conn_get(ret_ctx->u); + TEST_CHECK(ret_ctx->u_conn != NULL); + + ret_ctx->u_conn->upstream = ret_ctx->u; + + return ret_ctx; +} + +void http_client_ctx_destroy(struct http_client_ctx *http_ctx) +{ + TEST_CHECK(flb_upstream_conn_release(http_ctx->u_conn) == 0); + flb_upstream_destroy(http_ctx->u); + mk_event_loop_destroy(http_ctx->evl); + flb_config_exit(http_ctx->config); + flb_free(http_ctx); +} + +/* Check for expected Prometheus metrics. If the prom scrape endpoints returns a non-200 + * and fail_test is FLB_FALSE, this returns without failing the test. + * This returns 0 if all the assertions were checked and no retry is necessary. + */ +int assert_internal_log_metrics(struct http_client_ctx *http_ctx, int fail_test) +{ + struct flb_http_client *http_client; + int ret; + size_t b_sent; + struct flb_regex *regex; + + http_client = flb_http_client(http_ctx->u_conn, + FLB_HTTP_GET, + "/api/v2/metrics/prometheus", + "", /* body */ + 0, /* len(body) */ + "127.0.0.1", + 2020, + NULL, + 0); + TEST_ASSERT(http_client != NULL); + + TEST_ASSERT(flb_http_do(http_client, &b_sent) == 0); + + if (http_client->resp.status != 200 && !fail_test) { + ret = -1; + goto cleanup; + } + + TEST_MSG(http_client->resp.payload); + if (!TEST_CHECK(http_client->resp.status == 200)) { + TEST_MSG("http response code error. expect: 200, got: %d\n", + http_client->resp.status); + } + + /* There be no errors logged */ + if (!TEST_CHECK(strstr(http_client->resp.payload, + "fluentbit_logger_logs_total{message_type=\"error\"} 0") != NULL)) { + TEST_MSG("response payload: %s", http_client->resp.payload); + } + + /* The process startup should have logged at least 1 info log */ + regex = flb_regex_create("fluentbit_logger_logs_total\\{message_type=\"info\"\\} [1-9]+[0-9]*"); + TEST_CHECK(regex != NULL); + if (!TEST_CHECK(flb_regex_match( + regex, http_client->resp.payload, http_client->resp.payload_size))) { + TEST_MSG("response payload: %s\n", http_client->resp.payload); + } + flb_regex_destroy(regex); + + ret = 0; + +cleanup: + flb_http_client_destroy(http_client); + + return ret; +} + +/* + * Test that internal logs (i.e. those created by flb_info, flb_error, etc) + * tick internal v2 metrics. + */ +static void test_internal_log_metrics() +{ + flb_ctx_t *ctx; + int ret; + struct http_client_ctx *http_ctx; + struct flb_http_client *http_client; + size_t b_sent; + struct flb_regex *regex; + int i; + int attempt_count = 30; + + ctx = flb_create(); + TEST_ASSERT(ctx != NULL); + + TEST_ASSERT(flb_service_set(ctx, + "HTTP_Server", + "On", + "HTTP_Listen", + "127.0.0.1", + "HTTP_Port", + "2020", + NULL) == 0); + + ret = flb_start(ctx); + TEST_ASSERT(ret == 0); + + http_ctx = http_client_ctx_create(); + TEST_ASSERT(http_ctx != NULL); + + /* If the assertion fails, retry in a sleep loop since the fluent-bit's HTTP server + * may not be ready yet */ + for (i = 1; i <= attempt_count; i++) { + if (assert_internal_log_metrics(http_ctx, i == attempt_count ? FLB_TRUE : FLB_FALSE)) { + break; + } + flb_time_msleep(100); + } + + http_client_ctx_destroy(http_ctx); + TEST_CHECK(flb_stop(ctx) == 0); + flb_destroy(ctx); +} + +/* Test list */ +TEST_LIST = { + {"internal_log_metrics", test_internal_log_metrics}, + {NULL, NULL}, +}; From 12bc6e869425e0783c7734494915ea8d82c22271 Mon Sep 17 00:00:00 2001 From: Alec Holmes Date: Mon, 19 May 2025 10:11:50 -0700 Subject: [PATCH 2/6] Feedback (temporary -- will squash into above) Signed-off-by: Alec Holmes --- include/fluent-bit/flb_config.h | 1 - include/fluent-bit/flb_log.h | 3 +- src/flb_config.c | 13 -- src/flb_log.c | 212 ++++++++++++++------------- src/flb_metrics_exporter.c | 4 +- tests/runtime/core_internal_logger.c | 21 ++- 6 files changed, 126 insertions(+), 128 deletions(-) diff --git a/include/fluent-bit/flb_config.h b/include/fluent-bit/flb_config.h index f69a0ebfcd5..c2b7efdbc0a 100644 --- a/include/fluent-bit/flb_config.h +++ b/include/fluent-bit/flb_config.h @@ -164,7 +164,6 @@ struct flb_config { /* Logging */ char *log_file; struct flb_log *log; - struct flb_log_metrics *log_metrics_ctx; /* Global metrics for logging calls */ /* Parser Conf */ char *parsers_file; diff --git a/include/fluent-bit/flb_log.h b/include/fluent-bit/flb_log.h index 3cb3f06e88e..75de5060984 100644 --- a/include/fluent-bit/flb_log.h +++ b/include/fluent-bit/flb_log.h @@ -74,6 +74,7 @@ struct flb_log { pthread_t tid; /* thread ID */ struct flb_worker *worker; /* non-real worker reference */ struct mk_event_loop *evl; + struct flb_log_metrics *metrics; /* Initialization variables */ int pth_init; @@ -242,8 +243,6 @@ static inline int flb_log_suppress_check(int log_suppress_interval, const char * int flb_log_worker_init(struct flb_worker *worker); int flb_log_worker_destroy(struct flb_worker *worker); int flb_errno_print(int errnum, const char *file, int line); -struct flb_log_metrics *flb_log_metrics_create(); -void flb_log_metrics_destroy(struct flb_log_metrics *ctx); #ifdef WIN32 int flb_wsa_get_last_error_print(int errnum, const char *file, int line); #endif diff --git a/src/flb_config.c b/src/flb_config.c index 382e80dc504..1c61a4296c2 100644 --- a/src/flb_config.c +++ b/src/flb_config.c @@ -400,14 +400,6 @@ struct flb_config *flb_config_init() flb_regex_init(); #endif - /* Create internal logger metrics */ - config->log_metrics_ctx = flb_log_metrics_create(); - if (!config->log_metrics_ctx) { - flb_error("[engine] could not create log metrics"); - flb_config_exit(config); - return NULL; - } - return config; } @@ -578,11 +570,6 @@ void flb_config_exit(struct flb_config *config) flb_config_task_map_resize(config, 0); flb_routes_empty_mask_destroy(config); - /* Destroy internal logger metrics */ - if (config->log_metrics_ctx) { - flb_log_metrics_destroy(config->log_metrics_ctx); - } - flb_free(config); } diff --git a/src/flb_log.c b/src/flb_log.c index fb9e8b259bb..137aafd4658 100644 --- a/src/flb_log.c +++ b/src/flb_log.c @@ -440,6 +440,28 @@ int flb_log_get_level_str(char *str) return -1; } +static inline const char *flb_log_message_type_str(int type) +{ + switch (type) { + case FLB_LOG_HELP: + return "help"; + case FLB_LOG_INFO: + return "info"; + case FLB_LOG_WARN: + return "warn"; + case FLB_LOG_ERROR: + return "error"; + case FLB_LOG_DEBUG: + return "debug"; + case FLB_LOG_IDEBUG: + return "debug"; + case FLB_LOG_TRACE: + return "trace"; + default: + return NULL; + } +} + int flb_log_set_file(struct flb_config *config, char *out) { struct flb_log *log = config->log; @@ -456,6 +478,78 @@ int flb_log_set_file(struct flb_config *config, char *out) return 0; } + +/* + * Create and register cmetrics for the runtime logger. + * The caller must free the returned struct using flb_log_metrics_destroy. + */ +struct flb_log_metrics *flb_log_metrics_create() +{ + struct flb_log_metrics *metrics; + int i; + const char *message_type_str; + uint64_t ts; + int ret; + + metrics = flb_calloc(1, sizeof(struct flb_log_metrics)); + if (metrics == NULL) { + flb_errno(); + return NULL; + } + + metrics->cmt = cmt_create(); + if (!metrics->cmt) { + flb_free(metrics); + return NULL; + } + + metrics->logs_total_counter = cmt_counter_create(metrics->cmt, + "fluentbit", + "logger", + "logs_total", + "Total number of logs", + 1, (char *[]) {"message_type"}); + if (metrics->logs_total_counter == NULL) { + cmt_destroy(metrics->cmt); + flb_free(metrics); + return NULL; + } + + /* + * Initialize counters for all log message types to 0. + * This assumes types are contiguous starting at 1 (FLB_LOG_ERROR). + */ + ts = cfl_time_now(); + for (i = 1; ; i++) { + message_type_str = flb_log_message_type_str(i); + if (!message_type_str) { + break; + } + + ret = cmt_counter_set(metrics->logs_total_counter, + ts, + 0, + 1, (char *[]) {message_type_str}); + if (ret == -1) { + cmt_counter_destroy(metrics->logs_total_counter); + cmt_destroy(metrics->cmt); + flb_free(metrics); + return NULL; + } + } + + return metrics; +} + +/* Frees the metrics instance and its associated resources. */ +void flb_log_metrics_destroy(struct flb_log_metrics *metrics) +{ + cmt_counter_destroy(metrics->logs_total_counter); + cmt_destroy(metrics->cmt); + flb_free(metrics); +} + + struct flb_log *flb_log_create(struct flb_config *config, int type, int level, char *out) { @@ -509,6 +603,16 @@ struct flb_log *flb_log_create(struct flb_config *config, int type, return NULL; } + /* Create metrics */ + log->metrics = flb_log_metrics_create(); + if (log->metrics == NULL) { + fprintf(stderr, "[log] could not create log metrics\n"); + mk_event_loop_destroy(log->evl); + flb_free(log); + config->log = NULL; + return NULL; + } + /* * Since the main process/thread might want to write log messages, * it will need a 'worker-like' context, here we create a fake worker @@ -566,28 +670,6 @@ struct flb_log *flb_log_create(struct flb_config *config, int type, return log; } -static inline char *flb_log_message_type_str(int type) -{ - switch (type) { - case FLB_LOG_HELP: - return "help"; - case FLB_LOG_INFO: - return "info"; - case FLB_LOG_WARN: - return "warn"; - case FLB_LOG_ERROR: - return "error"; - case FLB_LOG_DEBUG: - return "debug"; - case FLB_LOG_IDEBUG: - return "debug"; - case FLB_LOG_TRACE: - return "trace"; - default: - return NULL; - } -} - int flb_log_construct(struct log_message *msg, int *ret_len, int type, const char *file, int line, const char *fmt, va_list *args) { @@ -597,7 +679,7 @@ int flb_log_construct(struct log_message *msg, int *ret_len, int total; time_t now; const char *header_color = NULL; - const char *header_title = flb_log_message_type_str(type); + const char *header_title; const char *bold_color = ANSI_BOLD; const char *reset_color = ANSI_RESET; struct tm result; @@ -647,6 +729,7 @@ int flb_log_construct(struct log_message *msg, int *ret_len, return -1; } + header_title = flb_log_message_type_str(type); len = snprintf(msg->msg, sizeof(msg->msg) - 1, "%s[%s%i/%02i/%02i %02i:%02i:%02i%s]%s [%s%5s%s] ", /* time */ /* type */ @@ -721,8 +804,8 @@ void flb_log_print(int type, const char *file, int line, const char *fmt, ...) int ret; struct log_message msg = {0}; va_list args; - char *msg_type_str = flb_log_message_type_str(type); - uint64_t ts = cfl_time_now(); + const char *msg_type_str; + uint64_t ts; struct flb_worker *w; struct flb_config *config; @@ -738,8 +821,10 @@ void flb_log_print(int type, const char *file, int line, const char *fmt, ...) w = flb_worker_get(); if (w) { config = w->config; - if (config && config->log_metrics_ctx) { - cmt_counter_inc(config->log_metrics_ctx->logs_total_counter, ts, 1, (char *[]) {msg_type_str}); // Ignoring inc error + if (config != NULL && config->log != NULL) { + msg_type_str = flb_log_message_type_str(type); + ts = cfl_time_now(); + cmt_counter_inc(config->log->metrics->logs_total_counter, ts, 1, (char *[]) {msg_type_str}); // Ignoring inc error } n = flb_pipe_write_all(w->log[1], &msg, sizeof(msg)); @@ -801,79 +886,8 @@ int flb_log_destroy(struct flb_log *log, struct flb_config *config) } flb_log_worker_destroy(log->worker); flb_free(log->worker); + flb_log_metrics_destroy(log->metrics); flb_free(log); return 0; } - -/* - * Create and register cmetrics for the runtime logger. - * The caller must free the returned struct using flb_log_metrics_destroy. - */ -struct flb_log_metrics *flb_log_metrics_create() -{ - struct flb_log_metrics *lm; - int i; - char *message_type_str; - uint64_t ts; - - lm = flb_calloc(1, sizeof(struct flb_log_metrics)); - if (!lm) { - flb_errno(); - goto error; - } - - lm->cmt = cmt_create(); - if (!lm->cmt) { - goto error; - } - - lm->logs_total_counter = cmt_counter_create(lm->cmt, - "fluentbit", "logger", "logs_total", - "Total number of logs", - 1, (char *[]) {"message_type"}); - if (!lm->logs_total_counter) { - goto error; - } - - /* - * Initialize counters for all log message types to 0. - * This assumes types are contiguous starting at 1 (FLB_LOG_ERROR). - */ - i = 1; - ts = cfl_time_now(); - for (i = 1; ; i++) { - message_type_str = flb_log_message_type_str(i); - if (!message_type_str) { - break; - } - - if (cmt_counter_set(lm->logs_total_counter, ts, 0, 1, (char *[]) {message_type_str}) == -1) { - goto error; - } - } - - return lm; - -error: - if (lm && lm->logs_total_counter) { - cmt_counter_destroy(lm->logs_total_counter); - } - - if (lm && lm->cmt) { - cmt_destroy(lm->cmt); - } - - if (lm) { - flb_free(lm); - } - - return NULL; -} - -void flb_log_metrics_destroy(struct flb_log_metrics *lm) -{ - cmt_counter_destroy(lm->logs_total_counter); - cmt_destroy(lm->cmt); - flb_free(lm); -} diff --git a/src/flb_metrics_exporter.c b/src/flb_metrics_exporter.c index 89e9f61ccdb..873b1892483 100644 --- a/src/flb_metrics_exporter.c +++ b/src/flb_metrics_exporter.c @@ -299,8 +299,8 @@ struct cmt *flb_me_get_cmetrics(struct flb_config *ctx) } } - if (ctx->log_metrics_ctx) { - ret = cmt_cat(cmt, ctx->log_metrics_ctx->cmt); + if (ctx->log != NULL) { + ret = cmt_cat(cmt, ctx->log->metrics->cmt); if (ret == -1) { flb_error("[metrics exporter] could not append global log_metrics_ctx"); cmt_destroy(cmt); diff --git a/tests/runtime/core_internal_logger.c b/tests/runtime/core_internal_logger.c index 48992e239c3..b960b1212b4 100644 --- a/tests/runtime/core_internal_logger.c +++ b/tests/runtime/core_internal_logger.c @@ -79,7 +79,6 @@ void http_client_ctx_destroy(struct http_client_ctx *http_ctx) int assert_internal_log_metrics(struct http_client_ctx *http_ctx, int fail_test) { struct flb_http_client *http_client; - int ret; size_t b_sent; struct flb_regex *regex; @@ -97,8 +96,8 @@ int assert_internal_log_metrics(struct http_client_ctx *http_ctx, int fail_test) TEST_ASSERT(flb_http_do(http_client, &b_sent) == 0); if (http_client->resp.status != 200 && !fail_test) { - ret = -1; - goto cleanup; + flb_http_client_destroy(http_client); + return -1; } TEST_MSG(http_client->resp.payload); @@ -108,26 +107,26 @@ int assert_internal_log_metrics(struct http_client_ctx *http_ctx, int fail_test) } /* There be no errors logged */ - if (!TEST_CHECK(strstr(http_client->resp.payload, - "fluentbit_logger_logs_total{message_type=\"error\"} 0") != NULL)) { + if (!TEST_CHECK( + strstr(http_client->resp.payload, + "fluentbit_logger_logs_total{message_type=\"error\"} 0") + != NULL)) { TEST_MSG("response payload: %s", http_client->resp.payload); } /* The process startup should have logged at least 1 info log */ - regex = flb_regex_create("fluentbit_logger_logs_total\\{message_type=\"info\"\\} [1-9]+[0-9]*"); + regex = flb_regex_create( + "fluentbit_logger_logs_total\\{message_type=\"info\"\\} [1-9]+[0-9]*"); TEST_CHECK(regex != NULL); if (!TEST_CHECK(flb_regex_match( regex, http_client->resp.payload, http_client->resp.payload_size))) { TEST_MSG("response payload: %s\n", http_client->resp.payload); } - flb_regex_destroy(regex); - ret = 0; - -cleanup: + flb_regex_destroy(regex); flb_http_client_destroy(http_client); - return ret; + return 0; } /* From 91c06114ef885dd3f17cea94373a4a802cd37920 Mon Sep 17 00:00:00 2001 From: Alec Holmes Date: Tue, 20 May 2025 10:28:59 -0700 Subject: [PATCH 3/6] Feedback (temporary -- will squash into above) Signed-off-by: Alec Holmes --- src/flb_log.c | 9 ++++++++- tests/runtime/core_internal_logger.c | 10 +++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/flb_log.c b/src/flb_log.c index 137aafd4658..5fa1bf73c4f 100644 --- a/src/flb_log.c +++ b/src/flb_log.c @@ -824,7 +824,14 @@ void flb_log_print(int type, const char *file, int line, const char *fmt, ...) if (config != NULL && config->log != NULL) { msg_type_str = flb_log_message_type_str(type); ts = cfl_time_now(); - cmt_counter_inc(config->log->metrics->logs_total_counter, ts, 1, (char *[]) {msg_type_str}); // Ignoring inc error + ret = cmt_counter_inc(config->log->metrics->logs_total_counter, + ts, + 1, (char *[]) {msg_type_str}); + if (ret == -1) { + fprintf(stderr, + "[log] failed to increment log total counter for message type '%s' (error=%d)\n", + msg_type_str != NULL ? msg_type_str : "unknown", ret); + } } n = flb_pipe_write_all(w->log[1], &msg, sizeof(msg)); diff --git a/tests/runtime/core_internal_logger.c b/tests/runtime/core_internal_logger.c index b960b1212b4..b01303a1bad 100644 --- a/tests/runtime/core_internal_logger.c +++ b/tests/runtime/core_internal_logger.c @@ -117,7 +117,11 @@ int assert_internal_log_metrics(struct http_client_ctx *http_ctx, int fail_test) /* The process startup should have logged at least 1 info log */ regex = flb_regex_create( "fluentbit_logger_logs_total\\{message_type=\"info\"\\} [1-9]+[0-9]*"); - TEST_CHECK(regex != NULL); + if (!TEST_CHECK(regex != NULL)) { + TEST_MSG("Failed to create regex for info log count check"); + flb_http_client_destroy(http_client); + return -1; + } if (!TEST_CHECK(flb_regex_match( regex, http_client->resp.payload, http_client->resp.payload_size))) { TEST_MSG("response payload: %s\n", http_client->resp.payload); @@ -164,8 +168,8 @@ static void test_internal_log_metrics() /* If the assertion fails, retry in a sleep loop since the fluent-bit's HTTP server * may not be ready yet */ - for (i = 1; i <= attempt_count; i++) { - if (assert_internal_log_metrics(http_ctx, i == attempt_count ? FLB_TRUE : FLB_FALSE)) { + for (i = 0; i < attempt_count; i++) { + if (assert_internal_log_metrics(http_ctx, i == (attempt_count - 1)) ) { break; } flb_time_msleep(100); From d42cb3e9597e727e250fb2e9dca6d76a7899f1dc Mon Sep 17 00:00:00 2001 From: Alec Holmes Date: Wed, 21 May 2025 08:34:16 -0700 Subject: [PATCH 4/6] Feedback (temporary -- will squash into above) Signed-off-by: Alec Holmes --- src/flb_log.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/flb_log.c b/src/flb_log.c index 5fa1bf73c4f..c9c3c3179d4 100644 --- a/src/flb_log.c +++ b/src/flb_log.c @@ -823,14 +823,19 @@ void flb_log_print(int type, const char *file, int line, const char *fmt, ...) config = w->config; if (config != NULL && config->log != NULL) { msg_type_str = flb_log_message_type_str(type); + if (msg_type_str == NULL) { + msg_type_str = "unknown"; + } + ts = cfl_time_now(); ret = cmt_counter_inc(config->log->metrics->logs_total_counter, ts, 1, (char *[]) {msg_type_str}); if (ret == -1) { + // Not using flb_log_debug to avoid recursing into this same function. fprintf(stderr, "[log] failed to increment log total counter for message type '%s' (error=%d)\n", - msg_type_str != NULL ? msg_type_str : "unknown", ret); + msg_type_str, ret); } } From 22f8ce891253f5cb89176a2ef60d5d4de4586096 Mon Sep 17 00:00:00 2001 From: Alec Holmes Date: Fri, 23 May 2025 09:28:32 -0700 Subject: [PATCH 5/6] Feedback (temporary -- will squash into above) Signed-off-by: Alec Holmes --- src/flb_log.c | 43 +++++++++++++++++--------------------- src/flb_metrics_exporter.c | 4 ++-- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/flb_log.c b/src/flb_log.c index c9c3c3179d4..d692f8cc492 100644 --- a/src/flb_log.c +++ b/src/flb_log.c @@ -478,6 +478,16 @@ int flb_log_set_file(struct flb_config *config, char *out) return 0; } +/* Frees the metrics instance and its associated resources. */ +void flb_log_metrics_destroy(struct flb_log_metrics *metrics) +{ + if (metrics != NULL && metrics->cmt != NULL) { + cmt_destroy(metrics->cmt); + } + if (metrics != NULL) { + flb_free(metrics); + } +} /* * Create and register cmetrics for the runtime logger. @@ -486,7 +496,7 @@ int flb_log_set_file(struct flb_config *config, char *out) struct flb_log_metrics *flb_log_metrics_create() { struct flb_log_metrics *metrics; - int i; + int log_message_type; const char *message_type_str; uint64_t ts; int ret; @@ -498,8 +508,8 @@ struct flb_log_metrics *flb_log_metrics_create() } metrics->cmt = cmt_create(); - if (!metrics->cmt) { - flb_free(metrics); + if (metrics->cmt == NULL) { + flb_log_metrics_destroy(metrics); return NULL; } @@ -510,18 +520,14 @@ struct flb_log_metrics *flb_log_metrics_create() "Total number of logs", 1, (char *[]) {"message_type"}); if (metrics->logs_total_counter == NULL) { - cmt_destroy(metrics->cmt); - flb_free(metrics); + flb_log_metrics_destroy(metrics); return NULL; } - /* - * Initialize counters for all log message types to 0. - * This assumes types are contiguous starting at 1 (FLB_LOG_ERROR). - */ + /* Initialize counters for log message types to 0. */ ts = cfl_time_now(); - for (i = 1; ; i++) { - message_type_str = flb_log_message_type_str(i); + for (log_message_type = FLB_LOG_ERROR; log_message_type <= FLB_LOG_TRACE; log_message_type++) { + message_type_str = flb_log_message_type_str(log_message_type); if (!message_type_str) { break; } @@ -531,9 +537,7 @@ struct flb_log_metrics *flb_log_metrics_create() 0, 1, (char *[]) {message_type_str}); if (ret == -1) { - cmt_counter_destroy(metrics->logs_total_counter); - cmt_destroy(metrics->cmt); - flb_free(metrics); + flb_log_metrics_destroy(metrics); return NULL; } } @@ -541,15 +545,6 @@ struct flb_log_metrics *flb_log_metrics_create() return metrics; } -/* Frees the metrics instance and its associated resources. */ -void flb_log_metrics_destroy(struct flb_log_metrics *metrics) -{ - cmt_counter_destroy(metrics->logs_total_counter); - cmt_destroy(metrics->cmt); - flb_free(metrics); -} - - struct flb_log *flb_log_create(struct flb_config *config, int type, int level, char *out) { @@ -832,7 +827,7 @@ void flb_log_print(int type, const char *file, int line, const char *fmt, ...) ts, 1, (char *[]) {msg_type_str}); if (ret == -1) { - // Not using flb_log_debug to avoid recursing into this same function. + /* Not using flb_log_debug to avoid recursing into this same function. */ fprintf(stderr, "[log] failed to increment log total counter for message type '%s' (error=%d)\n", msg_type_str, ret); diff --git a/src/flb_metrics_exporter.c b/src/flb_metrics_exporter.c index 873b1892483..9834ab96cb5 100644 --- a/src/flb_metrics_exporter.c +++ b/src/flb_metrics_exporter.c @@ -301,8 +301,8 @@ struct cmt *flb_me_get_cmetrics(struct flb_config *ctx) if (ctx->log != NULL) { ret = cmt_cat(cmt, ctx->log->metrics->cmt); - if (ret == -1) { - flb_error("[metrics exporter] could not append global log_metrics_ctx"); + if (ret != 0) { + flb_error("[metrics exporter] could not append global log metrics"); cmt_destroy(cmt); return NULL; } From b45c0b505042fcce1ce9fc523ed7fd61b0ebc13a Mon Sep 17 00:00:00 2001 From: Alec Holmes Date: Wed, 28 May 2025 13:28:42 -0700 Subject: [PATCH 6/6] Feedback (temporary -- will squash into above) Signed-off-by: Alec Holmes --- src/flb_log.c | 9 +++++---- src/flb_sds.c | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/flb_log.c b/src/flb_log.c index d692f8cc492..b0e4e28689f 100644 --- a/src/flb_log.c +++ b/src/flb_log.c @@ -481,12 +481,13 @@ int flb_log_set_file(struct flb_config *config, char *out) /* Frees the metrics instance and its associated resources. */ void flb_log_metrics_destroy(struct flb_log_metrics *metrics) { - if (metrics != NULL && metrics->cmt != NULL) { - cmt_destroy(metrics->cmt); + if (metrics == NULL) { + return; } - if (metrics != NULL) { - flb_free(metrics); + if (metrics->cmt != NULL) { + cmt_destroy(metrics->cmt); } + flb_free(metrics); } /* diff --git a/src/flb_sds.c b/src/flb_sds.c index 44e830cd2c8..4ac36ad22e8 100644 --- a/src/flb_sds.c +++ b/src/flb_sds.c @@ -33,7 +33,7 @@ #include #include -static flb_sds_t flb_sds_alloc_internal(size_t size) +static flb_sds_t sds_alloc(size_t size) { void *buf; flb_sds_t s; @@ -60,7 +60,7 @@ flb_sds_t flb_sds_create_len(const char *str, int len) flb_sds_t s; struct flb_sds *head; - s = flb_sds_alloc_internal(len); + s = sds_alloc(len); if (!s) { return NULL; } @@ -91,7 +91,7 @@ flb_sds_t flb_sds_create(const char *str) flb_sds_t flb_sds_create_size(size_t size) { - return flb_sds_alloc_internal(size); + return sds_alloc(size); } /* Increase SDS buffer size 'len' bytes */