Skip to content

out_s3: Handle otlp JSON format#11762

Open
cosmo0920 wants to merge 7 commits intomasterfrom
cosmo0920-handle-otlp-json-format-on-s3
Open

out_s3: Handle otlp JSON format#11762
cosmo0920 wants to merge 7 commits intomasterfrom
cosmo0920-handle-otlp-json-format-on-s3

Conversation

@cosmo0920
Copy link
Copy Markdown
Contributor

@cosmo0920 cosmo0920 commented Apr 30, 2026

With using otel input, we need to encode hex strings from binary encoded key-value like span_id and trace_id.
I added fromat parameter to handle binary encoded keys.

2nd attempt of resolving #11630.
Closes #11630.


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
service:
  flush: 1
  grace: 30
  log_level: info
  hot_reload: on
  http_server: on
  http_port: 2020
  health_check: on

pipeline:
  inputs:
    - name: opentelemetry
      port: 4318
      buffer_max_size: 10MB
      buffer_chunk_size: 512KB

  filters:
    - name: stdout
      match: '*'

  outputs:
    - name: s3
      match: '*'
      retry_limit: 5
      workers: 1
      bucket: "<your_bucket_name>
      region: "ap-region"
      upload_timeout: 1m
      format: otlp_json # Strictly handled parameter
      s3_key_format: /prefix/%Y-%m-%d-%H-%M-%S-$UUID.log
      total_file_size: 1MB
      json_date_key: false
      use_put_object: true
  • Debug log output from testing the change
* Copyright (C) 2015-2026 The Fluent Bit Authors
* Fluent Bit is a CNCF graduated project under the Fluent organization
* https://fluentbit.io

______ _                  _    ______ _ _           _____  _____ 
|  ___| |                | |   | ___ (_) |         |  ___||  _  |
| |_  | |_   _  ___ _ __ | |_  | |_/ /_| |_  __   _|___ \ | |/' |
|  _| | | | | |/ _ \ '_ \| __| | ___ \ | __| \ \ / /   \ \|  /| |
| |   | | |_| |  __/ | | | |_  | |_/ / | |_   \ V //\__/ /\ |_/ /
\_|   |_|\__,_|\___|_| |_|\__| \____/|_|\__|   \_/ \____(_)\___/


