10BC0 support write byte[] to bytes_value instead of array_value in TagWriter by JunweiSUN · Pull Request #6534 · open-telemetry/opentelemetry-dotnet · GitHub
[go: up one dir, main page]

Skip to content

Conversation

JunweiSUN
Copy link
Contributor
@JunweiSUN JunweiSUN commented Sep 24, 2025

Design discussion issue #6535

Changes

When writing big byte[] object to the attribute of LogRecord using ProtobufOtlpTagWriter, current implementation of TagWriter will treat byte[] as array_value in the proto schema instead of bytes_value, which brings two major concerns:

  1. The serialization / deserialization speed is slow since we need to iterate each element in the array and set it into the array_value field
  2. The serialized size is bigger, since we have nested structure and TagWriter will cast byte to long.

This PR allows ProtobufOtlpTagWriter to write byte[] as bytes_value directly, which will bring significant performance improvement when writing large byte[] objects.
A minimum benchmark could be found in #6535 .

Merge requirement checklist

  • CONTRIBUTING guidelines followed (license requirements, nullable enabled, static analysis, etc.)
  • Unit tests added/updated
  • Appropriate CHANGELOG.md files updated for non-trivial changes
  • Changes in public API reviewed (if applicable)

Copy link
linux-foundation-easycla bot commented Sep 24, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@github-actions github-actions bot added pkg:OpenTelemetry.Exporter.OpenTelemetryProtocol Issues related to OpenTelemetry.Exporter.OpenTelemetryProtocol NuGet package pkg:OpenTelemetry Issues related to OpenTelemetry NuGet package labels Sep 24, 2025
@JunweiSUN JunweiSUN force-pushed the develop/SupportWriteByteArrayDirectly branch from df532c1 to 13c13ff Compare September 24, 2025 11:44
Copy link
codecov bot commented Sep 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.64%. Comparing base (ff78d06) to head (4afea2d).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #6534      +/-   ##
==========================================
+ Coverage   86.62%   86.64%   +0.01%     
==========================================
  Files         258      258              
  Lines       11878    11888      +10     
==========================================
+ Hits        10289    10300      +11     
+ Misses       1589     1588       -1     
Flag Coverage Δ
unittests-Project-Experimental 86.35% <100.00%> (-0.18%) ⬇️
unittests-Project-Stable 86.53% <100.00%> (-0.03%) ⬇️
unittests-Solution 86.57% <100.00%> (+0.19%) ⬆️
unittests-UnstableCoreLibraries-Experimental 85.87% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...Implementation/Serializer/ProtobufOtlpTagWriter.cs 95.94% <100.00%> (+0.29%) ⬆️
...ol/Implementation/Serializer/ProtobufSerializer.cs 91.50% <100.00%> (+0.42%) ⬆️

... and 3 files with indirect coverage changes

@Kielek
Copy link
Member
Kielek commented Sep 24, 2025

@JunweiSUN, EasyCLA is mandatory, before we can consider your contribution. Could you please sign it?

@JunweiSUN JunweiSUN force-pushed the develop/SupportWriteByteArrayDirectly branch from 13c13ff to 09b7fe5 Compare September 25, 2025 01:57
@JunweiSUN
Copy link
Contributor Author
10000

Thanks @Kielek , I'm new to EasyCLA and I just got approved of CLA by my employer. Could you tell me how to rerun the EasyCLA check? Also I will finish the UT and open a discussion issue later. Thanks a lot!

@Kielek
Copy link
Member
Kielek commented Sep 25, 2025

/easycla

@Kielek
Copy link
Member
Kielek commented Sep 25, 2025

@JunweiSUN, when you are ready, just post message /easycla, like in my previous comment.

@JunweiSUN
Copy link
Contributor Author

/easycla

1 similar comment
@JunweiSUN
Copy link
Contributor Author

/easycla

@JunweiSUN
Copy link
Contributor Author

/easycla

@JunweiSUN JunweiSUN changed the title support write byte array directly support write byte[] to bytes_value instead of array_value in TagWriter Sep 25, 2025
@JunweiSUN
Copy link
Contributor Author
JunweiSUN commented Sep 25, 2025

The PR is ready to review. I will mark the PR as ready for review now.

