Skip to content

openetelemetry: Implement cmetrics max datapoints and its splitting - #12251

Open
cosmo0920 wants to merge 8 commits into
masterfrom
cosmo0920-implement-cmetrics-max-datapoints-and-its-splitting
Open

openetelemetry: Implement cmetrics max datapoints and its splitting#12251
cosmo0920 wants to merge 8 commits into
masterfrom
cosmo0920-implement-cmetrics-max-datapoints-and-its-splitting

Conversation

@cosmo0920

@cosmo0920 cosmo0920 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Implemented as a reusable Fluent Bit core feature, with no lib/cmetrics or other bundled-library changes.

Key changes:

  • Added the core OTLP metric batching API in flb_opentelemetry_metrics_batch.c.
  • Exposed APIs for encoded OTLP, struct cmt, and CMetrics MessagePack in flb_opentelemetry.h.
  • Preserves resource, scope, metric metadata, and supports gauge, sum, histogram, exponential histogram, and summary data points.
  • Added metrics_max_datapoints; 0 retains existing unlimited behavior.
  • Kept out_opentelemetry as a thin consumer of the core API.
  • Corrected HTTP/2 connection recycling exposed by sending multiple gRPC requests.
  • Added boundary, invalid-payload, all-metric-type, HTTP, and gRPC coverage.

Example:

[OUTPUT]
    Name                    opentelemetry
    Match                   *
    metrics_max_datapoints  1000

Verification passed:

  • Build: cmake --build build-codex-otel --target fluent-bit-bin flb-it-opentelemetry -j8
  • Internal: ctest --test-dir build-codex-otel -R flb-it-opentelemetry --output-on-failure — passed
  • Integration: tests/integration/.venv/Scripts/python.exe -m pytest tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py -k metrics_max_datapoints -q — 2 passed
  • HTTP and gRPC both produced three requests containing 4, 4, and 3 data points.
  • git diff --check — passed

Closes #12247.


Enter [N/A] in the box, if an item is not applicable to your change.

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
  • Debug log output from testing the change
  • Attached Valgrind output that shows no leaks or memory corruption was found

If this is a change to packaging of containers or native binaries then please confirm it works for all targets.

  • Run local packaging test showing all targets (including any new ones) build.
  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

Backporting

  • Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

Summary by CodeRabbit

  • New Features

    • Added configurable limits for metric data points in each OpenTelemetry export request.
    • Oversized metric payloads are automatically split into batches for HTTP and gRPC exports.
    • Resource, service, and metric associations are preserved across batches.
    • Zero or unlimited settings retain existing single-request behavior.
  • Bug Fixes

    • Improved handling of invalid limits, empty payloads, and encoding failures.
    • Prevented partially successful batches from being resent.

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

OpenTelemetry metrics now support configurable data-point limits per export request. Oversized protobuf payloads are split across metric boundaries and posted sequentially. CMT and MessagePack inputs use the same batching APIs. Tests cover HTTP, gRPC, metric types, resource preservation, and partial responses.

Changes

Metrics batching

Layer / File(s) Summary
Batching API and protobuf implementation
include/fluent-bit/flb_opentelemetry.h, src/opentelemetry/flb_opentelemetry_metrics_batch.c, src/CMakeLists.txt
Adds public batch structures and APIs. The implementation validates, partitions, serializes, and cleans up metric batches for protobuf, CMT, and MessagePack inputs.
Output configuration and export flow
plugins/out_opentelemetry/opentelemetry.h, plugins/out_opentelemetry/opentelemetry.c
Adds metrics_max_datapoints, validates negative values, submits limited payloads sequentially, and suppresses retries after prior batch success.
Batching validation
tests/internal/opentelemetry.c, tests/integration/scenarios/out_opentelemetry/..., tests/integration/src/server/otlp_server.py, tests/integration/README.md
Tests batching limits, metric types, empty inputs, HTTP and gRPC exports, resource preservation, partial responses, and sequential response statuses.

HTTP/2 connection recycling

Layer / File(s) Summary
HTTP/2 session connection handling
src/flb_http_client.c
Recycles the acquired upstream connection after keepalive is disabled during HTTP/2 session creation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MetricsInput
  participant OpenTelemetryOutput
  participant MetricsBatchAPI
  participant HTTPOrGRPCReceiver
  MetricsInput->>OpenTelemetryOutput: metric protobuf payload
  OpenTelemetryOutput->>MetricsBatchAPI: split by metrics_max_datapoints
  MetricsBatchAPI-->>OpenTelemetryOutput: bounded protobuf batches
  OpenTelemetryOutput->>HTTPOrGRPCReceiver: post batches sequentially
