From d6341b45cb16a20f2615876a3ce0a22be03ec07c Mon Sep 17 00:00:00 2001 From: Nandan Date: Wed, 26 Aug 2026 06:30:41 +0530 Subject: [PATCH] feat: support general attribute limits --- .../attribute_limits_configuration.h | 3 + .../log_record_limits_configuration.h | 3 + .../sdk/configuration/sdk_builder.h | 8 +- .../configuration/span_limits_configuration.h | 3 + sdk/src/configuration/configuration_parser.cc | 45 ++++ sdk/src/configuration/sdk_builder.cc | 73 ++++-- .../programmatic_configuration_test.cc | 234 ++++++++++++++++++ sdk/test/configuration/sdk_builder_test.cc | 170 +++++++++++++ sdk/test/configuration/yaml_logs_test.cc | 72 ++++++ sdk/test/configuration/yaml_test.cc | 54 ++++ sdk/test/configuration/yaml_trace_test.cc | 72 ++++++ 11 files changed, 716 insertions(+), 21 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h b/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h index 755069ea0..f02e12816 100644 --- a/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h +++ b/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h @@ -23,6 +23,9 @@ class AttributeLimitsConfiguration (std::numeric_limits::max)(); static constexpr std::size_t kDefaultAttributeCountLimit = 128; + bool has_attribute_value_length_limit{false}; + bool has_attribute_count_limit{false}; + std::size_t attribute_value_length_limit{kDefaultAttributeValueLengthLimit}; std::size_t attribute_count_limit{kDefaultAttributeCountLimit}; }; diff --git a/sdk/include/opentelemetry/sdk/configuration/log_record_limits_configuration.h b/sdk/include/opentelemetry/sdk/configuration/log_record_limits_configuration.h index 64bf93242..0bd8ff889 100644 --- a/sdk/include/opentelemetry/sdk/configuration/log_record_limits_configuration.h +++ b/sdk/include/opentelemetry/sdk/configuration/log_record_limits_configuration.h @@ -23,6 +23,9 @@ class LogRecordLimitsConfiguration (std::numeric_limits::max)(); static constexpr std::size_t kDefaultAttributeCountLimit = 128; + bool has_attribute_value_length_limit{false}; + bool has_attribute_count_limit{false}; + std::size_t attribute_value_length_limit{kDefaultAttributeValueLengthLimit}; std::size_t attribute_count_limit{kDefaultAttributeCountLimit}; }; diff --git a/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h b/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h index 637756bb3..fe2c12a42 100644 --- a/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h +++ b/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h @@ -161,7 +161,9 @@ class SdkBuilder std::unique_ptr CreateTracerProvider( const std::unique_ptr &model, - const opentelemetry::sdk::resource::Resource &resource) const; + const opentelemetry::sdk::resource::Resource &resource, + const opentelemetry::sdk::configuration::AttributeLimitsConfiguration *attribute_limits = + nullptr) const; std::unique_ptr CreateTextMapPropagator( const std::string &name) const; @@ -286,7 +288,9 @@ class SdkBuilder std::unique_ptr CreateLoggerProvider( const std::unique_ptr &model, - const opentelemetry::sdk::resource::Resource &resource) const; + const opentelemetry::sdk::resource::Resource &resource, + const opentelemetry::sdk::configuration::AttributeLimitsConfiguration *attribute_limits = + nullptr) const; std::unique_ptr CreateContainerResourceDetector( const opentelemetry::sdk::configuration::ContainerResourceDetectorConfiguration *model) const; diff --git a/sdk/include/opentelemetry/sdk/configuration/span_limits_configuration.h b/sdk/include/opentelemetry/sdk/configuration/span_limits_configuration.h index db0e4ca72..e27ffb880 100644 --- a/sdk/include/opentelemetry/sdk/configuration/span_limits_configuration.h +++ b/sdk/include/opentelemetry/sdk/configuration/span_limits_configuration.h @@ -27,6 +27,9 @@ class SpanLimitsConfiguration static constexpr std::uint32_t kDefaultEventAttributeCountLimit = 128; static constexpr std::uint32_t kDefaultLinkAttributeCountLimit = 128; + bool has_attribute_value_length_limit{false}; + bool has_attribute_count_limit{false}; + std::size_t attribute_value_length_limit{kDefaultAttributeValueLengthLimit}; std::uint32_t attribute_count_limit{kDefaultAttributeCountLimit}; std::uint32_t event_count_limit{kDefaultEventCountLimit}; diff --git a/sdk/src/configuration/configuration_parser.cc b/sdk/src/configuration/configuration_parser.cc index 3d2dab661..13180950b 100644 --- a/sdk/src/configuration/configuration_parser.cc +++ b/sdk/src/configuration/configuration_parser.cc @@ -363,6 +363,21 @@ ConfigurationParser::ParseAttributeLimitsConfiguration( using Config = AttributeLimitsConfiguration; auto model = std::make_unique(); + if (auto child = node->GetChildNode("attribute_value_length_limit")) + { + if (!child->IsNull()) + { + model->has_attribute_value_length_limit = true; + } + } + if (auto child = node->GetChildNode("attribute_count_limit")) + { + if (!child->IsNull()) + { + model->has_attribute_count_limit = true; + } + } + model->attribute_value_length_limit = node->GetInteger("attribute_value_length_limit", Config::kDefaultAttributeValueLengthLimit); model->attribute_count_limit = @@ -643,6 +658,21 @@ ConfigurationParser::ParseLogRecordLimitsConfiguration( using Config = LogRecordLimitsConfiguration; auto model = std::make_unique(); + if (auto child = node->GetChildNode("attribute_value_length_limit")) + { + if (!child->IsNull()) + { + model->has_attribute_value_length_limit = true; + } + } + if (auto child = node->GetChildNode("attribute_count_limit")) + { + if (!child->IsNull()) + { + model->has_attribute_count_limit = true; + } + } + model->attribute_value_length_limit = node->GetInteger("attribute_value_length_limit", Config::kDefaultAttributeValueLengthLimit); model->attribute_count_limit = @@ -1686,6 +1716,21 @@ std::unique_ptr ConfigurationParser::ParseSpanLimitsCon return static_cast(value); }; + if (auto child = node->GetChildNode("attribute_value_length_limit")) + { + if (!child->IsNull()) + { + model->has_attribute_value_length_limit = true; + } + } + if (auto child = node->GetChildNode("attribute_count_limit")) + { + if (!child->IsNull()) + { + model->has_attribute_count_limit = true; + } + } + model->attribute_value_length_limit = node->GetInteger("attribute_value_length_limit", Config::kDefaultAttributeValueLengthLimit); model->attribute_count_limit = diff --git a/sdk/src/configuration/sdk_builder.cc b/sdk/src/configuration/sdk_builder.cc index 39d959a23..c618caab0 100644 --- a/sdk/src/configuration/sdk_builder.cc +++ b/sdk/src/configuration/sdk_builder.cc @@ -1423,7 +1423,8 @@ SdkBuilder::CreateTracerConfigurator( std::unique_ptr SdkBuilder::CreateTracerProvider( const std::unique_ptr &model, - const opentelemetry::sdk::resource::Resource &resource) const + const opentelemetry::sdk::resource::Resource &resource, + const opentelemetry::sdk::configuration::AttributeLimitsConfiguration *attribute_limits) const { std::unique_ptr sdk; @@ -1451,14 +1452,33 @@ std::unique_ptr SdkBuilder::CreateTra } opentelemetry::sdk::trace::SpanLimits span_limits; + if (attribute_limits) + { + if (attribute_limits->has_attribute_value_length_limit || !model->limits) + { + span_limits.attribute_value_length_limit = attribute_limits->attribute_value_length_limit; + } + if (attribute_limits->has_attribute_count_limit || !model->limits) + { + span_limits.attribute_count_limit = + static_cast(attribute_limits->attribute_count_limit); + } + } + if (model->limits) { - span_limits.attribute_value_length_limit = model->limits->attribute_value_length_limit; - span_limits.attribute_count_limit = model->limits->attribute_count_limit; - span_limits.event_count_limit = model->limits->event_count_limit; - span_limits.link_count_limit = model->limits->link_count_limit; - span_limits.event_attribute_count_limit = model->limits->event_attribute_count_limit; - span_limits.link_attribute_count_limit = model->limits->link_attribute_count_limit; + if (model->limits->has_attribute_value_length_limit || !attribute_limits) + { + span_limits.attribute_value_length_limit = model->limits->attribute_value_length_limit; + } + if (model->limits->has_attribute_count_limit || !attribute_limits) + { + span_limits.attribute_count_limit = model->limits->attribute_count_limit; + } + span_limits.event_count_limit = model->limits->event_count_limit; + span_limits.link_count_limit = model->limits->link_count_limit; + span_limits.event_attribute_count_limit = model->limits->event_attribute_count_limit; + span_limits.link_attribute_count_limit = model->limits->link_attribute_count_limit; } if (model->tracer_configurator) @@ -2349,7 +2369,8 @@ SdkBuilder::CreateLoggerConfigurator( std::unique_ptr SdkBuilder::CreateLoggerProvider( const std::unique_ptr &model, - const opentelemetry::sdk::resource::Resource &resource) const + const opentelemetry::sdk::resource::Resource &resource, + const opentelemetry::sdk::configuration::AttributeLimitsConfiguration *attribute_limits) const { std::unique_ptr sdk; @@ -2361,10 +2382,29 @@ std::unique_ptr SdkBuilder::CreateLogg } opentelemetry::sdk::logs::LogRecordLimits log_record_limits; + if (attribute_limits) + { + if (attribute_limits->has_attribute_value_length_limit || !model->limits) + { + log_record_limits.attribute_value_length_limit = + attribute_limits->attribute_value_length_limit; + } + if (attribute_limits->has_attribute_count_limit || !model->limits) + { + log_record_limits.attribute_count_limit = attribute_limits->attribute_count_limit; + } + } + if (model->limits) { - log_record_limits.attribute_value_length_limit = model->limits->attribute_value_length_limit; - log_record_limits.attribute_count_limit = model->limits->attribute_count_limit; + if (model->limits->has_attribute_value_length_limit || !attribute_limits) + { + log_record_limits.attribute_value_length_limit = model->limits->attribute_value_length_limit; + } + if (model->limits->has_attribute_count_limit || !attribute_limits) + { + log_record_limits.attribute_count_limit = model->limits->attribute_count_limit; + } } std::unique_ptr SdkBuilder::CreateConfiguredSdk( { SetResource(sdk->resource, model->resource); - if (model->attribute_limits) - { - // FIXME-SDK: https://github.com/open-telemetry/opentelemetry-cpp/issues/3303 - // FIXME-SDK: Implement attribute limits - OTEL_INTERNAL_LOG_WARN("attribute_limits not supported, ignoring"); - } - if (model->tracer_provider) { - sdk->tracer_provider = CreateTracerProvider(model->tracer_provider, sdk->resource); + sdk->tracer_provider = CreateTracerProvider( + model->tracer_provider, sdk->resource, model->attribute_limits.get()); } if (model->propagator) @@ -2668,7 +2702,8 @@ std::unique_ptr SdkBuilder::CreateConfiguredSdk( if (model->logger_provider) { - sdk->logger_provider = CreateLoggerProvider(model->logger_provider, sdk->resource); + sdk->logger_provider = CreateLoggerProvider( + model->logger_provider, sdk->resource, model->attribute_limits.get()); } } diff --git a/sdk/test/configuration/programmatic_configuration_test.cc b/sdk/test/configuration/programmatic_configuration_test.cc index b57b9fd05..31cfd64c8 100644 --- a/sdk/test/configuration/programmatic_configuration_test.cc +++ b/sdk/test/configuration/programmatic_configuration_test.cc @@ -42,6 +42,7 @@ #include "opentelemetry/sdk/configuration/aggregation_configuration.h" #include "opentelemetry/sdk/configuration/always_off_sampler_configuration.h" +#include "opentelemetry/sdk/configuration/attribute_limits_configuration.h" #include "opentelemetry/sdk/configuration/base2_exponential_bucket_histogram_aggregation_configuration.h" #include "opentelemetry/sdk/configuration/batch_log_record_processor_builder.h" #include "opentelemetry/sdk/configuration/batch_log_record_processor_configuration.h" @@ -333,6 +334,239 @@ TEST_F(ProgrammaticConfigTest, LoggerProviderWithLogRecordLimits) } } +TEST_F(ProgrammaticConfigTest, LoggerProviderWithGeneralAttributeLimits) +{ + auto attr_limits = std::make_unique(); + attr_limits->attribute_count_limit = 2; + attr_limits->attribute_value_length_limit = 5; + attr_limits->has_attribute_count_limit = true; + attr_limits->has_attribute_value_length_limit = true; + + auto logger_provider_config = MakeLoggerProviderConfig(); + logger_provider_config->limits = nullptr; + + auto model = std::make_unique(); + model->attribute_limits = std::move(attr_limits); + model->logger_provider = std::move(logger_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->logger_provider, nullptr); + + auto logger = logs::Provider::GetLoggerProvider()->GetLogger("test"); + logger->EmitLogRecord( + logs::Severity::kInfo, nostd::string_view("test-message"), + common::MakeAttributes({{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}})); + + ASSERT_TRUE(sdk_->logger_provider->ForceFlush(std::chrono::milliseconds(kProcessTimeout))); + ASSERT_TRUE(sdk_->logger_provider->Shutdown(std::chrono::milliseconds(kProcessTimeout))); + + EXPECT_EQ(log_buffer_->size(), 1); + auto *record = log_buffer_->front().get(); + EXPECT_EQ(nostd::get(record->GetBody()), "test-message"); + const auto &attributes = record->GetAttributes(); + EXPECT_EQ(attributes.size(), 2u); + for (const auto &attr : attributes) + { + EXPECT_EQ(nostd::get(attr.second).size(), 5u); + } +} + +TEST_F(ProgrammaticConfigTest, LoggerProviderWithGeneralAttributeLimitsOverridden) +{ + auto attr_limits = std::make_unique(); + attr_limits->attribute_count_limit = 10; + attr_limits->attribute_value_length_limit = 20; + attr_limits->has_attribute_count_limit = true; + attr_limits->has_attribute_value_length_limit = true; + + config_sdk::LogRecordLimitsConfiguration limits; + limits.attribute_count_limit = 2; + limits.attribute_value_length_limit = 5; + limits.has_attribute_count_limit = true; + limits.has_attribute_value_length_limit = true; + + auto logger_provider_config = MakeLoggerProviderConfig(); + logger_provider_config->limits = + std::make_unique(limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attr_limits); + model->logger_provider = std::move(logger_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->logger_provider, nullptr); + + auto logger = logs::Provider::GetLoggerProvider()->GetLogger("test"); + logger->EmitLogRecord( + logs::Severity::kInfo, nostd::string_view("test-message"), + common::MakeAttributes({{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}})); + + ASSERT_TRUE(sdk_->logger_provider->ForceFlush(std::chrono::milliseconds(kProcessTimeout))); + ASSERT_TRUE(sdk_->logger_provider->Shutdown(std::chrono::milliseconds(kProcessTimeout))); + + EXPECT_EQ(log_buffer_->size(), 1); + auto *record = log_buffer_->front().get(); + const auto &attributes = record->GetAttributes(); + EXPECT_EQ(attributes.size(), 2u); + for (const auto &attr : attributes) + { + EXPECT_EQ(nostd::get(attr.second).size(), 5u); + } +} + +TEST_F(ProgrammaticConfigTest, LoggerProviderWithGeneralAttributeLimitsPartialOverride) +{ + auto attr_limits = std::make_unique(); + attr_limits->attribute_count_limit = 10; + attr_limits->attribute_value_length_limit = 5; + attr_limits->has_attribute_count_limit = true; + attr_limits->has_attribute_value_length_limit = true; + + config_sdk::LogRecordLimitsConfiguration limits; + limits.attribute_count_limit = 2; + limits.has_attribute_count_limit = true; + limits.has_attribute_value_length_limit = false; + + auto logger_provider_config = MakeLoggerProviderConfig(); + logger_provider_config->limits = + std::make_unique(limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attr_limits); + model->logger_provider = std::move(logger_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->logger_provider, nullptr); + + auto logger = logs::Provider::GetLoggerProvider()->GetLogger("test"); + logger->EmitLogRecord( + logs::Severity::kInfo, nostd::string_view("test-message"), + common::MakeAttributes({{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}})); + + ASSERT_TRUE(sdk_->logger_provider->ForceFlush(std::chrono::milliseconds(kProcessTimeout))); + ASSERT_TRUE(sdk_->logger_provider->Shutdown(std::chrono::milliseconds(kProcessTimeout))); + + EXPECT_EQ(log_buffer_->size(), 1); + auto *record = log_buffer_->front().get(); + const auto &attributes = record->GetAttributes(); + EXPECT_EQ(attributes.size(), 2u); + for (const auto &attr : attributes) + { + EXPECT_EQ(nostd::get(attr.second).size(), 5u); + } +} + +TEST_F(ProgrammaticConfigTest, TracerProviderWithGeneralAttributeLimits) +{ + auto attr_limits = std::make_unique(); + attr_limits->attribute_count_limit = 50; + attr_limits->attribute_value_length_limit = 1000; + attr_limits->has_attribute_count_limit = true; + attr_limits->has_attribute_value_length_limit = true; + + auto tracer_provider_config = MakeTracerProviderConfig(); + tracer_provider_config->limits = nullptr; + + auto model = std::make_unique(); + model->attribute_limits = std::move(attr_limits); + model->tracer_provider = std::move(tracer_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->tracer_provider, nullptr); + + const auto span_limits = sdk_->tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 50u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 1000u); +} + +TEST_F(ProgrammaticConfigTest, TracerProviderWithGeneralAttributeLimitsOverridden) +{ + auto attr_limits = std::make_unique(); + attr_limits->attribute_count_limit = 50; + attr_limits->attribute_value_length_limit = 1000; + attr_limits->has_attribute_count_limit = true; + attr_limits->has_attribute_value_length_limit = true; + + config_sdk::SpanLimitsConfiguration limits; + limits.attribute_count_limit = 20; + limits.attribute_value_length_limit = 500; + limits.has_attribute_count_limit = true; + limits.has_attribute_value_length_limit = true; + + auto tracer_provider_config = MakeTracerProviderConfig(); + tracer_provider_config->limits = + std::make_unique(limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attr_limits); + model->tracer_provider = std::move(tracer_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->tracer_provider, nullptr); + + const auto span_limits = sdk_->tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 20u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 500u); +} + +TEST_F(ProgrammaticConfigTest, TracerProviderWithGeneralAttributeLimitsPartialOverrideCount) +{ + auto attr_limits = std::make_unique(); + attr_limits->attribute_count_limit = 50; + attr_limits->attribute_value_length_limit = 1000; + attr_limits->has_attribute_count_limit = true; + attr_limits->has_attribute_value_length_limit = true; + + config_sdk::SpanLimitsConfiguration limits; + limits.attribute_count_limit = 20; + limits.has_attribute_count_limit = true; + limits.has_attribute_value_length_limit = false; + + auto tracer_provider_config = MakeTracerProviderConfig(); + tracer_provider_config->limits = + std::make_unique(limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attr_limits); + model->tracer_provider = std::move(tracer_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->tracer_provider, nullptr); + + const auto span_limits = sdk_->tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 20u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 1000u); +} + +TEST_F(ProgrammaticConfigTest, TracerProviderWithGeneralAttributeLimitsPartialOverrideLength) +{ + auto attr_limits = std::make_unique(); + attr_limits->attribute_count_limit = 50; + attr_limits->attribute_value_length_limit = 1000; + attr_limits->has_attribute_count_limit = true; + attr_limits->has_attribute_value_length_limit = true; + + config_sdk::SpanLimitsConfiguration limits; + limits.attribute_value_length_limit = 500; + limits.has_attribute_value_length_limit = true; + limits.has_attribute_count_limit = false; + + auto tracer_provider_config = MakeTracerProviderConfig(); + tracer_provider_config->limits = + std::make_unique(limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attr_limits); + model->tracer_provider = std::move(tracer_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->tracer_provider, nullptr); + + const auto span_limits = sdk_->tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 50u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 500u); +} + TEST_F(ProgrammaticConfigTest, LoggerProviderWithLoggerConfigurator) { auto error_logger_matcher = config_sdk::LoggerMatcherAndConfigConfiguration(); diff --git a/sdk/test/configuration/sdk_builder_test.cc b/sdk/test/configuration/sdk_builder_test.cc index 8558a920b..544cf2cb1 100644 --- a/sdk/test/configuration/sdk_builder_test.cc +++ b/sdk/test/configuration/sdk_builder_test.cc @@ -28,6 +28,7 @@ #include "opentelemetry/sdk/configuration/aggregation_configuration.h" #include "opentelemetry/sdk/configuration/always_off_sampler_configuration.h" #include "opentelemetry/sdk/configuration/always_on_sampler_configuration.h" +#include "opentelemetry/sdk/configuration/attribute_limits_configuration.h" #include "opentelemetry/sdk/configuration/attribute_value_configuration.h" #include "opentelemetry/sdk/configuration/attributes_configuration.h" #include "opentelemetry/sdk/configuration/cardinality_limits_configuration.h" @@ -53,7 +54,9 @@ #include "opentelemetry/sdk/configuration/instrument_type.h" #include "opentelemetry/sdk/configuration/logger_config_configuration.h" #include "opentelemetry/sdk/configuration/logger_configurator_configuration.h" +#include "opentelemetry/sdk/configuration/log_record_limits_configuration.h" #include "opentelemetry/sdk/configuration/logger_matcher_and_config_configuration.h" +#include "opentelemetry/sdk/configuration/logger_provider_configuration.h" #include "opentelemetry/sdk/configuration/parent_based_sampler_configuration.h" #include "opentelemetry/sdk/configuration/periodic_metric_reader_builder.h" #include "opentelemetry/sdk/configuration/periodic_metric_reader_configuration.h" @@ -83,7 +86,9 @@ #include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/instrumentationscope/scope_configurator.h" +#include "opentelemetry/sdk/logs/log_record_limits.h" #include "opentelemetry/sdk/logs/logger_config.h" +#include "opentelemetry/sdk/logs/logger_provider.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation_config.h" #include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" @@ -261,6 +266,171 @@ TEST(SdkBuilder, SpanLimitsConfiguration) EXPECT_EQ(limits.link_attribute_count_limit, model->limits->link_attribute_count_limit); } +TEST(SdkBuilder, GeneralAttributeLimitsTracerAndLogger) +{ + config_sdk::AttributeLimitsConfiguration attr_limits; + attr_limits.attribute_count_limit = 50; + attr_limits.attribute_value_length_limit = 1000; + attr_limits.has_attribute_count_limit = true; + attr_limits.has_attribute_value_length_limit = true; + + auto tracer_model = std::make_unique(); + tracer_model->limits = nullptr; + + auto logger_model = std::make_unique(); + logger_model->limits = nullptr; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + + auto tracer_provider = builder.CreateTracerProvider(tracer_model, resource, &attr_limits); + ASSERT_NE(tracer_provider, nullptr); + const auto span_limits = tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 50u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 1000u); + EXPECT_EQ(span_limits.event_count_limit, 128u); + + auto logger_provider = builder.CreateLoggerProvider(logger_model, resource, &attr_limits); + ASSERT_NE(logger_provider, nullptr); +} + +TEST(SdkBuilder, GeneralAttributeLimitsTracerOverride) +{ + config_sdk::AttributeLimitsConfiguration attr_limits; + attr_limits.attribute_count_limit = 50; + attr_limits.attribute_value_length_limit = 1000; + attr_limits.has_attribute_count_limit = true; + attr_limits.has_attribute_value_length_limit = true; + + auto tracer_model = std::make_unique(); + tracer_model->limits = std::make_unique(); + tracer_model->limits->attribute_count_limit = 20; + tracer_model->limits->attribute_value_length_limit = 500; + tracer_model->limits->has_attribute_count_limit = true; + tracer_model->limits->has_attribute_value_length_limit = true; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + + auto tracer_provider = builder.CreateTracerProvider(tracer_model, resource, &attr_limits); + ASSERT_NE(tracer_provider, nullptr); + const auto span_limits = tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 20u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 500u); +} + +TEST(SdkBuilder, GeneralAttributeLimitsTracerPartialOverrideCount) +{ + config_sdk::AttributeLimitsConfiguration attr_limits; + attr_limits.attribute_count_limit = 50; + attr_limits.attribute_value_length_limit = 1000; + attr_limits.has_attribute_count_limit = true; + attr_limits.has_attribute_value_length_limit = true; + + auto tracer_model = std::make_unique(); + tracer_model->limits = std::make_unique(); + tracer_model->limits->attribute_count_limit = 20; + tracer_model->limits->has_attribute_count_limit = true; + tracer_model->limits->has_attribute_value_length_limit = false; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + + auto tracer_provider = builder.CreateTracerProvider(tracer_model, resource, &attr_limits); + ASSERT_NE(tracer_provider, nullptr); + const auto span_limits = tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 20u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 1000u); +} + +TEST(SdkBuilder, GeneralAttributeLimitsTracerPartialOverrideLength) +{ + config_sdk::AttributeLimitsConfiguration attr_limits; + attr_limits.attribute_count_limit = 50; + attr_limits.attribute_value_length_limit = 1000; + attr_limits.has_attribute_count_limit = true; + attr_limits.has_attribute_value_length_limit = true; + + auto tracer_model = std::make_unique(); + tracer_model->limits = std::make_unique(); + tracer_model->limits->attribute_value_length_limit = 500; + tracer_model->limits->has_attribute_value_length_limit = true; + tracer_model->limits->has_attribute_count_limit = false; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + + auto tracer_provider = builder.CreateTracerProvider(tracer_model, resource, &attr_limits); + ASSERT_NE(tracer_provider, nullptr); + const auto span_limits = tracer_provider->GetSpanLimits(); + EXPECT_EQ(span_limits.attribute_count_limit, 50u); + EXPECT_EQ(span_limits.attribute_value_length_limit, 500u); +} + +TEST(SdkBuilder, GeneralAttributeLimitsLoggerOverride) +{ + config_sdk::AttributeLimitsConfiguration attr_limits; + attr_limits.attribute_count_limit = 50; + attr_limits.attribute_value_length_limit = 1000; + attr_limits.has_attribute_count_limit = true; + attr_limits.has_attribute_value_length_limit = true; + + auto logger_model = std::make_unique(); + logger_model->limits = std::make_unique(); + logger_model->limits->attribute_count_limit = 20; + logger_model->limits->attribute_value_length_limit = 500; + logger_model->limits->has_attribute_count_limit = true; + logger_model->limits->has_attribute_value_length_limit = true; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + + auto logger_provider = builder.CreateLoggerProvider(logger_model, resource, &attr_limits); + ASSERT_NE(logger_provider, nullptr); +} + +TEST(SdkBuilder, GeneralAttributeLimitsLoggerPartialOverrideCount) +{ + config_sdk::AttributeLimitsConfiguration attr_limits; + attr_limits.attribute_count_limit = 50; + attr_limits.attribute_value_length_limit = 1000; + attr_limits.has_attribute_count_limit = true; + attr_limits.has_attribute_value_length_limit = true; + + auto logger_model = std::make_unique(); + logger_model->limits = std::make_unique(); + logger_model->limits->attribute_count_limit = 20; + logger_model->limits->has_attribute_count_limit = true; + logger_model->limits->has_attribute_value_length_limit = false; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + + auto logger_provider = builder.CreateLoggerProvider(logger_model, resource, &attr_limits); + ASSERT_NE(logger_provider, nullptr); +} + +TEST(SdkBuilder, GeneralAttributeLimitsLoggerPartialOverrideLength) +{ + config_sdk::AttributeLimitsConfiguration attr_limits; + attr_limits.attribute_count_limit = 50; + attr_limits.attribute_value_length_limit = 1000; + attr_limits.has_attribute_count_limit = true; + attr_limits.has_attribute_value_length_limit = true; + + auto logger_model = std::make_unique(); + logger_model->limits = std::make_unique(); + logger_model->limits->attribute_value_length_limit = 500; + logger_model->limits->has_attribute_value_length_limit = true; + logger_model->limits->has_attribute_count_limit = false; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + + auto logger_provider = builder.CreateLoggerProvider(logger_model, resource, &attr_limits); + ASSERT_NE(logger_provider, nullptr); +} + #if defined(ENABLE_METRICS_EXEMPLAR_PREVIEW) && !defined(NO_GETENV) TEST_F(SdkBuilderExemplarFilterEnvironmentTest, DeclarativeExemplarFilterDoesNotReadEnvironment) { diff --git a/sdk/test/configuration/yaml_logs_test.cc b/sdk/test/configuration/yaml_logs_test.cc index 78ca46f62..0f6937af7 100644 --- a/sdk/test/configuration/yaml_logs_test.cc +++ b/sdk/test/configuration/yaml_logs_test.cc @@ -489,6 +489,78 @@ file_format: "1.0-logs" ASSERT_EQ(config->logger_provider->limits->attribute_count_limit, 2222); } +TEST(YamlLogs, limits_partial_count) +{ + std::string yaml = R"( +file_format: "1.0-logs" +logger_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_count_limit: 2222 +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->logger_provider, nullptr); + ASSERT_NE(config->logger_provider->limits, nullptr); + EXPECT_TRUE(config->logger_provider->limits->has_attribute_count_limit); + EXPECT_FALSE(config->logger_provider->limits->has_attribute_value_length_limit); + EXPECT_EQ(config->logger_provider->limits->attribute_count_limit, 2222u); + EXPECT_EQ(config->logger_provider->limits->attribute_value_length_limit, + opentelemetry::sdk::configuration::LogRecordLimitsConfiguration::kDefaultAttributeValueLengthLimit); +} + +TEST(YamlLogs, limits_partial_length) +{ + std::string yaml = R"( +file_format: "1.0-logs" +logger_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_value_length_limit: 1111 +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->logger_provider, nullptr); + ASSERT_NE(config->logger_provider->limits, nullptr); + EXPECT_FALSE(config->logger_provider->limits->has_attribute_count_limit); + EXPECT_TRUE(config->logger_provider->limits->has_attribute_value_length_limit); + EXPECT_EQ(config->logger_provider->limits->attribute_count_limit, 128u); + EXPECT_EQ(config->logger_provider->limits->attribute_value_length_limit, 1111u); +} + +TEST(YamlLogs, limits_null_values) +{ + std::string yaml = R"( +file_format: "1.0-logs" +logger_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_value_length_limit: + attribute_count_limit: +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->logger_provider, nullptr); + ASSERT_NE(config->logger_provider->limits, nullptr); + EXPECT_FALSE(config->logger_provider->limits->has_attribute_count_limit); + EXPECT_FALSE(config->logger_provider->limits->has_attribute_value_length_limit); + EXPECT_EQ(config->logger_provider->limits->attribute_count_limit, 128u); + EXPECT_EQ(config->logger_provider->limits->attribute_value_length_limit, + opentelemetry::sdk::configuration::LogRecordLimitsConfiguration::kDefaultAttributeValueLengthLimit); +} + TEST(YamlLogs, no_logger_configurator) { std::string yaml = R"( diff --git a/sdk/test/configuration/yaml_test.cc b/sdk/test/configuration/yaml_test.cc index 8a04886c9..2154843a6 100644 --- a/sdk/test/configuration/yaml_test.cc +++ b/sdk/test/configuration/yaml_test.cc @@ -200,6 +200,60 @@ file_format: "1.0" ASSERT_EQ(config->attribute_limits->attribute_count_limit, 5678); } +TEST(Yaml, attribute_limits_partial_count) +{ + std::string yaml = R"( +file_format: "1.0" +attribute_limits: + attribute_count_limit: 5678 +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->attribute_limits, nullptr); + EXPECT_TRUE(config->attribute_limits->has_attribute_count_limit); + EXPECT_FALSE(config->attribute_limits->has_attribute_value_length_limit); + EXPECT_EQ(config->attribute_limits->attribute_count_limit, 5678u); + EXPECT_EQ(config->attribute_limits->attribute_value_length_limit, + opentelemetry::sdk::configuration::AttributeLimitsConfiguration::kDefaultAttributeValueLengthLimit); +} + +TEST(Yaml, attribute_limits_partial_length) +{ + std::string yaml = R"( +file_format: "1.0" +attribute_limits: + attribute_value_length_limit: 1234 +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->attribute_limits, nullptr); + EXPECT_FALSE(config->attribute_limits->has_attribute_count_limit); + EXPECT_TRUE(config->attribute_limits->has_attribute_value_length_limit); + EXPECT_EQ(config->attribute_limits->attribute_count_limit, 128u); + EXPECT_EQ(config->attribute_limits->attribute_value_length_limit, 1234u); +} + +TEST(Yaml, attribute_limits_null_values) +{ + std::string yaml = R"( +file_format: "1.0" +attribute_limits: + attribute_value_length_limit: + attribute_count_limit: +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->attribute_limits, nullptr); + EXPECT_FALSE(config->attribute_limits->has_attribute_count_limit); + EXPECT_FALSE(config->attribute_limits->has_attribute_value_length_limit); + EXPECT_EQ(config->attribute_limits->attribute_count_limit, 128u); + EXPECT_EQ(config->attribute_limits->attribute_value_length_limit, + opentelemetry::sdk::configuration::AttributeLimitsConfiguration::kDefaultAttributeValueLengthLimit); +} + TEST(Yaml, no_optional_boolean) { std::string yaml = R"( diff --git a/sdk/test/configuration/yaml_trace_test.cc b/sdk/test/configuration/yaml_trace_test.cc index 1165f13ae..02a18aa21 100644 --- a/sdk/test/configuration/yaml_trace_test.cc +++ b/sdk/test/configuration/yaml_trace_test.cc @@ -645,6 +645,78 @@ file_format: "1.0-trace" ASSERT_EQ(config->tracer_provider->limits->link_attribute_count_limit, 6666); } +TEST(YamlTrace, limits_partial_count) +{ + std::string yaml = R"( +file_format: "1.0-trace" +tracer_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_count_limit: 2222 +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->tracer_provider, nullptr); + ASSERT_NE(config->tracer_provider->limits, nullptr); + EXPECT_TRUE(config->tracer_provider->limits->has_attribute_count_limit); + EXPECT_FALSE(config->tracer_provider->limits->has_attribute_value_length_limit); + EXPECT_EQ(config->tracer_provider->limits->attribute_count_limit, 2222u); + EXPECT_EQ(config->tracer_provider->limits->attribute_value_length_limit, + opentelemetry::sdk::configuration::SpanLimitsConfiguration::kDefaultAttributeValueLengthLimit); +} + +TEST(YamlTrace, limits_partial_length) +{ + std::string yaml = R"( +file_format: "1.0-trace" +tracer_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_value_length_limit: 1111 +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->tracer_provider, nullptr); + ASSERT_NE(config->tracer_provider->limits, nullptr); + EXPECT_FALSE(config->tracer_provider->limits->has_attribute_count_limit); + EXPECT_TRUE(config->tracer_provider->limits->has_attribute_value_length_limit); + EXPECT_EQ(config->tracer_provider->limits->attribute_count_limit, 128u); + EXPECT_EQ(config->tracer_provider->limits->attribute_value_length_limit, 1111u); +} + +TEST(YamlTrace, limits_null_values) +{ + std::string yaml = R"( +file_format: "1.0-trace" +tracer_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_value_length_limit: + attribute_count_limit: +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->tracer_provider, nullptr); + ASSERT_NE(config->tracer_provider->limits, nullptr); + EXPECT_FALSE(config->tracer_provider->limits->has_attribute_count_limit); + EXPECT_FALSE(config->tracer_provider->limits->has_attribute_value_length_limit); + EXPECT_EQ(config->tracer_provider->limits->attribute_count_limit, 128u); + EXPECT_EQ(config->tracer_provider->limits->attribute_value_length_limit, + opentelemetry::sdk::configuration::SpanLimitsConfiguration::kDefaultAttributeValueLengthLimit); +} + TEST(YamlTrace, limits_with_invalid_values) { std::string invalid_attribute_count_yaml = R"(