Skip to content

Feature/out otel resource attributes#11510

Open
cb645j wants to merge 3 commits intofluent:masterfrom
cb645j:feature/out-otel-resource-attributes
Open

Feature/out otel resource attributes#11510
cb645j wants to merge 3 commits intofluent:masterfrom
cb645j:feature/out-otel-resource-attributes

Conversation

@cb645j
Copy link
Contributor

@cb645j cb645j commented Mar 2, 2026


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
    • OpenTelemetry plugin can promote configured message-body fields into resource attributes for logs.
    • Added a multivalue configuration option to specify which message keys to promote.
  • Bug Fixes / Validation
    • New init-time validation to ensure each configured resource-attribute key is specified correctly (single value).

Example Configuration

[INPUT]
  Name   dummy
  Dummy {"message": "A log message", "span_id": "11aafe22712ca02c", "trace_id": "95e1d11ece6460e7d00c61d45cc195ff", "loglevel": "INFO", "application" : "helloworld", "service.name" : "myservice"}

[OUTPUT]
    Name stdout
    Log_Level trace
    Match *

[OUTPUT]
    Name opentelemetry
    Match *
    Log_Level trace
    Host ingest.frontend.com
    Port 443
    Log_response_payload True
    logs_body_key $message
    logs_span_id_message_key span_id
    logs_trace_id_message_key trace_id
    logs_resource_attributes_message_key application
    logs_resource_attributes_message_key service.name
    logs_severity_text_message_key loglevel
    Tls                  On
    Tls.verify           Off

Debug log ouput

[2026/03/02 15:30:38.171218000] [debug] [output:stdout:stdout.0] task_id=0 assigned to thread #0
{"date":1772483437.169789,"time":"2026-03-02T15:35:24.315873000Z","severity":"debug","severity_number":"7","msg":"Dev pr-11510 test2","subsys":"identity-cache-cell","deployment.environment.name":"dev","service.name":"my-app-log-svc5","application":"TESTAPP-19999"}

Documentation

Key Description Default
logs_resource_attributes_message_key Specify a resource attribute key to look up in the log events body/message none

Otel Log Data Model fields now supported:

  • Timestamp (already supported)
  • ObserveredTimestamp
  • TraceId
  • SpanId
  • TraceFlags
  • SeverityText
  • SeverityNumber
  • Resource
  • InstrumentationScope
  • Attributes (plan to add on separate pr)

Valgrind

coming soon

cb645j and others added 2 commits February 23, 2026 14:54
@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Adds configuration and runtime logic to promote configured message-body keys into OpenTelemetry OTLP resource attributes, with init-time validation and per-record extraction during log flushes.

Changes

Cohort / File(s) Summary
Header & Plugin State
plugins/out_opentelemetry/opentelemetry.h, plugins/out_opentelemetry/opentelemetry.c
Add ra_resource_attributes_message field to opentelemetry_context and expose new config map entry logs_resource_attributes_message_key (SLIST_1, multivalued) mapped to that field.
Configuration Initialization
plugins/out_opentelemetry/opentelemetry_conf.c
Refactor init flow: replace config_add_labels() call with config_log_body() and add config_ra_resource_attributes_message() validator to ensure each configured key has exactly one value.
Runtime Log Handling
plugins/out_opentelemetry/opentelemetry_logs.c
Add helper to read configured keys from the MSGPACK message body, convert values to OTLP KeyValue entries, and append them to resource attributes; call helper in group-start and per-record paths.
Includes / Small deps
plugins/out_opentelemetry/opentelemetry_logs.c
Add flb_slist.h include for SLIST handling.

Sequence Diagram(s)

sequenceDiagram
    participant FluentBit
    participant ConfigLoader as Config (init)
    participant OTLPPlugin as Plugin
    participant OTLPExporter as Collector
    FluentBit->>ConfigLoader: load `logs_resource_attributes_message_key`
    ConfigLoader->>OTLPPlugin: populate ra_resource_attributes_message (validated)
    FluentBit->>OTLPPlugin: emit log batch (MSGPACK)
    OTLPPlugin->>OTLPPlugin: parse message body, lookup configured keys
    OTLPPlugin->>OTLPPlugin: convert values -> OTLP KeyValue, append to resource.attributes
    OTLPPlugin->>OTLPExporter: send OTLP resource logs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

