diff --git a/lib/cmetrics/.github/workflows/build.yaml b/lib/cmetrics/.github/workflows/build.yaml index 9c004466e0b..305a0133e8e 100644 --- a/lib/cmetrics/.github/workflows/build.yaml +++ b/lib/cmetrics/.github/workflows/build.yaml @@ -19,7 +19,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -136,7 +136,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -170,7 +170,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -200,7 +200,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: true diff --git a/lib/cmetrics/.github/workflows/lint.yaml b/lib/cmetrics/.github/workflows/lint.yaml index 01b521496d7..7b23e8bb7dc 100644 --- a/lib/cmetrics/.github/workflows/lint.yaml +++ b/lib/cmetrics/.github/workflows/lint.yaml @@ -10,7 +10,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ludeeus/action-shellcheck@master actionlint: @@ -19,7 +19,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | echo "::add-matcher::.github/actionlint-matcher.json" bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) diff --git a/lib/cmetrics/.github/workflows/packages.yaml b/lib/cmetrics/.github/workflows/packages.yaml index ac5f78aaec5..ec02c4a2ce3 100644 --- a/lib/cmetrics/.github/workflows/packages.yaml +++ b/lib/cmetrics/.github/workflows/packages.yaml @@ -18,7 +18,7 @@ jobs: matrix: format: [ rpm, deb ] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -54,7 +54,7 @@ jobs: runs-on: [ ubuntu-latest ] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -81,7 +81,7 @@ jobs: ext: pkg runs-on: macos-14 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true @@ -109,7 +109,7 @@ jobs: contents: write steps: - name: Download all artefacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: path: artifacts/ diff --git a/lib/cmetrics/CMakeLists.txt b/lib/cmetrics/CMakeLists.txt index 580fd34cb36..5421f8c80da 100644 --- a/lib/cmetrics/CMakeLists.txt +++ b/lib/cmetrics/CMakeLists.txt @@ -68,11 +68,11 @@ else() endif() # Configuration options -option(CMT_DEV "Enable development mode" No) -option(CMT_DEBUG "Enable debug mode" No) -option(CMT_TESTS "Enable unit testing" No) +option(CMT_DEV "Enable development mode" No) +option(CMT_DEBUG "Enable debug mode" No) +option(CMT_TESTS "Enable unit testing" No) option(CMT_INSTALL_TARGETS "Enable subdirectory library installations" Yes) -option(CMT_ENABLE_PROMETHEUS_DECODER "Enable prometheus decoder" Yes) +option(CMT_PROMETHEUS_TEXT_DECODER "Enable prometheus text format decoder (requires Flex/Bison)" Yes) if(CMT_DEV) set(CMT_TESTS Yes) @@ -155,7 +155,7 @@ check_c_source_compiles(" return 0; }" CMT_HAVE_MSGPACK) -if(CMT_ENABLE_PROMETHEUS_DECODER) +if(CMT_PROMETHEUS_TEXT_DECODER) # Flex and Bison: check if the variables has not been defined before by # a parent project to avoid conflicts. if(NOT FLEX_FOUND) @@ -167,7 +167,8 @@ if(CMT_ENABLE_PROMETHEUS_DECODER) endif() if(FLEX_FOUND AND BISON_FOUND) - set(CMT_BUILD_PROMETHEUS_DECODER 1) + set(CMT_BUILD_PROMETHEUS_TEXT_DECODER 1) + CMT_DEFINITION(CMT_HAVE_PROMETHEUS_TEXT_DECODER) endif() endif() diff --git a/lib/cmetrics/include/CMakeLists.txt b/lib/cmetrics/include/CMakeLists.txt index 060ec03e181..5d12dff2e39 100644 --- a/lib/cmetrics/include/CMakeLists.txt +++ b/lib/cmetrics/include/CMakeLists.txt @@ -1,8 +1,25 @@ +# Install headers conditionally based on Prometheus text decoder availability file(GLOB cmetricsHeaders "cmetrics/*.h") -install(FILES ${cmetricsHeaders} - DESTINATION ${CMT_INSTALL_INCLUDEDIR}/cmetrics - COMPONENT headers - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) + +if(CMT_BUILD_PROMETHEUS_TEXT_DECODER) + # Install all headers when Prometheus text decoder is enabled + install(FILES ${cmetricsHeaders} + DESTINATION ${CMT_INSTALL_INCLUDEDIR}/cmetrics + COMPONENT headers + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) +else() + # Install headers except Prometheus text decoder header when disabled + # (remote write decoder header is always installed) + foreach(header ${cmetricsHeaders}) + get_filename_component(header_name ${header} NAME) + if(NOT header_name STREQUAL "cmt_decode_prometheus.h") + install(FILES ${header} + DESTINATION ${CMT_INSTALL_INCLUDEDIR}/cmetrics + COMPONENT headers + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) + endif() + endforeach() +endif() file(GLOB promHeaders "prometheus_remote_write/*.h") install(FILES ${promHeaders} diff --git a/lib/cmetrics/include/cmetrics/cmt_decode_prometheus.h b/lib/cmetrics/include/cmetrics/cmt_decode_prometheus.h index 5087981e00e..a565a4715b0 100644 --- a/lib/cmetrics/include/cmetrics/cmt_decode_prometheus.h +++ b/lib/cmetrics/include/cmetrics/cmt_decode_prometheus.h @@ -20,6 +20,10 @@ #ifndef CMT_DECODE_PROMETHEUS_H #define CMT_DECODE_PROMETHEUS_H +#include + +#ifdef CMT_HAVE_PROMETHEUS_TEXT_DECODER + #include #include @@ -110,4 +114,6 @@ int cmt_decode_prometheus_create( struct cmt_decode_prometheus_parse_opts *opts); void cmt_decode_prometheus_destroy(struct cmt *cmt); +#endif /* CMT_HAVE_PROMETHEUS_TEXT_DECODER */ + #endif diff --git a/lib/cmetrics/src/CMakeLists.txt b/lib/cmetrics/src/CMakeLists.txt index 064325ac110..4f46ccfdb60 100644 --- a/lib/cmetrics/src/CMakeLists.txt +++ b/lib/cmetrics/src/CMakeLists.txt @@ -1,4 +1,4 @@ -if (CMT_BUILD_PROMETHEUS_DECODER) +if (CMT_BUILD_PROMETHEUS_TEXT_DECODER) flex_target(cmt_decode_prometheus_lexer cmt_decode_prometheus.l "${FLEX_BISON_GENERATED_DIR}/cmt_decode_prometheus_lexer.c" DEFINES_FILE "${FLEX_BISON_GENERATED_DIR}/cmt_decode_prometheus_lexer.h" @@ -28,7 +28,6 @@ set(src cmt_decode_opentelemetry.c cmt_encode_prometheus.c cmt_encode_prometheus_remote_write.c - cmt_decode_prometheus_remote_write.c cmt_encode_splunk_hec.c cmt_encode_cloudwatch_emf.c cmt_encode_text.c @@ -37,12 +36,16 @@ set(src cmt_decode_msgpack.c cmt_decode_statsd.c cmt_mpack_utils.c - - # Prometheus related protobuf files - external/remote.pb-c.c - external/types.pb-c.c ) +# Add Prometheus remote write decoder (always available, only needs protobuf) +set(src ${src} + cmt_decode_prometheus_remote_write.c + # Prometheus related protobuf files + external/remote.pb-c.c + external/types.pb-c.c + ) + if (MSVC) set(PLATFORM_SPECIFIC_ATOMIC_MODULE cmt_atomic_msvc.c) @@ -63,7 +66,7 @@ set(src ${PLATFORM_SPECIFIC_ATOMIC_MODULE} ) -if (CMT_BUILD_PROMETHEUS_DECODER) +if (CMT_BUILD_PROMETHEUS_TEXT_DECODER) set(src ${src} ${FLEX_cmt_decode_prometheus_lexer_OUTPUTS} ${BISON_cmt_decode_prometheus_parser_OUTPUTS} diff --git a/lib/cmetrics/src/cmt_cat.c b/lib/cmetrics/src/cmt_cat.c index fb4123c3329..dcd941bdb81 100644 --- a/lib/cmetrics/src/cmt_cat.c +++ b/lib/cmetrics/src/cmt_cat.c @@ -108,7 +108,7 @@ static inline int cat_histogram_values(struct cmt_metric *metric_dst, struct cmt } } - for (i = 0; i <= histogram->buckets->count; i++) { + for (i = 0; i < histogram->buckets->count; i++) { /* histogram buckets are always integers, no need to convert them */ metric_dst->hist_buckets[i] += metric_src->hist_buckets[i]; } diff --git a/lib/cmetrics/src/cmt_decode_prometheus.c b/lib/cmetrics/src/cmt_decode_prometheus.c index 846e58242a4..afd22398f46 100644 --- a/lib/cmetrics/src/cmt_decode_prometheus.c +++ b/lib/cmetrics/src/cmt_decode_prometheus.c @@ -174,6 +174,7 @@ static int split_metric_name(struct cmt_decode_prometheus_context *context, *subsystem = strchr(*ns, '_'); if (!(*subsystem)) { *name = *ns; + *subsystem = ""; *ns = ""; } else { diff --git a/lib/cmetrics/src/cmt_histogram.c b/lib/cmetrics/src/cmt_histogram.c index 61efa6e002b..df4a5c8f4f0 100644 --- a/lib/cmetrics/src/cmt_histogram.c +++ b/lib/cmetrics/src/cmt_histogram.c @@ -36,7 +36,7 @@ struct cmt_histogram_buckets *cmt_histogram_buckets_create_size(double *bkts, si } /* besides buckets set by the user, we add an implicit bucket for +inf */ - upper_bounds = calloc(1, sizeof(double) * (count + 1)); + upper_bounds = calloc(1, sizeof(double) * count + 1); if (!upper_bounds) { cmt_errno(); return NULL; diff --git a/lib/cmetrics/tests/CMakeLists.txt b/lib/cmetrics/tests/CMakeLists.txt index 669b30baf0a..c71f8a80540 100644 --- a/lib/cmetrics/tests/CMakeLists.txt +++ b/lib/cmetrics/tests/CMakeLists.txt @@ -14,7 +14,7 @@ set(UNIT_TESTS_FILES filter.c ) -if (CMT_BUILD_PROMETHEUS_DECODER) +if (CMT_BUILD_PROMETHEUS_TEXT_DECODER) set(UNIT_TESTS_FILES ${UNIT_TESTS_FILES} prometheus_lexer.c diff --git a/lib/cmetrics/tests/issues.c b/lib/cmetrics/tests/issues.c index 8e6116e26cb..651a8c405a4 100644 --- a/lib/cmetrics/tests/issues.c +++ b/lib/cmetrics/tests/issues.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "cmt_tests.h" @@ -89,7 +91,40 @@ void test_issue_54() cmt_destroy(cmt1); } +#ifdef CMT_HAVE_PROMETHEUS_TEXT_DECODER + +/* issue: https://github.com/fluent/fluent-bit/issues/10761 */ +void test_prometheus_metric_no_subsystem() +{ + const char text[] = + "# HELP up A simple example metric no subsystem\n" + "# TYPE up gauge\n" + "up{job=\"42\"} 1\n"; + struct cmt *cmt; + cfl_sds_t result; + int ret; + + cmt_initialize(); + + ret = cmt_decode_prometheus_create(&cmt, text, strlen(text), NULL); + TEST_CHECK(ret == CMT_DECODE_PROMETHEUS_SUCCESS); + if (ret == CMT_DECODE_PROMETHEUS_SUCCESS) { + result = cmt_encode_prometheus_create(cmt, CMT_TRUE); + TEST_CHECK(result != NULL); + if (result) { + TEST_CHECK(strstr(result, "up{job=\"42\"} 1") != NULL); + cmt_encode_prometheus_destroy(result); + } + cmt_decode_prometheus_destroy(cmt); + } +} + +#endif + TEST_LIST = { {"issue_54", test_issue_54}, +#ifdef CMT_HAVE_PROMETHEUS_TEXT_DECODER + {"prometheus_metric_no_subsystem", test_prometheus_metric_no_subsystem}, +#endif { 0 } }; diff --git a/lib/monkey/CMakeLists.txt b/lib/monkey/CMakeLists.txt index 799d3059db8..3fbace595fe 100644 --- a/lib/monkey/CMakeLists.txt +++ b/lib/monkey/CMakeLists.txt @@ -23,7 +23,7 @@ endif() # Monkey Version set(MK_VERSION_MAJOR 1) set(MK_VERSION_MINOR 8) -set(MK_VERSION_PATCH 4) +set(MK_VERSION_PATCH 5) set(MK_VERSION_STR "${MK_VERSION_MAJOR}.${MK_VERSION_MINOR}.${MK_VERSION_PATCH}") # Output paths diff --git a/lib/monkey/mk_server/mk_http.c b/lib/monkey/mk_server/mk_http.c index 184a695a811..ad12a74a045 100644 --- a/lib/monkey/mk_server/mk_http.c +++ b/lib/monkey/mk_server/mk_http.c @@ -94,6 +94,16 @@ void mk_http_request_init(struct mk_http_session *session, session->channel, NULL, NULL, NULL, NULL); + + /* Initialize headers input stream */ + request->in_headers.type = MK_STREAM_IOV; + request->in_headers.dynamic = MK_FALSE; + request->in_headers.cb_consumed = NULL; + request->in_headers.cb_finished = NULL; + request->in_headers.buffer = NULL; + request->in_headers.bytes_total = 0; + request->in_headers.stream = &request->stream; + mk_list_add(&request->in_headers._head, &request->stream.inputs); } static inline int mk_http_point_header(mk_ptr_t *h, @@ -722,14 +732,6 @@ int mk_http_init(struct mk_http_session *cs, struct mk_http_request *sr, ret_file = mk_file_get_info(sr->real_path.data, &sr->file_info, MK_FILE_READ); - /* Manually set the headers input streams */ - sr->in_headers.type = MK_STREAM_IOV; - sr->in_headers.dynamic = MK_FALSE; - sr->in_headers.cb_consumed = NULL; - sr->in_headers.cb_finished = NULL; - sr->in_headers.stream = &sr->stream; - mk_list_add(&sr->in_headers._head, &sr->stream.inputs); - /* Plugin Stage 30: look for handlers for this request */ if (sr->stage30_blocked == MK_FALSE) { sr->uri_processed.data[sr->uri_processed.len] = '\0'; diff --git a/src/http_server/flb_http_server_http1.c b/src/http_server/flb_http_server_http1.c index 717e233bdd8..f21affcf7f5 100644 --- a/src/http_server/flb_http_server_http1.c +++ b/src/http_server/flb_http_server_http1.c @@ -18,6 +18,7 @@ */ #include +#include /* PRIVATE */ @@ -55,16 +56,6 @@ static void dummy_mk_http_request_init(struct mk_http_session *session, memset(request, 0, sizeof(struct mk_http_request)); mk_http_request_init(session, request, session->server); - - request->in_headers.type = MK_STREAM_IOV; - request->in_headers.dynamic = MK_FALSE; - request->in_headers.cb_consumed = NULL; - request->in_headers.cb_finished = NULL; - request->in_headers.stream = &request->stream; - - mk_list_add(&request->in_headers._head, &request->stream.inputs); - - request->session = session; } static int http1_evict_request(struct flb_http1_server_session *session) @@ -464,6 +455,7 @@ int flb_http1_server_session_init(struct flb_http1_server_session *session, dummy_mk_http_session_init(&session->inner_session, &session->inner_server); + memset(&session->inner_request, 0, sizeof(struct mk_http_request)); dummy_mk_http_request_init(&session->inner_session, &session->inner_request); mk_http_parser_init(&session->inner_parser);