Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/cmetrics/.github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true

Expand Down Expand Up @@ -136,7 +136,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true

Expand Down Expand Up @@ -170,7 +170,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true

Expand Down Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions lib/cmetrics/.github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: ludeeus/action-shellcheck@master

actionlint:
Expand All @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions lib/cmetrics/.github/workflows/packages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
matrix:
format: [ rpm, deb ]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true

Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:

runs-on: [ ubuntu-latest ]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true

Expand All @@ -81,7 +81,7 @@ jobs:
ext: pkg
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true

Expand Down Expand Up @@ -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/

Expand Down
13 changes: 7 additions & 6 deletions lib/cmetrics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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()

Expand Down
25 changes: 21 additions & 4 deletions lib/cmetrics/include/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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}
Expand Down
6 changes: 6 additions & 0 deletions lib/cmetrics/include/cmetrics/cmt_decode_prometheus.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#ifndef CMT_DECODE_PROMETHEUS_H
#define CMT_DECODE_PROMETHEUS_H

#include <cmetrics/cmt_info.h>

#ifdef CMT_HAVE_PROMETHEUS_TEXT_DECODER

#include <stdbool.h>

#include <cmetrics/cmetrics.h>
Expand Down Expand Up @@ -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
17 changes: 10 additions & 7 deletions lib/cmetrics/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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
)

Comment on lines +41 to +48
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Always-on remote write: ensure protobuf-c is linked and propagate it; also prefer list(APPEND).

