Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
53f3617
Implement EventToSpanEventBridge log record processor
om7057 Jul 26, 2026
bbb273f
Point changelog entry at the actual PR number
om7057 Jul 26, 2026
c8e67dc
Fix CI failures: RTTI-free cast and unrelated formatting drift
om7057 Jul 26, 2026
46fab04
Fix clang-tidy and iwyu findings on the new processor
om7057 Jul 26, 2026
41f9b89
Fix iwyu: include event_to_span_event_bridge configuration header dir…
om7057 Jul 26, 2026
ee5769b
refactor(logs): add OnEmitWithContext to LogRecordProcessor API
om7057 Jul 28, 2026
caf5e60
feat(logs): implement EventToSpanEventBridge with resolved context su…
om7057 Jul 28, 2026
ec30ecb
fix: add missing includes for OnEmitWithContext
om7057 Jul 29, 2026
fb33661
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Jul 30, 2026
a6ecfda
Address review: fix explicit-context bridging, gate context resolutio…
om7057 Jul 30, 2026
af2e49c
Fix Doxygen lint: name the OnEmitWithContext context parameter
om7057 Jul 30, 2026
01009bb
Fix iwyu findings from the review-response commit
om7057 Jul 30, 2026
7cccee7
Fix clang-tidy and iwyu findings on the new processor
om7057 Jul 31, 2026
0921a9c
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Jul 31, 2026
58f60f7
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 1, 2026
8f94856
Trigger CI re-run
om7057 Aug 2, 2026
3990431
Merge branch 'main' into fix/event-to-span-event-bridge-config
om7057 Aug 2, 2026
1f1ced6
Trigger CI re-run
om7057 Aug 2, 2026
dd1cb0e
Trigger CI re-run
om7057 Aug 2, 2026
1bbb8bf
Merge branch 'main' into fix/event-to-span-event-bridge-config
om7057 Aug 2, 2026
fb2d1db
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 4, 2026
7e1481f
Merge branch 'main' into fix/event-to-span-event-bridge-config
om7057 Aug 5, 2026
c687576
Merge branch 'main' into fix/event-to-span-event-bridge-config
om7057 Aug 5, 2026
727bc55
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 6, 2026
9bf4d53
Merge branch 'main' into fix/event-to-span-event-bridge-config
om7057 Aug 6, 2026
ac1b1c5
Retrigger CI (Windows jobs hit a vcpkg benchmark build flake then got…
om7057 Aug 7, 2026
a4b70b3
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 7, 2026
060849e
Merge branch 'main' into fix/event-to-span-event-bridge-config
dbarker Aug 7, 2026
5ed1c36
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 10, 2026
8097f04
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 11, 2026
7696c6b
Carry the resolved context through Logger::EmitLogRecord() end-to-end
om7057 Aug 11, 2026
5f7d98e
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 12, 2026
d1deb5a
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 12, 2026
9222337
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 13, 2026
6e727f5
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 13, 2026
bede0b5
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 17, 2026
2f8c5c2
Reduce scope to just the configuration model and YAML parser
om7057 Aug 19, 2026
63bc911
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 19, 2026
80333dd
Address review: make visitor method pure virtual, trim comment/changelog
om7057 Aug 20, 2026
ef57f7f
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Aug 20, 2026
7248930
Merge branch 'main' into fix/event-to-span-event-bridge-config
dbarker Sep 3, 2026
147324a
Merge branch 'main' into fix/event-to-span-event-bridge-config
dbarker Sep 4, 2026
0003bd4
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Sep 4, 2026
2f5951c
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Sep 10, 2026
98732f2
Merge branch 'main' into fix/event-to-span-event-bridge-config
om7057 Sep 15, 2026
54fb9fc
Fix include order in logs_builder_utils.cc
om7057 Sep 16, 2026
46a7f09
Merge branch 'main' into fix/event-to-span-event-bridge-config
om7057 Sep 16, 2026
cb1f08e
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Sep 24, 2026
f356314
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Oct 5, 2026
4df009b
Remove extra blank line in changelog
om7057 Oct 5, 2026
dd0773d
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Oct 18, 2026
e0eda64
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Oct 23, 2026
fd4b5e5
Merge remote-tracking branch 'origin/main' into fix/event-to-span-eve…
om7057 Oct 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ Increment the:

## [Unreleased]

* [CONFIGURATION] Parse the `event_to_span_event_bridge/development` log
record processor configuration in declarative configuration. The SDK
implementation of this processor is not yet available; `SdkBuilder` logs a
warning and skips it when configured.
[#4309](https://github.com/open-telemetry/opentelemetry-cpp/pull/4309)

* [SDK] Clamp `BatchSpanProcessor` max_export_batch_size to max_queue_size,
so a larger value no longer stops spans from being exported until the
schedule delay expires.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "opentelemetry/sdk/configuration/double_array_attribute_value_configuration.h"
#include "opentelemetry/sdk/configuration/double_attribute_value_configuration.h"
#include "opentelemetry/sdk/configuration/drop_aggregation_configuration.h"
#include "opentelemetry/sdk/configuration/event_to_span_event_bridge_log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/exemplar_filter.h"
#include "opentelemetry/sdk/configuration/explicit_bucket_histogram_aggregation_configuration.h"
#include "opentelemetry/sdk/configuration/extension_composable_sampler_configuration.h"
Expand Down Expand Up @@ -171,6 +172,10 @@ class ConfigurationParser
std::unique_ptr<SimpleLogRecordProcessorConfiguration> ParseSimpleLogRecordProcessorConfiguration(
const std::unique_ptr<DocumentNode> &node) const;

std::unique_ptr<EventToSpanEventBridgeLogRecordProcessorConfiguration>
ParseEventToSpanEventBridgeLogRecordProcessorConfiguration(
const std::unique_ptr<DocumentNode> &node) const;

std::unique_ptr<ExtensionLogRecordProcessorConfiguration>
ParseExtensionLogRecordProcessorConfiguration(const std::string &name,
std::unique_ptr<DocumentNode> node) const;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "opentelemetry/sdk/configuration/log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/log_record_processor_configuration_visitor.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace configuration
{

// YAML-SCHEMA: schema/logger_provider.json
// YAML-NODE: ExperimentalEventToSpanEventBridgeLogRecordProcessor
class EventToSpanEventBridgeLogRecordProcessorConfiguration : public LogRecordProcessorConfiguration
{
public:
void Accept(LogRecordProcessorConfigurationVisitor *visitor) const override
{
visitor->VisitEventToSpanEventBridge(this);
}
};

} // namespace configuration
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace configuration

class BatchLogRecordProcessorConfiguration;
class SimpleLogRecordProcessorConfiguration;
class EventToSpanEventBridgeLogRecordProcessorConfiguration;
class ExtensionLogRecordProcessorConfiguration;

class LogRecordProcessorConfigurationVisitor
Expand All @@ -27,8 +28,10 @@ class LogRecordProcessorConfigurationVisitor
const LogRecordProcessorConfigurationVisitor &other) = default;
virtual ~LogRecordProcessorConfigurationVisitor() = default;

virtual void VisitBatch(const BatchLogRecordProcessorConfiguration *model) = 0;
virtual void VisitSimple(const SimpleLogRecordProcessorConfiguration *model) = 0;
virtual void VisitBatch(const BatchLogRecordProcessorConfiguration *model) = 0;
virtual void VisitSimple(const SimpleLogRecordProcessorConfiguration *model) = 0;
virtual void VisitEventToSpanEventBridge(
const EventToSpanEventBridgeLogRecordProcessorConfiguration *model) = 0;
virtual void VisitExtension(const ExtensionLogRecordProcessorConfiguration *model) = 0;
};