@JunweiSUN JunweiSUN marked this pull request as ready for review September 25, 2025 11:21
@JunweiSUN JunweiSUN requested a review from a team as a code owner September 25, 2025 11:21
@JunweiSUN JunweiSUN force-pushed the develop/SupportWriteByteArrayDirectly branch from 5832b62 to 6766101 Compare September 25, 2025 11:24
Copy link
@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves the serialization performance of byte arrays in the OpenTelemetry Protocol (OTLP) exporter by writing byte[] objects directly to the bytes_value field instead of treating them as generic arrays that get serialized to array_value.

  • Introduces a new TryWriteByteArrayTag method to the TagWriter base class for specialized byte array handling
  • Implements optimized byte array serialization in ProtobufOtlpTagWriter using the protobuf bytes_value field
  • Updates existing tag writers to provide default implementations that fall back to array handling

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Shared/TagWriter/TagWriter.cs Adds byte array detection and new abstract method for specialized handling
src/Shared/TagWriter/JsonStringArrayTagWriter.cs Provides default implementation that falls back to array handling
src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs Implements optimized byte array serialization using protobuf bytes_value
src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs Adds helper method for writing byte arrays with protobuf tags
test/OpenTelemetry.Tests/Internal/JsonStringArrayTagWriterTests.cs Adds required method implementation to test mock
test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpAttributeTests.cs Updates test to verify byte arrays use bytes_value field
src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md Documents the change

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor
@paulomorgado paulomorgado left a comment

Choose a reason for hiding this comment

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

I would replace all APIs byte[] with ReadOnlySpan<byte>/Span<byte>. At most, have shallow byte[] overloads for backward compatibility marked with ObsoletAttribute.

I have this branch where I played around with that.

@JunweiSUN
Copy link
Contributor Author

Hi @paulomorgado , I think all new APIs in this PR are already using ReadOnlySpan<byte> as your previous comment. Could you explain more about your latest comment? Thanks!

@paulomorgado
Copy link
Contributor

Hi @paulomorgado , I think all new APIs in this PR are already using ReadOnlySpan<byte> as your previous comment. Could you explain more about your latest comment? Thanks!

This should use a Span<byte> instead of a byte[]:

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    internal static int WriteByteArrayWithTag(byte[] buffer, int writePosition, int fieldNumber, ReadOnlySpan<byte> value)
    {
        writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN);
        writePosition = WriteLength(buffer, writePosition, value.Length);
        value.CopyTo(buffer.AsSpan(writePosition));

        writePosition += value.Length;
        return writePosition;
    }

@JunweiSUN
Copy link
Contributor Author

Hi @paulomorgado , buffer is used to store the serialized protobuf message. Currently all existing APIs such as WriteStringWithTag, WriteDoubleWithTag are also using byte[]. If we want to change this, I think we can create a dedicated PR later? @rajkumar-rangaraj What do you think?

@paulomorgado
Copy link
Contributor

Hi @paulomorgado , buffer is used to store the serialized protobuf message. Currently all existing APIs such as WriteStringWithTag, WriteDoubleWithTag are also using byte[]. If we want to change this, I think we can create a dedicated PR later? @rajkumar-rangaraj What do you think?

Isn't this method being added now? Why add to the "problem" instead of adding to the "solution"?

Have a look at my branch.

@JunweiSUN
Copy link
Contributor Author

Hi @paulomorgado , I don't think it's a "problematic" way to keep the behavior of the new API aligned with other existing APIs. If we want to use Span in WriteByteArrayWithTag, since it will call WriteTag and WriteLength which are widely used APIs in the codebase, we must change the parameter type of these two APIs and all of their caller's, which may make this PR too huge and not focus on the issue it want to resolve. What do you think?

@rajkumar-rangaraj
Copy link
Contributor

@JunweiSUN I think the current approach of aligning with existing APIs is fine for now, so following up with a dedicated PR later makes sense. At the same time, I agree with @paulomorgado that we should eventually move toward a more consistent usage of Span to avoid carrying forward limitations.

@rajkumar-rangaraj
Copy link
Contributor

@paulomorgado I reviewed your branch, and it looks good. If you’re okay with it, would you like to create a follow-up PR with it?

@rajkumar-rangaraj rajkumar-rangaraj merged commit b816045 into open-telemetry:main Sep 30, 2025
60 of 61 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg:OpenTelemetry.Exporter.OpenTelemetryProtocol Issues related to OpenTelemetry.Exporter.OpenTelemetryProtocol NuGet package pkg:OpenTelemetry Issues related to OpenTelemetry NuGet package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0