Compiling external/*.pb-c.c introduces a hard link-time dependency on protobuf-c. cmetrics-static currently doesn’t declare/propagate that, which can break final linkage with static libs due to order/transitivity.

  • Within this hunk, switch to list(APPEND) for clarity:
- set(src ${src}
-     cmt_decode_prometheus_remote_write.c
-     # Prometheus related protobuf files
-     external/remote.pb-c.c
-     external/types.pb-c.c
-     )
+ list(APPEND src
+   cmt_decode_prometheus_remote_write.c
+   # Prometheus remote write protobufs
+   external/remote.pb-c.c
+   external/types.pb-c.c
+ )
  • Ensure cmetrics-static links protobuf-c and propagates it (adjust the exact target name to match your build, e.g., protobuf-c or protobuf-c::protobuf-c):
# Replace the existing line with a keyworded form and add protobuf-c
target_link_libraries(cmetrics-static
  PUBLIC mpack-static cfl-static fluent-otel-proto protobuf-c)
  • If protobuf-c discovery isn’t guaranteed earlier, fail fast with a clear message (optional):
if (NOT TARGET protobuf-c AND NOT PROTOBUF_C_FOUND)
  message(FATAL_ERROR "protobuf-c is required when building Prometheus remote write decoder")
endif()

Verification script to confirm discovery/links:


🏁 Script executed:

#!/bin/bash
# Check old var usages
rg -n --hidden -C2 '\bCMT_BUILD_PROMETHEUS_DECODER\b'

# Check protobuf-c discovery/targets
rg -n -C2 'find_package\((ProtobufC|protobuf-c)\b|pkg_check_modules\((PROTOBUF_C|protobuf-c)\b|target_link_libraries\([^)]+protobuf-?c' cmake CMakeLists.txt lib -g '!**/build/**'

Length of output: 0


🏁 Script executed:

#!/bin/bash
set -e

# Search for any find_package(ProtobufC) or find_package(protobuf-c) in CMake files
rg -n --type cmake 'find_package\([^)]*(ProtobufC|protobuf-c)' -C2 .

# Search for pkg_check_modules(PROTOBUF_C) in CMake files
rg -n --type cmake 'pkg_check_modules\([^)]*PROTOBUF_C' -C2 .

# Search for target_link_libraries references to protobuf libraries
rg -n 'target_link_libraries\([^)]+protobuf' -C2 .

# Check for the custom build flag CMT_BUILD_PROMETHEUS_DECODER
rg -n 'CMT_BUILD_PROMETHEUS_DECODER' -C2 .

Length of output: 0


🏁 Script executed:

#!/bin/bash
set -e
sed -n '1,200p' lib/cmetrics/src/CMakeLists.txt

Length of output: 2668


Always-on remote write: link protobuf-c and switch to list(APPEND)

  • In lib/cmetrics/src/CMakeLists.txt (around the block that adds external/*.pb-c.c), replace
    set(src ${src}
        cmt_decode_prometheus_remote_write.c
        external/remote.pb-c.c
        external/types.pb-c.c
    )
    with
    list(APPEND src
        cmt_decode_prometheus_remote_write.c
        external/remote.pb-c.c
        external/types.pb-c.c
    )
  • Add a find_package(ProtobufC REQUIRED) (or your preferred discovery) before appending the .pb-c.c files.
  • Update the static target to propagate protobuf-c:
    target_link_libraries(cmetrics-static
      PUBLIC mpack-static cfl-static fluent-otel-proto protobuf-c
    )
  • (Optional) Fail fast if protobuf-c isn’t available:
    if (NOT TARGET protobuf-c AND NOT PROTOBUF_C_FOUND)
      message(FATAL_ERROR "protobuf-c is required for the Prometheus remote-write decoder")
    endif()
🤖 Prompt for AI Agents
In lib/cmetrics/src/CMakeLists.txt around lines 41 to 48, replace the set(...)
that adds cmt_decode_prometheus_remote_write.c and the generated
external/*.pb-c.c files with list(APPEND src ...) so the files are appended
instead of resetting the variable; add a find_package(ProtobufC REQUIRED) (or
equivalent discovery) before appending the .pb-c.c files; update the
cmetrics-static target to link against protobuf-c by adding protobuf-c to
target_link_libraries(cmetrics-static PUBLIC ...); and (optionally) add a short
check that fails fast with message(FATAL_ERROR ...) if protobuf-c isn’t found
(i.e., if neither TARGET protobuf-c nor PROTOBUF_C_FOUND).


if (MSVC)
set(PLATFORM_SPECIFIC_ATOMIC_MODULE cmt_atomic_msvc.c)
Expand All @@ -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}
Expand Down
2 changes: 1 addition & 1 deletion lib/cmetrics/src/cmt_cat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Comment on lines +111 to 114
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Histogram concatenation drops the +Inf bucket.

hist_buckets has length count + 1; iterating with < count excludes the +Inf bucket at index count, producing incorrect merged histograms.

Apply:

-    for (i = 0; i < histogram->buckets->count; i++) {
+    for (i = 0; i <= histogram->buckets->count; i++) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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];
}
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];
}
🤖 Prompt for AI Agents
In lib/cmetrics/src/cmt_cat.c around lines 111 to 114, the loop iterates only up
to histogram->buckets->count - 1 and thus omits the +Inf bucket at index count;
update the iteration to include the final bucket (either change the loop
condition to iterate up to and including count, or compute bucket_len =
histogram->buckets->count + 1 and loop i < bucket_len) so
metric_dst->hist_buckets accumulates the +Inf bucket as well.

Expand Down
1 change: 1 addition & 0 deletions lib/cmetrics/src/cmt_decode_prometheus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion lib/cmetrics/src/cmt_histogram.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix calloc under-allocation (parentheses bug).

Allocates sizeof(double) * count + 1 bytes instead of (count + 1) * sizeof(double) (or just count * sizeof(double)). This can corrupt memory when writing bucket bounds.

Apply one of the safe patterns (consistent with the rest of this file, upper_bounds has length = count):

-    upper_bounds = calloc(1, sizeof(double) * count + 1);
+    upper_bounds = calloc(count, sizeof(double));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
upper_bounds = calloc(1, sizeof(double) * count + 1);
upper_bounds = calloc(count, sizeof(double));
🤖 Prompt for AI Agents
In lib/cmetrics/src/cmt_histogram.c around line 39, the calloc call is
under-allocating due to missing parentheses (it does sizeof(double) * count +
1); replace it with a correct allocation matching the intended length: use
calloc(count, sizeof(double)) if upper_bounds length == count (or calloc(count +
1, sizeof(double)) if an extra slot is needed), ensuring the multiplication is
done before addition; keep the allocation pattern consistent with the rest of
the file and check for NULL return as done elsewhere.

if (!upper_bounds) {
cmt_errno();
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion lib/cmetrics/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions lib/cmetrics/tests/issues.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <cmetrics/cmt_encode_msgpack.h>
#include <cmetrics/cmt_decode_msgpack.h>
#include <cmetrics/cmt_encode_text.h>
#include <cmetrics/cmt_decode_prometheus.h>
#include <cmetrics/cmt_encode_prometheus.h>

#include "cmt_tests.h"

Expand Down Expand Up @@ -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 }
};
2 changes: 1 addition & 1 deletion lib/monkey/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 10 additions & 8 deletions lib/monkey/mk_server/mk_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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';
Expand Down
12 changes: 2 additions & 10 deletions src/http_server/flb_http_server_http1.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

#include <fluent-bit/http_server/flb_http_server.h>
#include <string.h>

/* PRIVATE */

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
Loading