Expand Down
12 changes: 12 additions & 0 deletions sdk/src/configuration/configuration_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "opentelemetry/sdk/configuration/double_array_attribute_value_configuration.h"
#include "opentelemetry/sdk/configuration/double_attribute_value_configuration.h"
#include "opentelemetry/sdk/configuration/drop_aggregation_configuration.h"
#include "opentelemetry/sdk/configuration/event_to_span_event_bridge_log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/exemplar_filter.h"
#include "opentelemetry/sdk/configuration/explicit_bucket_histogram_aggregation_configuration.h"
#include "opentelemetry/sdk/configuration/extension_composable_sampler_configuration.h"
Expand Down Expand Up @@ -612,6 +613,13 @@ ConfigurationParser::ParseSimpleLogRecordProcessorConfiguration(
return model;
}

std::unique_ptr<EventToSpanEventBridgeLogRecordProcessorConfiguration>
ConfigurationParser::ParseEventToSpanEventBridgeLogRecordProcessorConfiguration(
const std::unique_ptr<DocumentNode> & /* node */) const
{
return std::make_unique<EventToSpanEventBridgeLogRecordProcessorConfiguration>();
}

std::unique_ptr<ExtensionLogRecordProcessorConfiguration>
ConfigurationParser::ParseExtensionLogRecordProcessorConfiguration(
const std::string &name,
Expand Down Expand Up @@ -657,6 +665,10 @@ ConfigurationParser::ParseLogRecordProcessorConfiguration(
{
model = ParseSimpleLogRecordProcessorConfiguration(child);
}
else if (name == "event_to_span_event_bridge/development")
{
model = ParseEventToSpanEventBridgeLogRecordProcessorConfiguration(child);
}
else
{
model = ParseExtensionLogRecordProcessorConfiguration(name, std::move(child));
Expand Down
20 changes: 20 additions & 0 deletions sdk/src/configuration/logs_builder_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "opentelemetry/sdk/configuration/batch_log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/console_log_record_exporter_builder.h"
#include "opentelemetry/sdk/configuration/console_log_record_exporter_configuration.h"
#include "opentelemetry/sdk/configuration/event_to_span_event_bridge_log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/extension_log_record_exporter_builder.h"
#include "opentelemetry/sdk/configuration/extension_log_record_exporter_configuration.h"
#include "opentelemetry/sdk/configuration/extension_log_record_processor_builder.h"
Expand Down Expand Up @@ -172,6 +173,18 @@ class LogRecordExporterDispatcher
const Registry *registry_;
};

static std::unique_ptr<opentelemetry::sdk::logs::LogRecordProcessor>
CreateEventToSpanEventBridgeLogRecordProcessor(
const opentelemetry::sdk::configuration::EventToSpanEventBridgeLogRecordProcessorConfiguration
* /* model */)
{
// FIXME-SDK: not yet implemented.
// https://github.com/open-telemetry/opentelemetry-cpp/issues/4454
OTEL_INTERNAL_LOG_WARN(
"event_to_span_event_bridge/development processor is not yet supported, ignoring");
return nullptr;
}

static std::unique_ptr<opentelemetry::sdk::logs::LogRecordProcessor>
CreateExtensionLogRecordProcessor(
const Registry *registry,
Expand Down Expand Up @@ -233,6 +246,13 @@ class LogRecordProcessorDispatcher
throw UnsupportedException(message);
}

void VisitEventToSpanEventBridge(
const opentelemetry::sdk::configuration::EventToSpanEventBridgeLogRecordProcessorConfiguration
*model) override
{
processor = CreateEventToSpanEventBridgeLogRecordProcessor(model);
}

void VisitExtension(
const opentelemetry::sdk::configuration::ExtensionLogRecordProcessorConfiguration *model)
override
Expand Down
1 change: 1 addition & 0 deletions sdk/test/configuration/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ cc_test(
"//sdk:headers",
"//sdk/src/configuration:configuration_logs_builders",
"//sdk/src/logs",
"//test_common:headers",
"@com_google_googletest//:gtest_main",
],
)
Expand Down
2 changes: 1 addition & 1 deletion sdk/test/configuration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ target_link_libraries(
logs_builders_test
PRIVATE ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}
opentelemetry_configuration_logs_builders
opentelemetry_configuration_core)
opentelemetry_configuration_core opentelemetry_test_common)
gtest_add_tests(
TARGET logs_builders_test
TEST_PREFIX config.
Expand Down
25 changes: 25 additions & 0 deletions sdk/test/configuration/logs_builders_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
#include "opentelemetry/logs/provider.h"
#include "opentelemetry/logs/severity.h"

#include "opentelemetry/sdk/common/global_log_handler.h"
#include "opentelemetry/sdk/configuration/batch_log_record_processor_builder.h"
#include "opentelemetry/sdk/configuration/batch_log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/configuration.h"
#include "opentelemetry/sdk/configuration/configured_sdk.h"
#include "opentelemetry/sdk/configuration/console_log_record_exporter_builder.h"
#include "opentelemetry/sdk/configuration/console_log_record_exporter_configuration.h"
#include "opentelemetry/sdk/configuration/event_to_span_event_bridge_log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/extension_log_record_exporter_builder.h"
#include "opentelemetry/sdk/configuration/extension_log_record_exporter_configuration.h"
#include "opentelemetry/sdk/configuration/extension_log_record_processor_builder.h"
Expand Down Expand Up @@ -50,6 +52,7 @@
#include "opentelemetry/sdk/logs/logger_config.h"
#include "opentelemetry/sdk/logs/logger_provider.h"
#include "opentelemetry/sdk/logs/processor.h"
#include "opentelemetry/test_common/sdk/common/scoped_test_log_handler.h"

#include "config_test_logs.h"

Expand Down Expand Up @@ -236,6 +239,28 @@ TEST_F(LogsBuildersTest, CreateSimpleLogRecordProcessor)
EXPECT_NE(result, nullptr);
}