[2026/04/30 16:03:45.400] [ info] Configuration:
[2026/04/30 16:03:45.400] [ info]  flush time     | 1.000000 seconds
[2026/04/30 16:03:45.400] [ info]  grace          | 30 seconds
[2026/04/30 16:03:45.400] [ info]  daemon         | 0
[2026/04/30 16:03:45.400] [ info] ___________
[2026/04/30 16:03:45.400] [ info]  inputs:
[2026/04/30 16:03:45.400] [ info]      opentelemetry
[2026/04/30 16:03:45.400] [ info] ___________
[2026/04/30 16:03:45.400] [ info]  filters:
[2026/04/30 16:03:45.400] [ info]      stdout.0
[2026/04/30 16:03:45.400] [ info] ___________
[2026/04/30 16:03:45.400] [ info]  outputs:
[2026/04/30 16:03:45.400] [ info]      s3.0
[2026/04/30 16:03:45.400] [ info] ___________
[2026/04/30 16:03:45.400] [ info]  collectors:
[2026/04/30 16:03:45.400] [ info] [fluent bit] version=5.0.4, commit=8c0880a8d8, pid=6721
[2026/04/30 16:03:45.400] [debug] [engine] coroutine stack size: 36864 bytes (36.0K)
[2026/04/30 16:03:45.400] [ info] [storage] ver=1.4.0, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2026/04/30 16:03:45.400] [ info] [simd    ] NEON
[2026/04/30 16:03:45.400] [ info] [cmetrics] version=2.1.2
[2026/04/30 16:03:45.400] [ info] [ctraces ] version=0.7.1
[2026/04/30 16:03:45.401] [ info] [input:opentelemetry:opentelemetry.0] initializing
[2026/04/30 16:03:45.401] [ info] [input:opentelemetry:opentelemetry.0] storage_strategy='memory' (memory only)
[2026/04/30 16:03:45.401] [debug] [opentelemetry:opentelemetry.0] created event channels: read=21 write=22
[2026/04/30 16:03:45.401] [debug] [downstream] listening on 0.0.0.0:4318
[2026/04/30 16:03:45.401] [ info] [input:opentelemetry:opentelemetry.0] listening on 0.0.0.0:4318 with 1 worker
[2026/04/30 16:03:45.401] [debug] [s3:s3.0] created event channels: read=24 write=25
[2026/04/30 16:03:45.450] [debug] [tls] attempting to load certificates from system keychain of macOS
<snip>
[2026/04/30 16:03:45.538] [debug] [tls] successfully loaded and added certificate 158 to trusted store
[2026/04/30 16:03:45.538] [debug] [tls] finished loading keychain certificates, total loaded: 159
[2026/04/30 16:03:45.538] [debug] [aws_credentials] Initialized Env Provider in standard chain
[2026/04/30 16:03:45.538] [debug] [aws_credentials] creating profile (null) provider
[2026/04/30 16:03:45.538] [debug] [aws_credentials] Initialized AWS Profile Provider in standard chain
[2026/04/30 16:03:45.538] [debug] [aws_credentials] Not initializing EKS provider because AWS_ROLE_ARN was not set
[2026/04/30 16:03:45.538] [debug] [aws_credentials] Not initializing ECS/EKS HTTP Provider because AWS_CONTAINER_CREDENTIALS_RELATIVE_URI and AWS_CONTAINER_CREDENTIALS_FULL_URI is not set
[2026/04/30 16:03:45.538] [debug] [aws_credentials] Initialized EC2 Provider in standard chain
[2026/04/30 16:03:45.538] [debug] [aws_credentials] Sync called on the EC2 provider
[2026/04/30 16:03:45.538] [debug] [aws_credentials] Init called on the env provider
[2026/04/30 16:03:45.538] [debug] [aws_credentials] upstream_set called on the EC2 provider
[2026/04/30 16:03:45.539] [ info] [output:s3:s3.0] initializing worker
[2026/04/30 16:03:45.539] [ info] [output:s3:s3.0] worker #0 started
[2026/04/30 16:03:45.539] [debug] [downstream] listening on 0.0.0.0:2020
[2026/04/30 16:03:45.539] [ info] [http_server] listen iface=0.0.0.0 tcp_port=2020
[2026/04/30 16:03:45.539] [ info] [sp] stream processor started
[2026/04/30 16:03:45.539] [ info] [engine] Shutdown Grace Period=30, Shutdown Input Grace Period=15
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[2026/04/30 16:03:50.543] [debug] [task] created task=0x700f24480 id=0 OK
[2026/04/30 16:03:50.543] [debug] [output:s3:s3.0] task_id=0 assigned to thread #0
[2026/04/30 16:03:50.543] [debug] [output:s3:s3.0] Creating upload timer with frequency 10s
[2026/04/30 16:03:50.675] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 is connected
[2026/04/30 16:03:50.675] [debug] [http_client] not using http_proxy for header
[2026/04/30 16:03:50.675] [debug] [aws_credentials] Requesting credentials from the env provider..
[2026/04/30 16:03:50.731] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 is now available
[2026/04/30 16:03:50.731] [debug] [output:s3:s3.0] PutObject http status=200
[2026/04/30 16:03:50.731] [ info] [output:s3:s3.0] Successfully uploaded object /prefix/2026-03-30-13-36-04-ggddB56D.log
[2026/04/30 16:03:50.731] [debug] [out flush] cb_destroy coro_id=0
[2026/04/30 16:03:50.731] [debug] [task] destroy task=0x700f24480 (task_id=0)
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[2026/04/30 16:03:55.543] [debug] [task] created task=0x700f24480 id=0 OK
[2026/04/30 16:03:55.543] [debug] [output:s3:s3.0] task_id=0 assigned to thread #0
[2026/04/30 16:03:55.543] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 has been assigned (recycled)
[2026/04/30 16:03:55.543] [debug] [http_client] not using http_proxy for header
[2026/04/30 16:03:55.543] [debug] [aws_credentials] Requesting credentials from the env provider..
[2026/04/30 16:03:55.598] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 is now available
[2026/04/30 16:03:55.599] [debug] [output:s3:s3.0] PutObject http status=200
[2026/04/30 16:03:55.599] [ info] [output:s3:s3.0] Successfully uploaded object /prefix/2026-03-30-13-36-04-YTCXu7Op.log
[2026/04/30 16:03:55.599] [debug] [out flush] cb_destroy coro_id=1
[2026/04/30 16:03:55.599] [debug] [task] destroy task=0x700f24480 (task_id=0)
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[2026/04/30 16:03:56.543] [debug] [task] created task=0x700f24480 id=0 OK
[2026/04/30 16:03:56.543] [debug] [output:s3:s3.0] task_id=0 assigned to thread #0
[2026/04/30 16:03:56.543] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 has been assigned (recycled)
[2026/04/30 16:03:56.543] [debug] [http_client] not using http_proxy for header
[2026/04/30 16:03:56.543] [debug] [aws_credentials] Requesting credentials from the env provider..
[2026/04/30 16:03:56.641] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 is now available
[2026/04/30 16:03:56.641] [debug] [output:s3:s3.0] PutObject http status=200
[2026/04/30 16:03:56.641] [ info] [output:s3:s3.0] Successfully uploaded object /prefix/2026-03-30-13-36-04-RlZyghZy.log
[2026/04/30 16:03:56.641] [debug] [out flush] cb_destroy coro_id=2
[2026/04/30 16:03:56.642] [debug] [task] destroy task=0x700f24480 (task_id=0)
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[2026/04/30 16:03:57.543] [debug] [task] created task=0x700f24480 id=0 OK
[2026/04/30 16:03:57.543] [debug] [output:s3:s3.0] task_id=0 assigned to thread #0
[2026/04/30 16:03:57.543] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 has been assigned (recycled)
[2026/04/30 16:03:57.543] [debug] [http_client] not using http_proxy for header
[2026/04/30 16:03:57.543] [debug] [aws_credentials] Requesting credentials from the env provider..
[2026/04/30 16:03:57.580] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 is now available
[2026/04/30 16:03:57.580] [debug] [output:s3:s3.0] PutObject http status=200
[2026/04/30 16:03:57.580] [ info] [output:s3:s3.0] Successfully uploaded object /prefix/2026-03-30-13-36-04-PO1DaGCd.log
[2026/04/30 16:03:57.580] [debug] [out flush] cb_destroy coro_id=3
[2026/04/30 16:03:57.580] [debug] [task] destroy task=0x700f24480 (task_id=0)
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[0] v1_logs: [1774877764.000000000, {"otlp"=>{"observed_timestamp"=>1774877764000000000, "severity_number"=>2, "severity_text"=>"INFO", "trace_id"=>"\xc4\x13\xd5\xb5\xfe\xa3es%\xfff3 \xc7\xfd\x10", "span_id"=>"we\x1b\xbd\\xe0\xce\x99"}}, {"specversion"=>"1.0", "id"=>"3c344379-2eee-404b-b144-79ffbee05861"}]
[2026/04/30 16:03:58.543] [debug] [task] created task=0x700f24480 id=0 OK
[2026/04/30 16:03:58.543] [debug] [output:s3:s3.0] task_id=0 assigned to thread #0
[2026/04/30 16:03:58.543] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 has been assigned (recycled)
[2026/04/30 16:03:58.543] [debug] [http_client] not using http_proxy for header
[2026/04/30 16:03:58.543] [debug] [aws_credentials] Requesting credentials from the env provider..
[2026/04/30 16:03:58.584] [debug] [upstream] KA connection #48 to s3.ap-northeast-1.amazonaws.com:443 is now available
[2026/04/30 16:03:58.584] [debug] [output:s3:s3.0] PutObject http status=200
[2026/04/30 16:03:58.584] [ info] [output:s3:s3.0] Successfully uploaded object /prefix/2026-03-30-13-36-04-EE1U6sHw.log
[2026/04/30 16:03:58.584] [debug] [out flush] cb_destroy coro_id=4
[2026/04/30 16:03:58.584] [debug] [task] destroy task=0x700f24480 (task_id=0)
[2026/04/30 16:04:00.547] [debug] [output:s3:s3.0] Running upload timer callback (upload_queue)..
[2026/04/30 16:04:00.547] [debug] [output:s3:s3.0] No files found in upload_queue. Scanning for timed out chunks
[2026/04/30 16:04:00.547] [ info] [output:s3:s3.0] Running upload timer callback (cb_s3_upload)..
^C[2026/04/30 16:04:01] [engine] caught signal (SIGINT)
[2026/04/30 16:04:01.815] [ info] [output:s3:s3.0] thread worker #0 stopping...
[2026/04/30 16:04:01.815] [ info] [output:s3:s3.0] terminating worker
[2026/04/30 16:04:01.816] [ info] [output:s3:s3.0] thread worker #0 stopped

