Skip to content

[EXPORTER] Handle OTLP partial success response#4104

Open
RaviTriv wants to merge 38 commits into
open-telemetry:mainfrom
RaviTriv:ravtrive/handle-oltp-partial-success-response
Open

[EXPORTER] Handle OTLP partial success response#4104
RaviTriv wants to merge 38 commits into
open-telemetry:mainfrom
RaviTriv:ravtrive/handle-oltp-partial-success-response

Conversation

@RaviTriv

@RaviTriv RaviTriv commented May 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #1577

Changes

PR to handle partial success responses from OTLP collector. As per the spec it states explicitly to not retry, the proposed solution is to log the rejection count and message.

For significant contributions please make sure you have completed the following items:

  • CHANGELOG.md updated for non-trivial changes
  • Unit tests have been added
  • Changes in public API reviewed

Comment thread exporters/otlp/test/otlp_grpc_exporter_test.cc Outdated
@codecov

codecov Bot commented May 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 61.03896% with 60 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.98%. Comparing base (353fa6b) to head (d1c983c).

Files with missing lines Patch % Lines
exporters/otlp/src/otlp_grpc_client.cc 0.00% 18 Missing ⚠️
exporters/otlp/src/otlp_grpc_exporter.cc 26.67% 11 Missing ⚠️
...xporters/otlp/src/otlp_grpc_log_record_exporter.cc 28.58% 10 Missing ⚠️
exporters/otlp/src/otlp_grpc_metric_exporter.cc 28.58% 10 Missing ⚠️
exporters/otlp/src/otlp_http_client.cc 88.68% 6 Missing ⚠️
...xporters/otlp/src/otlp_http_log_record_exporter.cc 84.62% 2 Missing ⚠️
exporters/otlp/src/otlp_http_metric_exporter.cc 83.34% 2 Missing ⚠️
exporters/otlp/src/otlp_http_exporter.cc 93.34% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4104      +/-   ##
==========================================
+ Coverage   82.91%   82.98%   +0.08%     
==========================================
  Files         406      406              
  Lines       17153    17256     +103     