// The event_to_span_event_bridge/development processor has no SDK implementation yet (see
// https://github.com/open-telemetry/opentelemetry-cpp/issues/4454): SdkBuilder should log a
// warning and skip it rather than build a processor, so a pipeline like
// [event_to_span_event_bridge, batch] just runs batch instead of failing or crashing.
TEST_F(LogsBuildersTest, CreateEventToSpanEventBridgeLogRecordProcessorWarnsAndSkips)
{
opentelemetry::test_common::ScopedTestLogHandler log_handler{
opentelemetry::sdk::common::internal_log::LogLevel::Warning};

std::unique_ptr<config_sdk::LogRecordProcessorConfiguration> model =
std::make_unique<config_sdk::EventToSpanEventBridgeLogRecordProcessorConfiguration>();

auto result = MakeLogRecordProcessor(std::move(model));

EXPECT_EQ(result, nullptr);

auto entries = log_handler.Drain();
ASSERT_EQ(entries.size(), 1U);
EXPECT_EQ(entries[0].level, opentelemetry::sdk::common::internal_log::LogLevel::Warning);
EXPECT_NE(entries[0].msg.find("event_to_span_event_bridge"), std::string::npos);
}

TEST_F(LogsBuildersTest, UnregisteredLoggerConfigurator)
{
registry_->SetLoggerConfiguratorBuilder(nullptr);
Expand Down
97 changes: 97 additions & 0 deletions sdk/test/configuration/yaml_logs_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "opentelemetry/sdk/configuration/headers_configuration.h"
#include "opentelemetry/sdk/configuration/http_tls_configuration.h"
#include "opentelemetry/sdk/configuration/log_record_limits_configuration.h"
#include "opentelemetry/sdk/configuration/log_record_processor_configuration.h"
#include "opentelemetry/sdk/configuration/log_record_processor_configuration_visitor.h"
#include "opentelemetry/sdk/configuration/logger_config_configuration.h"
#include "opentelemetry/sdk/configuration/logger_configurator_configuration.h"
#include "opentelemetry/sdk/configuration/logger_matcher_and_config_configuration.h"
Expand Down Expand Up @@ -109,6 +111,101 @@ file_format: "1.0-logs"
ASSERT_NE(exporter, nullptr);
}

