diff --git a/include/fluent-bit/flb_config.h b/include/fluent-bit/flb_config.h index 4e1912c6459..59bc3a57c8e 100644 --- a/include/fluent-bit/flb_config.h +++ b/include/fluent-bit/flb_config.h @@ -258,6 +258,7 @@ struct flb_config { int enable_hot_reload; int ensure_thread_safety_on_hot_reloading; + unsigned int hot_reloaded_count; /* Co-routines */ unsigned int coro_stack_size; diff --git a/src/flb_config.c b/src/flb_config.c index 459ff8197dd..76973be6e29 100644 --- a/src/flb_config.c +++ b/src/flb_config.c @@ -274,6 +274,7 @@ struct flb_config *flb_config_init() /* reload */ config->ensure_thread_safety_on_hot_reloading = FLB_TRUE; + config->hot_reloaded_count = 0; #ifdef FLB_HAVE_SQLDB mk_list_init(&config->sqldb_list); diff --git a/src/flb_metrics.c b/src/flb_metrics.c index 6f664cfe602..9a9e9c7e7d8 100644 --- a/src/flb_metrics.c +++ b/src/flb_metrics.c @@ -320,6 +320,25 @@ static int attach_build_info(struct flb_config *ctx, struct cmt *cmt, uint64_t t return 0; } +static int attach_hot_reload_info(struct flb_config *ctx, struct cmt *cmt, uint64_t ts, + char *hostname) +{ + double val; + struct cmt_gauge *g; + + g = cmt_gauge_create(cmt, "fluentbit", "", "hot_reloaded_times", + "Collect the count of hot reloaded times.", + 1, (char *[]) {"hostname"}); + if (!g) { + return -1; + } + + val = (double) ctx->hot_reloaded_count; + + cmt_gauge_set(g, ts, val, 1, (char *[]) {hostname}); + return 0; +} + /* Append internal Fluent Bit metrics to context */ int flb_metrics_fluentbit_add(struct flb_config *ctx, struct cmt *cmt) { @@ -340,6 +359,7 @@ int flb_metrics_fluentbit_add(struct flb_config *ctx, struct cmt *cmt) attach_uptime(ctx, cmt, ts, hostname); attach_process_start_time_seconds(ctx, cmt, ts, hostname); attach_build_info(ctx, cmt, ts, hostname); + attach_hot_reload_info(ctx, cmt, ts, hostname); return 0; } diff --git a/src/flb_reload.c b/src/flb_reload.c index 27c5b7f1520..641fa4a66d0 100644 --- a/src/flb_reload.c +++ b/src/flb_reload.c @@ -367,6 +367,7 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) struct flb_cf *new_cf; struct flb_cf *original_cf; int verbose; + int reloaded_count = 0; if (ctx == NULL) { flb_error("[reload] given flb context is NULL"); @@ -425,6 +426,8 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) /* Inherit verbose from the old ctx instance */ verbose = ctx->config->verbose; new_config->verbose = verbose; + /* Increment and store the number of hot reloaded times */ + reloaded_count = ctx->config->hot_reloaded_count + 1; #ifdef FLB_HAVE_STREAM_PROCESSOR /* Inherit stream processor definitions from command line */ @@ -504,5 +507,11 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) ret = flb_start(new_ctx); + /* Store the new value of hot reloading times into the new context */ + if (ret == 0) { + new_config->hot_reloaded_count = reloaded_count; + flb_debug("[reload] hot reloaded %d time(s)", reloaded_count); + } + return 0; } diff --git a/src/http_server/api/v2/reload.c b/src/http_server/api/v2/reload.c index 83626f11ae2..3bb5159fa57 100644 --- a/src/http_server/api/v2/reload.c +++ b/src/http_server/api/v2/reload.c @@ -33,22 +33,13 @@ #include -static void cb_reload(mk_request_t *request, void *data) +static void handle_reload_request(mk_request_t *request, struct flb_config *config) { int ret; flb_sds_t out_buf; size_t out_size; msgpack_packer mp_pck; msgpack_sbuffer mp_sbuf; - struct flb_hs *hs = data; - struct flb_config *config = hs->config; - - if (request->method != MK_METHOD_POST && - request->method != MK_METHOD_PUT) { - mk_http_status(request, 400); - mk_http_done(request); - return; - } /* initialize buffers */ msgpack_sbuffer_init(&mp_sbuf); @@ -109,6 +100,58 @@ static void cb_reload(mk_request_t *request, void *data) flb_sds_destroy(out_buf); } +static void handle_get_reload_status(mk_request_t *request, struct flb_config *config) +{ + flb_sds_t out_buf; + size_t out_size; + msgpack_packer mp_pck; + msgpack_sbuffer mp_sbuf; + + /* initialize buffers */ + msgpack_sbuffer_init(&mp_sbuf); + msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write); + + msgpack_pack_map(&mp_pck, 1); + msgpack_pack_str(&mp_pck, 16); + msgpack_pack_str_body(&mp_pck, "hot_reload_count", 16); + msgpack_pack_int64(&mp_pck, config->hot_reloaded_count); + + /* Export to JSON */ + out_buf = flb_msgpack_raw_to_json_sds(mp_sbuf.data, mp_sbuf.size); + msgpack_sbuffer_destroy(&mp_sbuf); + if (!out_buf) { + mk_http_status(request, 400); + mk_http_done(request); + return; + } + out_size = flb_sds_len(out_buf); + + mk_http_status(request, 200); + flb_hs_add_content_type_to_req(request, FLB_HS_CONTENT_TYPE_JSON); + mk_http_send(request, out_buf, out_size, NULL); + mk_http_done(request); + + flb_sds_destroy(out_buf); +} + +static void cb_reload(mk_request_t *request, void *data) +{ + struct flb_hs *hs = data; + struct flb_config *config = hs->config; + + if (request->method == MK_METHOD_POST || + request->method == MK_METHOD_PUT) { + handle_reload_request(request, config); + } + else if (request->method == MK_METHOD_GET) { + handle_get_reload_status(request, config); + } + else { + mk_http_status(request, 400); + mk_http_done(request); + } +} + /* Perform registration */ int api_v2_reload(struct flb_hs *hs) {