==========================================
+ Hits        14221    14319      +98     
- Misses       2932     2937       +5     
Files with missing lines Coverage Δ
...de/opentelemetry/exporters/otlp/otlp_http_client.h 100.00% <ø> (ø)
exporters/otlp/src/otlp_http_exporter.cc 99.14% <93.34%> (-0.41%) ⬇️
...xporters/otlp/src/otlp_http_log_record_exporter.cc 98.30% <84.62%> (-0.81%) ⬇️
exporters/otlp/src/otlp_http_metric_exporter.cc 98.35% <83.34%> (-0.79%) ⬇️
exporters/otlp/src/otlp_http_client.cc 70.70% <88.68%> (+3.20%) ⬆️
...xporters/otlp/src/otlp_grpc_log_record_exporter.cc 80.19% <28.58%> (-6.90%) ⬇️
exporters/otlp/src/otlp_grpc_metric_exporter.cc 71.93% <28.58%> (+22.43%) ⬆️
exporters/otlp/src/otlp_grpc_exporter.cc 78.10% <26.67%> (-6.68%) ⬇️
exporters/otlp/src/otlp_grpc_client.cc 70.63% <0.00%> (-0.90%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread exporters/otlp/src/otlp_grpc_exporter.cc Outdated
Comment thread exporters/otlp/src/otlp_grpc_log_record_exporter.cc Outdated
Comment thread exporters/otlp/src/otlp_http_client.cc
Comment thread exporters/otlp/src/otlp_http_metric_exporter.cc Outdated
@RaviTriv RaviTriv marked this pull request as ready for review May 27, 2026 21:14
@RaviTriv RaviTriv requested a review from a team as a code owner May 27, 2026 21:14
Comment thread exporters/otlp/src/otlp_http_client.cc Outdated
if (result_callback_)
{
result_callback_(result);
result_callback_(result, response_);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this ordering is risky. response_ is owned by the arena stored in the session data, but ReleaseSession() moves that session data to the cleanup list before the callback reads response_. In async HTTP export, another thread could clean up the session and destroy the arena before this callback uses the response. Can we run the callback while the session still owns the arena, or otherwise keep the arena alive through the callback?

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.

Good catch, reordered so that the callback runs before the ReleaseSession() to ensure that the response_ is valid when the callback runs.

Comment thread exporters/otlp/src/otlp_http_client.cc Outdated
// On 2xx, parse the body into the caller-provided typed response
if (response_ != nullptr && result == sdk::common::ExportResult::kSuccess)
{
if (!response_->ParseFromString(body_))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This only handles binary protobuf responses. For OTLP/HTTP JSON mode, the server should send the response as JSON too, so ParseFromString() will fail and the partial_success response will be missed. Can we parse based on options_.content_type, and add a JSON response test as well?

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.

Thanks for pointing this out! Updated to parse based on the the content_type and added corresponding tests

Copilot AI 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.

Pull request overview

Implements OTLP “partial success” handling across HTTP and gRPC exporters by parsing Export*ServiceResponse and emitting a log that includes the rejected item count and server-provided error message (per spec guidance to not retry on partial success).

Changes:

  • Extend OTLP HTTP client/exporters to deserialize successful 2xx responses into typed protobuf responses (binary + JSON) and log partial success details.
  • Add partial-success logging to OTLP gRPC exporters (sync + async paths) via an on_complete hook in DelegateExport.
  • Add test infrastructure (ScopedTestLogHandler) and expand exporter tests to assert partial-success logging for HTTP/gRPC + JSON/proto.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test_common/include/opentelemetry/test_common/sdk/common/scoped_test_log_handler.h Adds reusable scoped log handler for tests to capture internal logs.
sdk/test/metrics/meter_provider_sdk_test.cc Switches test to use shared ScopedTestLogHandler helper.
sdk/test/metrics/CMakeLists.txt Links metrics tests with opentelemetry_test_common for the new test helper header.
sdk/test/metrics/BUILD Adds Bazel dependency on //test_common:headers for the new test helper header.
exporters/otlp/test/otlp_http_metric_exporter_test.cc Adds HTTP metric exporter partial-success tests (proto + JSON) and log assertions.
exporters/otlp/test/otlp_http_log_record_exporter_test.cc Adds HTTP log exporter partial-success tests (proto + JSON) and log assertions.
exporters/otlp/test/otlp_http_exporter_test.cc Adds HTTP trace exporter partial-success tests (proto + JSON) and log assertions.
exporters/otlp/test/otlp_grpc_metric_exporter_test.cc Adds gRPC metric exporter partial-success test and log assertions.
exporters/otlp/test/otlp_grpc_log_record_exporter_test.cc Adds gRPC log exporter partial-success test and log assertions.
exporters/otlp/test/otlp_grpc_exporter_test.cc Adds gRPC trace exporter partial-success test and log assertions.
exporters/otlp/src/otlp_http_metric_exporter.cc Allocates response on arena and logs partial success from parsed HTTP response.
exporters/otlp/src/otlp_http_log_record_exporter.cc Allocates response on arena and logs partial success from parsed HTTP response.
exporters/otlp/src/otlp_http_exporter.cc Allocates response on arena and logs partial success from parsed HTTP response.
exporters/otlp/src/otlp_http_client.cc Parses successful HTTP response bodies into a caller-provided protobuf message (JSON/proto) and forwards it to callbacks while keeping arena alive.
exporters/otlp/src/otlp_grpc_metric_exporter.cc Logs partial success for gRPC metrics responses in async and sync code paths.
exporters/otlp/src/otlp_grpc_log_record_exporter.cc Logs partial success for gRPC logs responses in async and sync code paths.
exporters/otlp/src/otlp_grpc_exporter.cc Logs partial success for gRPC trace responses; routes success logging through completion hook.
exporters/otlp/src/otlp_grpc_client.cc Adds an optional on_complete callback to DelegateExport to inspect response on success while keeping arena alive.
exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h Adds typed-response async export overload and extends session data to retain arena/response lifetime.
exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_client.h Adds optional on_complete callback to sync DelegateExport overloads.
exporters/otlp/CMakeLists.txt Links OTLP exporter tests with opentelemetry_test_common for the shared log handler helper.
exporters/otlp/BUILD Adds protobuf dependency and //test_common:headers deps needed by updated tests.
CHANGELOG.md Adds changelog entry for OTLP partial success handling.

Comment thread exporters/otlp/test/otlp_http_metric_exporter_test.cc Outdated
Comment thread exporters/otlp/test/otlp_http_exporter_test.cc Outdated
Comment thread exporters/otlp/test/otlp_http_log_record_exporter_test.cc Outdated
Comment thread exporters/otlp/test/otlp_grpc_exporter_test.cc Outdated
Comment thread exporters/otlp/test/otlp_grpc_metric_exporter_test.cc Outdated
{
if (content_type_ == HttpRequestContentType::kJson)
{
if (!google::protobuf::util::JsonStringToMessage(body_, response_).ok())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we avoid treating this as a success if parsing the response body fails? Right now we only log the parse error, so the exporter may still continue with an empty response and miss partial_success.

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.

Yep, updated to set the result as kFailure on parse fail

@RaviTriv RaviTriv force-pushed the ravtrive/handle-oltp-partial-success-response branch 4 times, most recently from 62795e6 to b24d27e Compare June 8, 2026 00:06
return opentelemetry::sdk::common::ExportResult::kFailure;
}

return opentelemetry::sdk::common::ExportResult::kSuccess;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we return the final callback result here instead of always returning success? OnResponse() now changes the result to kFailure when parsing the response body fails, but this path still returns kSuccess as long as the wait completed. That means sync HTTP export can log a parse failure but still report success to the caller

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.

good catch! definitely, updated the sync path to return kFailure if parse fails.

Comment thread exporters/otlp/src/otlp_http_exporter.cc Outdated
Comment thread exporters/otlp/src/otlp_http_log_record_exporter.cc Outdated
Comment thread exporters/otlp/src/otlp_http_client.cc Outdated
@RaviTriv RaviTriv force-pushed the ravtrive/handle-oltp-partial-success-response branch from d7540b8 to 76ec719 Compare June 9, 2026 23:08
@RaviTriv RaviTriv force-pushed the ravtrive/handle-oltp-partial-success-response branch from 76ec719 to cf2e36a Compare June 10, 2026 10:20

Copilot AI 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.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.

Comment thread exporters/otlp/src/otlp_http_client.cc Outdated
Comment thread exporters/otlp/src/otlp_http_client.cc

@owent owent left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM. thanks.

@marcalff

Copy link
Copy Markdown
Member

LGTM, but the real expert in this area is @owent , trusting his review.

@lalitb Since you looked at this PR already, do you have any remaining comments ?

Ok to merge ?

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.

Handle partial success responses from OTLP export services

5 participants