Sample OTEL payloads with ingested by curl:

$ curl -sS -X POST http://127.0.0.1:4318/v1/logs \
     -H 'Content-Type: application/json' -d '{"resourceLogs":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"my.service"}}]},"scopeLogs":[{"scope":{"name":"my.library","version":"1.0.0","attributes":[{"key":"my.scope.attribute","value":{"stringValue":"somescopeattribute"}}]},"logRecords":[{"timeUnixNano":"1774877764000000000","observedTimeUnixNano":"1774877764000000000","severityNumber":2,"severityText":"INFO","traceId":"c413d5b5fea3657325ff663320c7fd10","spanId":"77651bbd5ce0ce99","body":{"kvlistValue":{"values":[{"key":"specversion","value":{"stringValue":"1.0"}},{"key":"id","value":{"stringValue":"3c344379-2eee-404b-b144-79ffbee05861"}}]}}}]}]}]}'

And out_s3 encodes binary encoded records into hex encoding with concatenated records include of chunks:

{
  "resourceLogs": [
    {
      "resource": {
        "attributes": [
          {
            "key": "service.name",
            "value": {
              "stringValue": "my.service"
            }
          }
        ]
      },
      "scopeLogs": [
        {
          "scope": {
            "name": "my.library",
            "version": "1.0.0",
            "attributes": [
              {
                "key": "my.scope.attribute",
                "value": {
                  "stringValue": "somescopeattribute"
                }
              }
            ]
          },
          "logRecords": [
            {
              "timeUnixNano": "1774877764000000000",
              "observedTimeUnixNano": "1774877764000000000",
              "severityNumber": 2,
              "severityText": "INFO",
              "traceId": "c413d5b5fea3657325ff663320c7fd10",
              "spanId": "77651bbd5ce0ce99",
              "body": {
                "kvlistValue": {
                  "values": [
                    {
                      "key": "specversion",
                      "value": {
                        "stringValue": "1.0"
                      }
                    },
                    {
                      "key": "id",
                      "value": {
                        "stringValue": "3c344379-2eee-404b-b144-79ffbee05861"
                      }
                    }
                  ]
                }
              }
            },
            {
              "timeUnixNano": "1774877764000000000",
              "observedTimeUnixNano": "1774877764000000000",
              "severityNumber": 2,
              "severityText": "INFO",
              "traceId": "c413d5b5fea3657325ff663320c7fd10",
              "spanId": "77651bbd5ce0ce99",
              "body": {
                "kvlistValue": {
                  "values": [
                    {
                      "key": "specversion",
                      "value": {
                        "stringValue": "1.0"
                      }
                    },
                    {
                      "key": "id",
                      "value": {
                        "stringValue": "3c344379-2eee-404b-b144-79ffbee05861"
                      }
                    }
                  ]
                }
              }
            }
          ]
        }
      ]
    }
  ]
}
  • 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

    • S3 output plugin: configurable output format (default JSON Lines; options include OTLP JSON and pretty OTLP JSON).
    • OTLP modes emit OTLP-compatible JSON for logs, metrics, and traces.
  • Bug Fixes / Reliability

    • Configuration validates allowed format values and rejects invalid entries.
    • log_key is disallowed with OTLP formats to prevent incompatible output.
    • Flush behavior improved: OTLP formats are serialized and uploaded immediately; other formats keep prior buffering.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a configurable format option to the S3 output plugin (defaults to json_lines), validates format, disallows log_key with otlp_json, centralizes chunk serialization into s3_format_event_chunk(), and makes OTLP modes bypass buffering by uploading serialized payloads directly.

