Skip to content

Conversation

@edsiper
Copy link
Member

@edsiper edsiper commented Sep 1, 2025

Fixes #10796

  • Updated OTLP JSON parsing to treat intValue and doubleValue wrappers containing either numeric or string values as numbers, ensuring attributes are unwrapped correctly during ingestion

  • Extended trace attribute processing to convert numeric strings into integers or doubles when constructing attributes, preventing malformed records for verbose OTLP payloads

  • Added regression tests and fixture cases validating integer attributes expressed as strings, guarding against regressions in wrapped attribute handling


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 ingestion now accepts integer and floating-point attributes provided as strings, automatically coercing them to numeric values.
    • Enhanced validation and error handling for invalid numeric strings to prevent crashes.
  • Tests

    • Added unit tests to verify string-to-number coercion for intValue and doubleValue in JSON payloads.
    • Introduced test data covering resource attributes with numeric values expressed as strings.

Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
@coderabbitai
Copy link

coderabbitai bot commented Sep 1, 2025

Walkthrough

The PR updates OpenTelemetry attribute handling to accept numeric strings for intValue and doubleValue, parsing them into numeric types during ingestion. Utilities and parser logic are adjusted accordingly, and new tests validate coercion for resource attributes with stringified integers.

Changes

Cohort / File(s) Change Summary
OTel input plugin: attribute parsing
plugins/in_opentelemetry/opentelemetry_traces.c
Extended process_attribute to parse string values for integer and float attributes using strtoll/strtod; added memory management and error handling for string parsing paths; relaxed prior strict numeric-only checks.
OTel utils: wrapped value extraction
src/opentelemetry/flb_opentelemetry_utils.c
flb_otel_utils_json_payload_get_wrapped_value now accepts MSGPACK_OBJECT_STR for intValue/doubleValue in addition to numeric types; updated validation logic accordingly.
Tests: JSON scenarios
tests/internal/data/opentelemetry/test_cases.json
Added resource_attribute_intvalue_string test case validating coercion of "1" (string) to 1 for resource attribute resourceVersion.
Tests: unit
tests/internal/opentelemetry.c
Added unit test in test_json_payload_get_wrapped_value for intValue as a string; asserts successful handling and expected types.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant in_opentelemetry as in_opentelemetry
  participant Utils as flb_otel_utils_json_payload_get_wrapped_value
  participant Parser as process_attribute

  Client->>in_opentelemetry: POST /v1/logs (JSON)
  in_opentelemetry->>Utils: Extract wrapped value (intValue/doubleValue)
  alt value is number
    Utils-->>in_opentelemetry: Return numeric msgpack object
  else value is string
    Utils-->>in_opentelemetry: Return string msgpack object
  end
  in_opentelemetry->>Parser: Process attribute (key, value)
  alt integer path
    opt value is string
      Parser->>Parser: strtoll parse to int
    end
    Parser-->>in_opentelemetry: Set integer attribute
  else float path
    opt value is string
      Parser->>Parser: strtod parse to double
    end
    Parser-->>in_opentelemetry: Set float attribute
  else unsupported
    Parser-->>in_opentelemetry: Error
  end
  in_opentelemetry-->>Client: 200 OK
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
Simplify OTLP JSON attributes by coercing string intValue to numeric for resource attributes (#10796)
Accept string forms for intValue and doubleValue in wrapped values parsing (#10796)
Ensure output shows resourceVersion as numeric 1 in group attributes (#10796)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation

Poem

A bunny taps keys with a whisker’s finesse,
Turning “1” into 1—less frill, less mess.
Strings into numbers, neat as a nibble,
Parsing the carrots without any quibble.
Logs hop lighter, fields aligned—
Otel made crisp, by rabbit design. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch otel-resource-attributes

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/opentelemetry/flb_opentelemetry_utils.c (1)

123-131: Allowing doubleValue as string is correct, but downstream conversion is missing.

The unwrap path for FLOAT currently passes through strings unchanged, so {"doubleValue":"3.14"} will emit a string, not a double. Add symmetric parsing like the int branch.

Apply this diff in flb_otel_utils_json_payload_append_unwrapped_value:

-    char            temporary_buffer[33];
+    char            temporary_buffer[128];
@@
-        else if (type == MSGPACK_OBJECT_FLOAT) {
-            unwrap_value = FLB_TRUE;
-        }
+        else if (type == MSGPACK_OBJECT_FLOAT) {
+            if (value->type == MSGPACK_OBJECT_STR) {
+                memset(temporary_buffer, 0, sizeof(temporary_buffer));
+
+                if (value->via.str.size < sizeof(temporary_buffer)) {
+                    strncpy(temporary_buffer,
+                            value->via.str.ptr,
+                            value->via.str.size);
+                }
+                else {
+                    strncpy(temporary_buffer,
+                            value->via.str.ptr,
+                            sizeof(temporary_buffer) - 1);
+                }
+
+                result = flb_log_event_encoder_append_double(
+                            encoder,
+                            target_field,
+                            strtod(temporary_buffer, NULL));
+            }
+            else {
+                unwrap_value = FLB_TRUE;
+            }
+        }
🧹 Nitpick comments (5)
tests/internal/data/opentelemetry/test_cases.json (1)

1258-1280: Add doubleValue-as-string and negative intValue-as-string cases.

To fully cover this PR’s goal, please add:

  • resource attribute with {"doubleValue":"3.14"} → expected 3.14
  • resource attribute with {"intValue":"-2"} → expected -2

Apply this minimal fixture extension:

@@
   "resource_attribute_intvalue_string": {
@@
     }
   },
+  "resource_attribute_doublevalue_string": {
+    "input": {
+      "resourceLogs": [{
+        "resource": {
+          "attributes": [
+            {"key": "resourceThreshold", "value": {"doubleValue": "3.14"}}
+          ]
+        },
+        "scopeLogs": [{
+          "logRecords": [{
+            "timeUnixNano": "1640995200000000000",
+            "body": {"stringValue": "test log"}
+          }]
+        }]
+      }]
+    },
+    "expected": {
+      "group_metadata": {"schema":"otlp","resource_id":0,"scope_id":0},
+      "group_body": {"resource":{"attributes":{"resourceThreshold":3.14}}},
+      "log_metadata": {"otlp":{}},
+      "log_body": {"log": "test log"}
+    }
+  },
+  "resource_attribute_intvalue_string_negative": {
+    "input": {
+      "resourceLogs": [{
+        "resource": {
+          "attributes": [
+            {"key": "resourceVersion", "value": {"intValue": "-2"}}
+          ]
+        },
+        "scopeLogs": [{
+          "logRecords": [{
+            "timeUnixNano": "1640995200000000000",
+            "body": {"stringValue": "test log"}
+          }]
+        }]
+      }]
+    },
+    "expected": {
+      "group_metadata": {"schema":"otlp","resource_id":0,"scope_id":0},
+      "group_body": {"resource":{"attributes":{"resourceVersion":-2}}},
+      "log_metadata": {"otlp":{}},
+      "log_body": {"log": "test log"}
+    }
+  },
src/opentelemetry/flb_opentelemetry_utils.c (1)

301-323: Consider stricter validation for integer strings.

Current strtoll() usage accepts prefixes like "123abc". If you need tighter conformance, parse with endptr and ensure full consumption.

-                result = flb_log_event_encoder_append_int64(
+                char *endp = NULL;
+                long long parsed = strtoll(temporary_buffer, &endp, 10);
+                if (endp == temporary_buffer || *endp != '\0') {
+                    /* fall back to original string to avoid silent misparse */
+                    return -2;
+                }
+                result = flb_log_event_encoder_append_int64(
                             encoder,
                             target_field,
-                            strtoll(temporary_buffer, NULL, 10));
+                            (int64_t) parsed);
tests/internal/opentelemetry.c (1)

479-499: Add a symmetric test for doubleValue-as-string.

Covers the broadened acceptance and guards future regressions.

@@ void test_json_payload_get_wrapped_value()
-    msgpack_sbuffer_destroy(&sbuf);
-    msgpack_unpacked_destroy(&up);
+    msgpack_sbuffer_destroy(&sbuf);
+    msgpack_unpacked_destroy(&up);
+
+    /* Test double value provided as a string */
+    msgpack_sbuffer_init(&sbuf);
+    msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);
+
+    msgpack_pack_map(&pck, 1);
+    msgpack_pack_str(&pck, 11);
+    msgpack_pack_str_body(&pck, "doubleValue", 11);
+    msgpack_pack_str(&pck, 4);
+    msgpack_pack_str_body(&pck, "3.14", 4);
+
+    msgpack_unpacked_init(&up);
+    msgpack_unpack_next(&up, sbuf.data, sbuf.size, NULL);
+
+    ret = flb_otel_utils_json_payload_get_wrapped_value(&up.data, &val, &type);
+    TEST_CHECK(ret == 0);
+    TEST_CHECK(type == MSGPACK_OBJECT_FLOAT);
+    TEST_CHECK(val->type == MSGPACK_OBJECT_STR);
+
+    msgpack_sbuffer_destroy(&sbuf);
+    msgpack_unpacked_destroy(&up);
plugins/in_opentelemetry/opentelemetry_traces.c (2)

118-131: Float attribute accepts numeric strings — add minimal validation.

strtod() will parse prefixes (e.g., "3.14xyz"). If stricter behavior is desired, validate with endptr and reject partials.

-            value_double = strtod(value_str, NULL);
+            {
+                char *endp = NULL;
+                value_double = strtod(value_str, &endp);
+                if (endp == value_str || *endp != '\0') {
+                    flb_sds_destroy(value_str);
+                    flb_sds_destroy(key_str);
+                    return -1;
+                }
+            }

96-109: Optional: factor out string→number parsing to a helper.

Avoids duplication and centralizes validation (int64/double). I can provide a small static utility if useful.

Also applies to: 118-131

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a46116d and f701662.

📒 Files selected for processing (4)
  • plugins/in_opentelemetry/opentelemetry_traces.c (1 hunks)
  • src/opentelemetry/flb_opentelemetry_utils.c (1 hunks)
  • tests/internal/data/opentelemetry/test_cases.json (1 hunks)
  • tests/internal/opentelemetry.c (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
plugins/in_opentelemetry/opentelemetry_traces.c (2)
src/flb_sds.c (2)
  • flb_sds_create_len (58-76)
  • flb_sds_destroy (389-399)
lib/ctraces/src/ctr_attributes.c (1)
  • ctr_attributes_set_int64 (68-71)
tests/internal/opentelemetry.c (1)
src/opentelemetry/flb_opentelemetry_utils.c (1)
  • flb_otel_utils_json_payload_get_wrapped_value (75-192)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (29)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_ARROW=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: pr-compile-centos-7
  • GitHub Check: PR - fuzzing test
🔇 Additional comments (4)
tests/internal/data/opentelemetry/test_cases.json (1)

1258-1280: Good regression case for intValue as string.

Covers the resource attribute path and verifies numeric coercion to 1.

src/opentelemetry/flb_opentelemetry_utils.c (1)

114-122: Allowing intValue as string is correct and aligns with OTLP payloads.

tests/internal/opentelemetry.c (1)

479-499: Unit test for intValue-as-string looks good.

plugins/in_opentelemetry/opentelemetry_traces.c (1)

96-109: Nice: integer attribute accepts numeric strings.

Good use of strtoll with i64 fallback when already numeric.

@edsiper edsiper merged commit c74ef23 into master Sep 1, 2025
60 of 62 checks passed
@edsiper edsiper deleted the otel-resource-attributes branch September 1, 2025 19:41
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.

Regression: Fluent-bit does not simplify OTLP JSON attributes

2 participants