Loading

Possibly related PRs

Suggested reviewers: edsiper

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: splitting OpenTelemetry metrics by a maximum datapoint count, despite minor spelling and grammar issues.
Linked Issues check ✅ Passed The implementation adds configurable metric datapoint limits and splitting, including core APIs, output integration, metadata preservation, and HTTP/gRPC coverage required by issue #12247.
Out of Scope Changes check ✅ Passed All changes support metric batching, retry behavior, HTTP/2 request handling, configuration, or related test coverage for issue #12247.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cosmo0920-implement-cmetrics-max-datapoints-and-its-splitting

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 84e546954a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/out_opentelemetry/opentelemetry.c

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/internal/opentelemetry.c (1)

2966-2994: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add coverage for metrics with no data points.

The splitting loop in flb_opentelemetry_metrics_proto_batches_create has a dedicated path for data_point_count == 0 (it calls batch_add_metric with count 0), and metric_data_point_count has a path for OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA__NOT_SET. Neither path is exercised.

Extend this fixture with one metric that has n_data_points == 0 and one metric with an unset data_case. Then assert that the batch count and the data point totals stay unchanged, and that the empty metrics are still present in the output.

Based on coding guidelines: "Validate both success and failure paths, including invalid payloads, boundary sizes, and null or missing fields."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/internal/opentelemetry.c` around lines 2966 - 2994, Extend the fixture
constructing the metrics request to include one metric with n_data_points set to
0 and another whose data_case is
OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA__NOT_SET. Keep the existing
batch totals and data-point assertions, add checks that the batch count and
totals remain unchanged, and verify both empty metrics are retained in the
resulting batches.

Source: Coding guidelines

plugins/out_opentelemetry/opentelemetry.c (1)

768-780: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Report which batch failed, and document the resend behavior.

If batch n fails after batches 0..n-1 succeeded, the function returns the failure for the complete chunk. The engine then retries the complete chunk, so the already accepted batches are sent again. The backend receives duplicate data points.

The at-least-once semantics are expected in Fluent Bit, but the current code gives no signal about it. Add an error log with the batch index and the total count, so operators can correlate duplicates with a partial export.

♻️ Proposed change
         if (result != FLB_OK) {
+            flb_plg_error(ctx->ins,
+                          "metrics batch %zu of %zu failed; previously accepted "
+                          "batches will be resent on retry",
+                          index + 1, batches->count);
             break;
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/out_opentelemetry/opentelemetry.c` around lines 768 - 780, Update the
batch loop in the surrounding export function to log an error when
opentelemetry_post fails, including the failed batch index and total batches
count. Keep returning the failure for the complete chunk so Fluent Bit retries
it, and document that previously accepted batches may be resent under the
existing at-least-once behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/opentelemetry/flb_opentelemetry_metrics_batch.c`:
- Around line 763-785: Update flb_opentelemetry_metrics_to_otlp_proto_batches
and flb_opentelemetry_metrics_msgpack_to_otlp_proto_batches to share a helper
for empty encoded payloads. When the encoder returns a zero-length payload,
return an empty batch collection with success instead of calling
flb_opentelemetry_metrics_proto_batches_create; preserve existing error handling
for NULL payloads and normal batching for non-empty payloads.
- Around line 342-344: Update metric_data_point_count to treat an unrecognized
data_case as zero data points instead of returning
FLB_OPENTELEMETRY_OTLP_PROTO_INVALID_ARGUMENT. Preserve the existing counts for
the five supported types so flb_opentelemetry_metrics_proto_batches_create
forwards unsupported metrics using the existing metric_view_create behavior.

---

Nitpick comments:
In `@plugins/out_opentelemetry/opentelemetry.c`:
- Around line 768-780: Update the batch loop in the surrounding export function
to log an error when opentelemetry_post fails, including the failed batch index
and total batches count. Keep returning the failure for the complete chunk so
Fluent Bit retries it, and document that previously accepted batches may be
resent under the existing at-least-once behavior.

In `@tests/internal/opentelemetry.c`:
- Around line 2966-2994: Extend the fixture constructing the metrics request to
include one metric with n_data_points set to 0 and another whose data_case is
OPENTELEMETRY__PROTO__METRICS__V1__METRIC__DATA__NOT_SET. Keep the existing
batch totals and data-point assertions, add checks that the batch count and
totals remain unchanged, and verify both empty metrics are retained in the
resulting batches.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5dc3e41f-55cd-44ad-925e-b1581cf94e64

📥 Commits

Reviewing files that changed from the base of the PR and between a1d6fb1 and 84e5469.

📒 Files selected for processing (11)
  • include/fluent-bit/flb_opentelemetry.h
  • plugins/out_opentelemetry/opentelemetry.c
  • plugins/out_opentelemetry/opentelemetry.h
  • src/CMakeLists.txt
  • src/flb_http_client.c
  • src/opentelemetry/flb_opentelemetry_metrics_batch.c
  • tests/integration/README.md
  • tests/integration/scenarios/out_opentelemetry/config/out_otel_grpc_metrics_max_datapoints.conf
  • tests/integration/scenarios/out_opentelemetry/config/out_otel_http_metrics_max_datapoints.conf
  • tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py
  • tests/internal/opentelemetry.c

Comment thread src/opentelemetry/flb_opentelemetry_metrics_batch.c
Comment thread src/opentelemetry/flb_opentelemetry_metrics_batch.c
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
… points

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
…limitation

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/internal/opentelemetry.c (1)

2757-2757: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the required C control-block brace style.

Put the opening brace on the next line for each changed for and if block in this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/internal/opentelemetry.c` at line 2757, Update the changed for and if
control blocks in the OpenTelemetry test code to place each opening brace on the
following line, including the loop beginning with index = 0. Preserve the
existing block logic and indentation.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py`:
- Around line 1030-1042: Strengthen the assertions in the test around
metrics_seen so the first two export requests each contain exactly four points
and their series sets are exactly {0,1,2,3} and {4,5,6,7}, respectively. Also
assert that series IDs 8, 9, and 10 do not appear in any exported request,
replacing the insufficient disjointness-only check.
- Around line 539-619: Validate resource and scope metadata preservation across
batches: in
tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py
lines 539-619, add distinct resource and scope schema URLs, have
iter_metric_points_with_resource return scope metadata alongside each point, and
assert every point retains its resource and scope association; in
tests/internal/opentelemetry.c lines 2900-3065, add distinct resource and scope
metadata to the input request and assert every decoded batch preserves it.

In `@tests/internal/opentelemetry.c`:
- Around line 2921-2955: Expand the test setup around the gauge, sum, histogram,
exponential histogram, and summary metrics so each contains more data points
than max_data_points, then exercise offset-based splitting for every metric
type. Assert each decoded batch retains the expected points and all associated
metric fields, including names, data cases, and type-specific values.

---

Nitpick comments:
In `@tests/internal/opentelemetry.c`:
- Line 2757: Update the changed for and if control blocks in the OpenTelemetry
test code to place each opening brace on the following line, including the loop
beginning with index = 0. Preserve the existing block logic and indentation.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2b960230-a856-479e-b220-cf35c41d36f8

📥 Commits

Reviewing files that changed from the base of the PR and between 84e5469 and 079d083.

📒 Files selected for processing (5)
  • plugins/out_opentelemetry/opentelemetry.c
  • src/opentelemetry/flb_opentelemetry_metrics_batch.c
  • tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py
  • tests/integration/src/server/otlp_server.py
  • tests/internal/opentelemetry.c
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/out_opentelemetry/opentelemetry.c
  • src/opentelemetry/flb_opentelemetry_metrics_batch.c

Comment thread tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py Outdated
Comment thread tests/internal/opentelemetry.c Outdated
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py`:
- Around line 1064-1074: Update the test around the batch_series assertions to
keep the receiver/service active through the configured retry interval before
taking the final requests snapshot and asserting no retry occurred. Ensure the
failed batch remains un-retried and validate both successful batches and the
retry behavior after the wait.
- Around line 1006-1028: Update the batch-validation test around the loop over
points to record series IDs separately for each received request, then assert
the requests arrive in order as {0,1,2,3}, {4,5,6,7}, and {8,9,10}. Preserve the
existing per-point resource and scope assertions, and add coverage for both
successful ordered batches and the failure path when ordering is violated.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 159b17ce-782b-4143-82e8-273bc499555e

📥 Commits

Reviewing files that changed from the base of the PR and between aa2be0e and e17fe88.

📒 Files selected for processing (2)
  • tests/integration/scenarios/out_opentelemetry/tests/test_out_opentelemetry_001.py
  • tests/internal/opentelemetry.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/internal/opentelemetry.c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Limit OpenTelemetry metrics per request to support AWS's OpenTelemetry

1 participant