Changes

Cohort / File(s) Summary
S3 Plugin Implementation
plugins/out_s3/s3.c
Add format parsing/validation (json_lines, otlp_json, otlp_json_pretty), refactor chunk serialization into s3_format_event_chunk(), implement OTLP JSON (and pretty) conversion for logs/metrics/traces, error on log_key with otlp_json, and make OTLP flows call s3_put_object() directly (bypass prior buffering/upload queue).
S3 Plugin Header
plugins/out_s3/s3.h
Add public int out_format member to struct flb_s3 to store configured output format.
Config/Docs (implicit)
...
Configuration now supports a format key with allowed values (json_lines, otlp_json, otlp_json_pretty); docs/schema likely require update to reflect new option and validation.

Sequence Diagram

sequenceDiagram
    participant Flush as Flush callback
    participant S3 as S3 plugin
    participant Helper as s3_format_event_chunk
    participant OTLP as OTLP converter
    participant Store as S3 storage

    Flush->>S3: deliver event chunk
    S3->>Helper: s3_format_event_chunk(chunk, out_format, log_key)
    alt out_format == otlp_json or otlp_json_pretty
        Helper->>OTLP: convert msgpack (logs/metrics/traces)
        OTLP-->>Helper: OTLP JSON / pretty JSON (or NULL)
        Helper-->>S3: formatted_payload or NULL
        S3->>Store: s3_put_object(formatted_payload)
    else json_lines
        Helper->>Helper: extract `log_key` or marshal JSON Lines
        Helper-->>S3: formatted_payload
        S3->>Store: enqueue/buffer/upload via existing path
    end
    Store-->>S3: success / error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • fujimotos
  • koleini

Poem

🐰 I hop through chunks both large and small,
I pick a format when the configs call,
OTLP or JSON Lines I tidy and pack,
I bound to S3 and never look back,
Carrots and payloads — delivered, one and all 🥕

🚥 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
Title check ✅ Passed The title 'out_s3: Handle otlp JSON format' directly describes the main change: adding OTLP JSON format support to the S3 output plugin.
Linked Issues check ✅ Passed The PR implements format parameter with otlp_json support to convert binary-encoded trace_id/span_id to hex strings, directly addressing issue #11630's core requirement of preserving OTEL trace IDs and span IDs.
Out of Scope Changes check ✅ Passed All changes are focused on S3 plugin format handling and OTLP serialization; no unrelated modifications detected beyond the stated objectives.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cosmo0920-handle-otlp-json-format-on-s3

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 and usage tips.

@cosmo0920 cosmo0920 added this to the Fluent Bit v5.0.4 milestone Apr 30, 2026
Copy link
Copy Markdown

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

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: 7928c53340

ℹ️ 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_s3/s3.c Outdated
Comment thread plugins/out_s3/s3.c Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/out_s3/s3.c`:
- Around line 710-712: The code sets ins->event_type |= FLB_OUTPUT_METRICS |
FLB_OUTPUT_TRACES when ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP, which
advertises metrics/traces support that cb_s3_flush cannot safely handle (it
still computes file_first_log_time via log-style decoding). Revert/remove the OR
of FLB_OUTPUT_METRICS and FLB_OUTPUT_TRACES in that branch (leave event_type
as-is for now) or gate it behind a new capability check, and only re-enable
setting those bits after cb_s3_flush (and any helpers that compute
file_first_log_time and object naming) is updated to properly decode and handle
OTLP/metrics/traces payloads.
🪄 Autofix (Beta)

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

Run ID: 0f8b6775-4a4e-4c76-ad5c-c1b61c4cc265

📥 Commits

Reviewing files that changed from the base of the PR and between 230eb3c and 7928c53.

📒 Files selected for processing (2)
  • plugins/out_s3/s3.c
  • plugins/out_s3/s3.h

Comment thread plugins/out_s3/s3.c Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@plugins/out_s3/s3.c`:
- Around line 3799-3825: The current path using flb_opentelemetry_*_to_otlp_json
(e.g. flb_opentelemetry_logs_to_otlp_json,
flb_opentelemetry_metrics_msgpack_to_otlp_json,
flb_opentelemetry_traces_msgpack_to_otlp_json) returns complete OTLP JSON
documents per engine chunk but the out_s3 buffering concatenates chunks raw,
producing invalid "doc1doc2..." objects; fix by either (A) merging multiple OTLP
JSON documents into a single valid JSON container before returning/ buffering
(e.g., wrap items into a top-level array or merge their inner arrays/objects) or
(B) force upload-one-object-per-chunk for OTLP JSON paths by signalling the
caller to flush immediately instead of buffering; update the branch handling
ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP (and the similar code at the other
occurrence noted) to implement one of these approaches so S3 objects remain
valid OTLP JSON rather than concatenated documents.
- Around line 693-708: When parsing the "format" in cb_s3_init() (the block that
calls flb_pack_to_json_format_type and sets ctx->out_format), validate that if
the selected format is FLB_PACK_JSON_FORMAT_OTLP (otlp_json) then no log_key is
configured: detect the presence of a log_key (via
flb_output_get_property("log_key", ins) or ctx->log_key) and if both are present
call flb_plg_error on ctx->ins with a descriptive message and return -1 to fail
fast; also add the same check in the other format-parsing site that mirrors this
logic (the similar block referenced around the other occurrence) so
s3_format_event_chunk() won’t silently ignore ctx->log_key in OTLP mode.
🪄 Autofix (Beta)

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

Run ID: ccf4a2ac-4f19-40ea-a4d9-e5e29fba7ed7

📥 Commits

Reviewing files that changed from the base of the PR and between 7928c53 and bd1fcad.

📒 Files selected for processing (2)
  • plugins/out_s3/s3.c
  • plugins/out_s3/s3.h

Comment thread plugins/out_s3/s3.c
Comment thread plugins/out_s3/s3.c Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/out_s3/s3.c`:
- Around line 3814-3829: The conversion calls
(flb_opentelemetry_logs_to_otlp_json,
flb_opentelemetry_metrics_msgpack_to_otlp_json,
flb_opentelemetry_traces_msgpack_to_otlp_json) can return NULL and set the
out-parameter result on error; update the branches that call these functions to
check if the returned json is NULL, and when NULL call flb_plg_error(ctx->ins,
"could not convert event chunk to OTLP JSON: %d", result) and return -1 to match
out_stdout/out_kafka behavior—do this for the LOGS, METRICS and TRACES paths
surrounding the use of the result variable and ctx->ins.
🪄 Autofix (Beta)

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

Run ID: 9deb3cae-bd83-4b40-b91c-e88110e79cc3

📥 Commits

Reviewing files that changed from the base of the PR and between bd1fcad and c671752.

📒 Files selected for processing (1)
  • plugins/out_s3/s3.c

Comment thread plugins/out_s3/s3.c Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
plugins/out_s3/s3.c (1)

710-715: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reject log_key for otlp_json_pretty too.

ctx->log_key is only blocked for otlp_json, but the pretty OTLP path also ignores it in s3_format_event_chunk(). That makes format=otlp_json_pretty silently change the output shape instead of failing fast.

Suggested fix
-        if (ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP &&
+        if ((ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP ||
+             ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP_PRETTY) &&
             ctx->log_key != NULL) {
             flb_plg_error(ctx->ins,
-                          "'log_key' is not supported when format=otlp_json");
+                          "'log_key' is not supported when format is "
+                          "otlp_json or otlp_json_pretty");
             return -1;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/out_s3/s3.c` around lines 710 - 715, The current check in s3.c only