opentelemetry, docs-required

Poem

🐰 I hopped through maps and keys with glee,

Pulled message secrets up to resource tree,
One-by-one each value found,
Now OTLP attributes proudly bound,
Hop, hop—logs sing merrily!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title refers to a real aspect of the change (OpenTelemetry resource attributes feature), but it is overly broad and lacks specificity about the actual change (adding logs_resource_attributes_message_key configuration).

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@cb645j
Copy link
Contributor Author

cb645j commented Mar 2, 2026

This is related to issue #11491

@cb645j cb645j marked this pull request as ready for review March 2, 2026 19:47
@cb645j cb645j requested review from cosmo0920 and edsiper as code owners March 2, 2026 19:47
Copy link

@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: 07e1ed1c54

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link

@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

🧹 Nitpick comments (1)
plugins/out_opentelemetry/opentelemetry_conf.c (1)

186-187: Consider renaming config_log_body to match actual responsibility.

This function currently handles add_label parsing and label KV setup, so the name is misleading.

💡 Suggested rename for clarity
-static int config_log_body(struct flb_output_instance *ins,
-                           struct opentelemetry_context *ctx)
+static int config_add_labels(struct flb_output_instance *ins,
+                             struct opentelemetry_context *ctx)
@@
-    ret = config_log_body(ins, ctx);
+    ret = config_add_labels(ins, ctx);

Also applies to: 332-333

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/out_opentelemetry/opentelemetry_conf.c` around lines 186 - 187, The
function name config_log_body is misleading because it parses add_label and sets
up label key/value pairs; rename the function to something descriptive like
config_parse_labels (or config_setup_labels) and update its
declaration/definition and all call sites that reference config_log_body,
including the second occurrence referenced at lines 332-333; ensure the
opentelemetry_context parameter and any uses of add_label, label KVs, and
related symbols are preserved, update any forward declarations or header
prototypes, and adjust comments/documentation to match the new name.
🤖 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_opentelemetry/opentelemetry_logs.c`:
- Around line 1218-1219: The call to
set_resource_attributes_from_message_body(ctx, event.body,
resource_log->resource) is being run only during resource initialization so
later records in the same resource never get their configured keys promoted;
move this promotion into the per-record processing path where each event.body is
handled (instead of only in the resource init code), invoking
set_resource_attributes_from_message_body with the current ctx and event.body
against resource_log->resource for every record, and make the promotion
idempotent (do not overwrite existing resource attributes unless intended) so
repeated promotions are safe.
- Around line 793-862: The code currently appends promoted keys into
resource->attributes unconditionally, causing duplicates; after creating attr
via msgpack_kv_to_otlp_any_value and before calling flb_realloc, scan the
existing resource->attributes (resource->n_attributes entries) and compare their
key strings to attr->key (e.g., strcmp(resource->attributes[i]->key,
attr->key)); if a match is found, call otlp_kvpair_destroy(attr) and skip the
append (break/continue out of promotion loop) to avoid reallocating and adding a
duplicate; if no match, proceed with the existing flb_realloc / assignment
logic.

---

Nitpick comments:
In `@plugins/out_opentelemetry/opentelemetry_conf.c`:
- Around line 186-187: The function name config_log_body is misleading because
it parses add_label and sets up label key/value pairs; rename the function to
something descriptive like config_parse_labels (or config_setup_labels) and
update its declaration/definition and all call sites that reference
config_log_body, including the second occurrence referenced at lines 332-333;
ensure the opentelemetry_context parameter and any uses of add_label, label KVs,
and related symbols are preserved, update any forward declarations or header
prototypes, and adjust comments/documentation to match the new name.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7db0c7 and 07e1ed1.