namespace
{

// Records which LogRecordProcessorConfigurationVisitor callback a parsed model dispatches to.
// The bridge configuration carries no properties of its own, so there is no parsed field to
// assert on; dispatching through Accept() is what actually proves the YAML key selected the
// bridge configuration rather than falling through to the extension configuration. This also
// avoids needing RTTI.
class RecordingLogRecordProcessorVisitor final
: public opentelemetry::sdk::configuration::LogRecordProcessorConfigurationVisitor
{
public:
void VisitBatch(
const opentelemetry::sdk::configuration::BatchLogRecordProcessorConfiguration *) override
{
++batch_count;
}

void VisitSimple(
const opentelemetry::sdk::configuration::SimpleLogRecordProcessorConfiguration *) override
{
++simple_count;
}

void VisitEventToSpanEventBridge(
const opentelemetry::sdk::configuration::EventToSpanEventBridgeLogRecordProcessorConfiguration
*) override
{
++bridge_count;
}

void VisitExtension(
const opentelemetry::sdk::configuration::ExtensionLogRecordProcessorConfiguration *) override
{
++extension_count;
}

int batch_count{0};
int simple_count{0};
int bridge_count{0};
int extension_count{0};
};

} // namespace

TEST(YamlLogs, event_to_span_event_bridge_processor)
{
std::string yaml = R"(
file_format: "1.0-logs"
logger_provider:
processors:
- event_to_span_event_bridge/development:
)";

auto config = DoParse(yaml);
ASSERT_NE(config, nullptr);
ASSERT_NE(config->logger_provider, nullptr);
ASSERT_EQ(config->logger_provider->processors.size(), 1);
auto *processor = config->logger_provider->processors[0].get();
ASSERT_NE(processor, nullptr);

RecordingLogRecordProcessorVisitor visitor;
processor->Accept(&visitor);

EXPECT_EQ(visitor.bridge_count, 1);
EXPECT_EQ(visitor.extension_count, 0);
EXPECT_EQ(visitor.batch_count, 0);
EXPECT_EQ(visitor.simple_count, 0);
}

TEST(YamlLogs, event_to_span_event_bridge_processor_misspelled_key_is_not_the_bridge)
{
// A misspelled key falls through to the extension processor configuration. Guards against the
// bridge assertion above passing for a model that is not actually the bridge.
std::string yaml = R"(
file_format: "1.0-logs"
logger_provider:
processors:
- event_to_span_event_brige/development:
)";

auto config = DoParse(yaml);
ASSERT_NE(config, nullptr);
ASSERT_NE(config->logger_provider, nullptr);
ASSERT_EQ(config->logger_provider->processors.size(), 1);
auto *processor = config->logger_provider->processors[0].get();
ASSERT_NE(processor, nullptr);

RecordingLogRecordProcessorVisitor visitor;
processor->Accept(&visitor);

EXPECT_EQ(visitor.bridge_count, 0);
EXPECT_EQ(visitor.extension_count, 1);
}

TEST(YamlLogs, default_batch_processor)
{
std::string yaml = R"(
Expand Down
Loading