rejects ctx->log_key when ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP, but the
pretty OTLP variant (FLB_PACK_JSON_FORMAT_OTLP_PRETTY) also ignores log_key in
s3_format_event_chunk(), causing silent output changes; update the conditional
that logs the error (the block using flb_plg_error and return -1) to also
include FLB_PACK_JSON_FORMAT_OTLP_PRETTY (i.e., check for either
FLB_PACK_JSON_FORMAT_OTLP || FLB_PACK_JSON_FORMAT_OTLP_PRETTY) so both OTLP JSON
flavors reject log_key up front and fail fast.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@plugins/out_s3/s3.c`:
- Around line 710-715: The current check in s3.c only rejects ctx->log_key when
ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP, but the pretty OTLP variant
(FLB_PACK_JSON_FORMAT_OTLP_PRETTY) also ignores log_key in
s3_format_event_chunk(), causing silent output changes; update the conditional
that logs the error (the block using flb_plg_error and return -1) to also
include FLB_PACK_JSON_FORMAT_OTLP_PRETTY (i.e., check for either
FLB_PACK_JSON_FORMAT_OTLP || FLB_PACK_JSON_FORMAT_OTLP_PRETTY) so both OTLP JSON
flavors reject log_key up front and fail fast.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dbe7e728-f61a-467a-8ae9-c3f2530c8c0a

📥 Commits

Reviewing files that changed from the base of the PR and between c671752 and 8ac97df.

📒 Files selected for processing (1)
  • plugins/out_s3/s3.c

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@plugins/out_s3/s3.c`:
- Around line 3983-3990: The OTLP direct PutObject branch bypasses
upload_data()/put_all_chunks(), so data never gets compressed even though
s3_put_object() sets Content-Encoding; add a helper (e.g.,
s3_put_marshaled_object) that takes the same args as s3_put_object (ctx, tag,
file_first_log_time, body, body_size), performs the existing compression
pre-processing using flb_aws_compression_compress when ctx->compression !=
FLB_AWS_COMPRESS_NONE, calls s3_put_object() with the possibly-compressed buffer
and size, frees any temporary compressed buffer, and return its result; then
replace the direct call site in the OTLP branch to call this new helper instead
of s3_put_object() so advertised Content-Encoding matches the actual payload.
- Around line 710-715: cb_s3_init currently rejects ctx->log_key only when
ctx->out_format == FLB_PACK_JSON_FORMAT_OTLP but not when the pretty OTLP
variant is used, causing s3_format_event_chunk to ignore log_key for
FLB_PACK_JSON_FORMAT_OTLP_PRETTY and silently change output; update the
validation in cb_s3_init to also check for FLB_PACK_JSON_FORMAT_OTLP_PRETTY
(i.e., treat both FLB_PACK_JSON_FORMAT_OTLP and FLB_PACK_JSON_FORMAT_OTLP_PRETTY
the same), log the same flb_plg_error message referencing "'log_key' is not
supported when format=otlp_json" and return -1 so the unsupported combination is
rejected early (also verify s3_format_event_chunk is consistent with this
behavior).
🪄 Autofix (Beta)

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

Run ID: e810d606-8c5a-46dc-825a-0e0a38e146b8

📥 Commits

Reviewing files that changed from the base of the PR and between 8ac97df and caac199.

📒 Files selected for processing (1)
  • plugins/out_s3/s3.c

Comment thread plugins/out_s3/s3.c
Comment thread plugins/out_s3/s3.c Outdated
@cosmo0920 cosmo0920 force-pushed the cosmo0920-handle-otlp-json-format-on-s3 branch from b6cb79d to 3b99023 Compare April 30, 2026 08:54
Copy link
Copy Markdown

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

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: 5ca3029122

ℹ️ 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_s3/s3.c Outdated
Comment thread tests/runtime/out_s3.c Outdated
Comment thread plugins/out_s3/s3.c Outdated
if [[ "$FLB_OPT" =~ COVERAGE ]]; then
# Coverage build requires larger coroutine stack.
if [[ "$FLB_OPT" =~ COVERAGE ||
"$FLB_OPT" =~ SANITIZE_ADDRESS ||
Copy link
Copy Markdown
Contributor

@patrick-stephens patrick-stephens Apr 30, 2026

Choose a reason for hiding this comment

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

Probably can just do a check for == FLB_SANITIZE_* rather than use a regex compare with a specific string - or use the regex compare to just check if it contains?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This SEGV issue which seems to be run out coroutine memory just occurring only for SANITIZE_ADDRESS and SANITIZE_UNDEFINED so gating for FLB_SANITIZE_* is a bit of larger condition than we needed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right, in which case probably use a direct comparison rather than regex as just looks bit weird to me but fine.

cosmo0920 added 7 commits May 1, 2026 10:56
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
…nitizers

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
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.

OTEL trace_id and span_id are malformed

3 participants