📒 Files selected for processing (4)
  • plugins/out_opentelemetry/opentelemetry.c
  • plugins/out_opentelemetry/opentelemetry.h
  • plugins/out_opentelemetry/opentelemetry_conf.c
  • plugins/out_opentelemetry/opentelemetry_logs.c

Comment on lines +793 to +862
int i;
size_t key_len;
struct mk_list *head;
struct flb_config_map_val *mv;
struct flb_slist_entry *entry;
msgpack_object_kv *kv;
Opentelemetry__Proto__Common__V1__KeyValue *attr;
Opentelemetry__Proto__Common__V1__KeyValue **tmp_attrs;

/*
* Use ctx->ra_resource_attributes_message directly — this is the pointer
* managed by the Fluent Bit config-map framework and is reliably available
* in every worker thread context, unlike an embedded mk_list copy.
*/
if (!ctx->ra_resource_attributes_message ||
mk_list_size(ctx->ra_resource_attributes_message) == 0) {
return;
}

if (body == NULL || body->type != MSGPACK_OBJECT_MAP) {
return;
}

/* Iterate directly over the config-map-managed list */
flb_config_map_foreach(head, mv, ctx->ra_resource_attributes_message) {
if (mk_list_size(mv->val.list) != 1) {
continue;
}

entry = mk_list_entry_first(mv->val.list, struct flb_slist_entry, _head);
key_len = flb_sds_len(entry->str);

for (i = 0; i < body->via.map.size; i++) {
kv = &body->via.map.ptr[i];

if (kv->key.type != MSGPACK_OBJECT_STR) {
continue;
}

if (kv->key.via.str.size != key_len) {
continue;
}

if (strncmp(kv->key.via.str.ptr, entry->str, key_len) != 0) {
continue;
}

/* Found the key — convert to OTLP KeyValue */
attr = msgpack_kv_to_otlp_any_value(kv);
if (!attr) {
flb_plg_warn(ctx->ins, "resource attributes: failed to convert key '%s' to OTLP KeyValue",
entry->str);
break;
}

/* Grow the resource attributes array by one slot */
tmp_attrs = flb_realloc(resource->attributes,
(resource->n_attributes + 1) *
sizeof(Opentelemetry__Proto__Common__V1__KeyValue *));
if (!tmp_attrs) {
flb_plg_error(ctx->ins, "resource attributes: memory allocation failed for key '%s'",
entry->str);
otlp_kvpair_destroy(attr);
break;
}

resource->attributes = tmp_attrs;
resource->attributes[resource->n_attributes] = attr;
resource->n_attributes++;
break;
Copy link

@coderabbitai coderabbitai bot Mar 2, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent duplicate resource-attribute keys during promotion.

The helper appends promoted keys unconditionally. If a key already exists in resource->attributes (e.g., from $resource['attributes']), you can emit duplicate keys for the same resource.

💡 Suggested fix (skip already-present keys before append)
 static void set_resource_attributes_from_message_body(
     struct opentelemetry_context *ctx,
     msgpack_object *body,
     Opentelemetry__Proto__Resource__V1__Resource *resource)
 {
     int i;
+    size_t j;
+    int duplicate;
     size_t key_len;
@@
             if (strncmp(kv->key.via.str.ptr, entry->str, key_len) != 0) {
                 continue;
             }
 
+            duplicate = FLB_FALSE;
+            for (j = 0; j < resource->n_attributes; j++) {
+                if (resource->attributes[j] != NULL &&
+                    resource->attributes[j]->key != NULL &&
+                    strcmp(resource->attributes[j]->key, entry->str) == 0) {
+                    duplicate = FLB_TRUE;
+                    break;
+                }
+            }
+
+            if (duplicate == FLB_TRUE) {
+                break;
+            }
+
             /* Found the key — convert to OTLP KeyValue */
             attr = msgpack_kv_to_otlp_any_value(kv);
             if (!attr) {
                 flb_plg_warn(ctx->ins, "resource attributes: failed to convert key '%s' to OTLP KeyValue",
                              entry->str);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/out_opentelemetry/opentelemetry_logs.c` around lines 793 - 862, The
code currently appends promoted keys into resource->attributes unconditionally,
causing duplicates; after creating attr via msgpack_kv_to_otlp_any_value and
before calling flb_realloc, scan the existing resource->attributes
(resource->n_attributes entries) and compare their key strings to attr->key
(e.g., strcmp(resource->attributes[i]->key, attr->key)); if a match is found,
call otlp_kvpair_destroy(attr) and skip the append (break/continue out of
promotion loop) to avoid reallocating and adding a duplicate; if no match,
proceed with the existing flb_realloc / assignment logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

making change

Copy link

Choose a reason for hiding this comment

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

@cb645j, sounds good! The suggested diff should cover it — scan resource->attributes[0..n_attributes-1] and compare each .key against attr->key (via strcmp) before calling flb_realloc. If a match is found, call otlp_kvpair_destroy(attr) and break to skip the append. Let me know if you run into anything while implementing it.

@cb645j
Copy link
Contributor Author

cb645j commented Mar 2, 2026

@edsiper can you please check this

@cb645j
Copy link
Contributor Author

cb645j commented Mar 2, 2026

@patrick-stephens pls review

@cb645j
Copy link
Contributor Author

cb645j commented Mar 2, 2026

link to docs

fluent/fluent-bit-docs#2405

@cb645j
Copy link
Contributor Author

cb645j commented Mar 3, 2026

@cosmo0920 can you please review

@cosmo0920
Copy link
Contributor

@cosmo0920 can you please review

We need to handle coderabbitai's reviews at first.
It seems that it posted several worth comments that are needed to consider.

Signed-off-by: BOSLET, CORY <cb645j+ATT@att.com>
@cb645j
Copy link
Contributor Author

cb645j commented Mar 11, 2026

@cosmo0920 can you please review

We need to handle coderabbitai's reviews at first. It seems that it posted several worth comments that are needed to consider.

i have made updates based off coderabbitai. Can you please check now. How do we get the PR checks to run?

Copy link

@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.

🧹 Nitpick comments (1)
plugins/out_opentelemetry/opentelemetry_conf.c (1)

187-188: Function name config_log_body is misleading.

This function processes add_label configuration and populates ctx->kv_labels, but its name suggests it handles log body configuration. The comment on line 332 (/* Parse 'add_label' */) also conflicts with the function name.

Consider renaming to something more descriptive like config_add_labels or config_kv_labels to match its actual purpose.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/out_opentelemetry/opentelemetry_conf.c` around lines 187 - 188,
Rename the misleading static function config_log_body to a descriptive name like
config_add_labels (or config_kv_labels) because it parses the 'add_label'
configuration and populates ctx->kv_labels; update the function definition, any
prototype/declaration, and every call site to use the new name while keeping the
static linkage, and also update the nearby comment ("/* Parse 'add_label' */")
to match the new function name so identifiers (config_log_body, ctx->kv_labels)
are no longer inconsistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@plugins/out_opentelemetry/opentelemetry_conf.c`:
- Around line 187-188: Rename the misleading static function config_log_body to
a descriptive name like config_add_labels (or config_kv_labels) because it
parses the 'add_label' configuration and populates ctx->kv_labels; update the
function definition, any prototype/declaration, and every call site to use the
new name while keeping the static linkage, and also update the nearby comment
("/* Parse 'add_label' */") to match the new function name so identifiers
(config_log_body, ctx->kv_labels) are no longer inconsistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 125eefb4-5c22-4a49-ad33-0bc7e465a6f8

📥 Commits

Reviewing files that changed from the base of the PR and between 07e1ed1 and d265e3b.

📒 Files selected for processing (2)
  • plugins/out_opentelemetry/opentelemetry_conf.c
  • plugins/out_opentelemetry/opentelemetry_logs.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/out_opentelemetry/opentelemetry_logs.c

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants