diff --git a/CHANGELOG.md b/CHANGELOG.md index a4b17ef3f..ea82737b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,15 @@ Increment the: ## [Unreleased] +* [CONFIGURATION] Apply general `attribute_limits` per individual limit field. + If a model-specific limit is set it is used, otherwise the matching general + limit, otherwise the model-specific default. Limit fields on + `AttributeLimitsConfiguration`, `SpanLimitsConfiguration`, and + `LogRecordLimitsConfiguration` are now optional so omitted keys and YAML + `null` are distinct from explicit values. This is a breaking change to the + experimental configuration model. + [#4467](https://github.com/open-telemetry/opentelemetry-cpp/issues/4467) + * [CONFIGURATION] Add a configuration builder for the host resource detector [#4451](https://github.com/open-telemetry/opentelemetry-cpp/issues/4451) * [CONFIGURATION] Build the configured resource detectors in SdkBuilder, apply diff --git a/install/test/src/test_sdk.cc b/install/test/src/test_sdk.cc index 128c8385b..bb5fb4080 100644 --- a/install/test/src/test_sdk.cc +++ b/install/test/src/test_sdk.cc @@ -189,6 +189,7 @@ #include #include #include +#include #include #include #include diff --git a/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h b/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h index 755069ea0..98a0042de 100644 --- a/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h +++ b/sdk/include/opentelemetry/sdk/configuration/attribute_limits_configuration.h @@ -6,6 +6,7 @@ #include #include +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -23,8 +24,8 @@ class AttributeLimitsConfiguration (std::numeric_limits::max)(); static constexpr std::size_t kDefaultAttributeCountLimit = 128; - std::size_t attribute_value_length_limit{kDefaultAttributeValueLengthLimit}; - std::size_t attribute_count_limit{kDefaultAttributeCountLimit}; + OptionalValue attribute_value_length_limit; + OptionalValue attribute_count_limit; }; } // namespace configuration diff --git a/sdk/include/opentelemetry/sdk/configuration/document_node.h b/sdk/include/opentelemetry/sdk/configuration/document_node.h index 281515574..dc1efb0d2 100644 --- a/sdk/include/opentelemetry/sdk/configuration/document_node.h +++ b/sdk/include/opentelemetry/sdk/configuration/document_node.h @@ -7,6 +7,7 @@ #include #include +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -50,6 +51,7 @@ class DocumentNode virtual std::size_t GetRequiredInteger(const std::string &name) const = 0; virtual std::size_t GetInteger(const std::string &name, std::size_t default_value) const = 0; + virtual OptionalValue GetOptionalInteger(const std::string &name) const = 0; virtual std::int64_t GetSignedInteger(const std::string &name, std::int64_t default_value) const = 0; 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..d7c427ae9 100644 --- a/sdk/include/opentelemetry/sdk/configuration/log_record_limits_configuration.h +++ b/sdk/include/opentelemetry/sdk/configuration/log_record_limits_configuration.h @@ -6,6 +6,7 @@ #include #include +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -23,8 +24,8 @@ class LogRecordLimitsConfiguration (std::numeric_limits::max)(); static constexpr std::size_t kDefaultAttributeCountLimit = 128; - std::size_t attribute_value_length_limit{kDefaultAttributeValueLengthLimit}; - std::size_t attribute_count_limit{kDefaultAttributeCountLimit}; + OptionalValue attribute_value_length_limit; + OptionalValue attribute_count_limit; }; } // namespace configuration diff --git a/sdk/include/opentelemetry/sdk/configuration/optional_value.h b/sdk/include/opentelemetry/sdk/configuration/optional_value.h new file mode 100644 index 000000000..42086f6f4 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/configuration/optional_value.h @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace configuration +{ + +/** + * C++14-friendly optional for configuration fields that may be set, omitted, or + * explicitly null in YAML. + */ +template +class OptionalValue +{ +public: + OptionalValue() = default; + + explicit OptionalValue(T value) : has_value_(true), value_(value) {} + + bool HasValue() const { return has_value_; } + + const T &Value() const + { + if (!has_value_) + { + throw std::runtime_error("OptionalValue has no value"); + } + return value_; + } + + T ValueOr(T fallback) const { return has_value_ ? value_ : fallback; } + + OptionalValue &operator=(T value) + { + has_value_ = true; + value_ = value; + return *this; + } + +private: + bool has_value_{false}; + T value_{}; +}; + +} // namespace configuration +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h b/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h index 37248df4c..642402ff0 100644 --- a/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h +++ b/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h @@ -10,6 +10,7 @@ #include #include "opentelemetry/sdk/configuration/document_node.h" +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -50,6 +51,7 @@ class RymlDocumentNode : public DocumentNode std::size_t GetRequiredInteger(const std::string &name) const override; std::size_t GetInteger(const std::string &name, std::size_t default_value) const override; + OptionalValue GetOptionalInteger(const std::string &name) const override; std::int64_t GetSignedInteger(const std::string &name, std::int64_t default_value) const override; diff --git a/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h b/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h index 637756bb3..69d96f673 100644 --- a/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h +++ b/sdk/include/opentelemetry/sdk/configuration/sdk_builder.h @@ -7,6 +7,7 @@ #include #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_configuration.h" #include "opentelemetry/sdk/configuration/batch_span_processor_configuration.h" @@ -161,7 +162,8 @@ 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 AttributeLimitsConfiguration *attribute_limits = nullptr) const; std::unique_ptr CreateTextMapPropagator( const std::string &name) const; @@ -286,7 +288,8 @@ 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 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..f6ad99290 100644 --- a/sdk/include/opentelemetry/sdk/configuration/span_limits_configuration.h +++ b/sdk/include/opentelemetry/sdk/configuration/span_limits_configuration.h @@ -4,8 +4,10 @@ #pragma once #include +#include #include +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -27,12 +29,12 @@ class SpanLimitsConfiguration static constexpr std::uint32_t kDefaultEventAttributeCountLimit = 128; static constexpr std::uint32_t kDefaultLinkAttributeCountLimit = 128; - std::size_t attribute_value_length_limit{kDefaultAttributeValueLengthLimit}; - std::uint32_t attribute_count_limit{kDefaultAttributeCountLimit}; - std::uint32_t event_count_limit{kDefaultEventCountLimit}; - std::uint32_t link_count_limit{kDefaultLinkCountLimit}; - std::uint32_t event_attribute_count_limit{kDefaultEventAttributeCountLimit}; - std::uint32_t link_attribute_count_limit{kDefaultLinkAttributeCountLimit}; + OptionalValue attribute_value_length_limit; + OptionalValue attribute_count_limit; + OptionalValue event_count_limit; + OptionalValue link_count_limit; + OptionalValue event_attribute_count_limit; + OptionalValue link_attribute_count_limit; }; } // namespace configuration diff --git a/sdk/src/configuration/configuration_parser.cc b/sdk/src/configuration/configuration_parser.cc index 3d2dab661..0fc7762f1 100644 --- a/sdk/src/configuration/configuration_parser.cc +++ b/sdk/src/configuration/configuration_parser.cc @@ -87,6 +87,7 @@ #include "opentelemetry/sdk/configuration/metric_producer_configuration.h" #include "opentelemetry/sdk/configuration/metric_reader_configuration.h" #include "opentelemetry/sdk/configuration/open_census_metric_producer_configuration.h" +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/sdk/configuration/otlp_file_log_record_exporter_configuration.h" #include "opentelemetry/sdk/configuration/otlp_file_push_metric_exporter_configuration.h" #include "opentelemetry/sdk/configuration/otlp_file_span_exporter_configuration.h" @@ -360,13 +361,10 @@ std::unique_ptr ConfigurationParser::ParseAttributeLimitsConfiguration( const std::unique_ptr &node) const { - using Config = AttributeLimitsConfiguration; - auto model = std::make_unique(); + auto model = std::make_unique(); - model->attribute_value_length_limit = - node->GetInteger("attribute_value_length_limit", Config::kDefaultAttributeValueLengthLimit); - model->attribute_count_limit = - node->GetInteger("attribute_count_limit", Config::kDefaultAttributeCountLimit); + model->attribute_value_length_limit = node->GetOptionalInteger("attribute_value_length_limit"); + model->attribute_count_limit = node->GetOptionalInteger("attribute_count_limit"); return model; } @@ -640,13 +638,10 @@ std::unique_ptr ConfigurationParser::ParseLogRecordLimitsConfiguration( const std::unique_ptr &node) const { - using Config = LogRecordLimitsConfiguration; - auto model = std::make_unique(); + auto model = std::make_unique(); - model->attribute_value_length_limit = - node->GetInteger("attribute_value_length_limit", Config::kDefaultAttributeValueLengthLimit); - model->attribute_count_limit = - node->GetInteger("attribute_count_limit", Config::kDefaultAttributeCountLimit); + model->attribute_value_length_limit = node->GetOptionalInteger("attribute_value_length_limit"); + model->attribute_count_limit = node->GetOptionalInteger("attribute_count_limit"); return model; } @@ -1673,29 +1668,28 @@ std::unique_ptr ConfigurationParser::ParsePropagatorCon std::unique_ptr ConfigurationParser::ParseSpanLimitsConfiguration( const std::unique_ptr &node) const { - using Config = SpanLimitsConfiguration; - auto model = std::make_unique(); + auto model = std::make_unique(); - const auto get_valid_uint32 = [&node](const std::string &name, std::size_t default_value) { - std::size_t value = node->GetInteger(name, default_value); - if (value > std::numeric_limits::max()) + const auto get_optional_uint32 = [&node](const std::string &name) { + OptionalValue value = node->GetOptionalInteger(name); + if (!value.HasValue()) { - std::string message = "Invalid value for " + name + ": " + std::to_string(value); + return OptionalValue{}; + } + if (value.Value() > std::numeric_limits::max()) + { + std::string message = "Invalid value for " + name + ": " + std::to_string(value.Value()); throw InvalidSchemaException(node->Location(), message); } - return static_cast(value); + return OptionalValue{static_cast(value.Value())}; }; - model->attribute_value_length_limit = - node->GetInteger("attribute_value_length_limit", Config::kDefaultAttributeValueLengthLimit); - model->attribute_count_limit = - get_valid_uint32("attribute_count_limit", Config::kDefaultAttributeCountLimit); - model->event_count_limit = get_valid_uint32("event_count_limit", Config::kDefaultEventCountLimit); - model->link_count_limit = get_valid_uint32("link_count_limit", Config::kDefaultLinkCountLimit); - model->event_attribute_count_limit = - get_valid_uint32("event_attribute_count_limit", Config::kDefaultEventAttributeCountLimit); - model->link_attribute_count_limit = - get_valid_uint32("link_attribute_count_limit", Config::kDefaultLinkAttributeCountLimit); + model->attribute_value_length_limit = node->GetOptionalInteger("attribute_value_length_limit"); + model->attribute_count_limit = get_optional_uint32("attribute_count_limit"); + model->event_count_limit = get_optional_uint32("event_count_limit"); + model->link_count_limit = get_optional_uint32("link_count_limit"); + model->event_attribute_count_limit = get_optional_uint32("event_attribute_count_limit"); + model->link_attribute_count_limit = get_optional_uint32("link_attribute_count_limit"); return model; } diff --git a/sdk/src/configuration/ryml_document_node.cc b/sdk/src/configuration/ryml_document_node.cc index 65d5ec43c..634764280 100644 --- a/sdk/src/configuration/ryml_document_node.cc +++ b/sdk/src/configuration/ryml_document_node.cc @@ -13,6 +13,7 @@ #include "opentelemetry/sdk/common/global_log_handler.h" #include "opentelemetry/sdk/configuration/document_node.h" #include "opentelemetry/sdk/configuration/invalid_schema_exception.h" +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/sdk/configuration/ryml_document.h" #include "opentelemetry/sdk/configuration/ryml_document_node.h" #include "opentelemetry/version.h" @@ -297,6 +298,27 @@ size_t RymlDocumentNode::GetInteger(const std::string &name, size_t default_valu return IntegerFromString(value); } +OptionalValue RymlDocumentNode::GetOptionalInteger(const std::string &name) const +{ + OTEL_INTERNAL_LOG_DEBUG("RymlDocumentNode::GetOptionalInteger(" << name << ")"); + + auto child = GetChildNode(name); + + if (!child || child->IsNull()) + { + return OptionalValue{}; + } + + std::string value = child->AsString(); + + if (value.empty()) + { + return OptionalValue{}; + } + + return OptionalValue{IntegerFromString(value)}; +} + std::int64_t RymlDocumentNode::GetSignedInteger(const std::string &name, std::int64_t default_value) const { diff --git a/sdk/src/configuration/sdk_builder.cc b/sdk/src/configuration/sdk_builder.cc index 39d959a23..ece90672e 100644 --- a/sdk/src/configuration/sdk_builder.cc +++ b/sdk/src/configuration/sdk_builder.cc @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include "opentelemetry/sdk/configuration/always_off_sampler_configuration.h" #include "opentelemetry/sdk/configuration/always_on_sampler_builder.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/attribute_value_configuration_visitor.h" #include "opentelemetry/sdk/configuration/attributes_configuration.h" @@ -101,6 +103,7 @@ #include "opentelemetry/sdk/configuration/meter_provider_configuration.h" #include "opentelemetry/sdk/configuration/metric_reader_configuration.h" #include "opentelemetry/sdk/configuration/metric_reader_configuration_visitor.h" +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/sdk/configuration/otlp_file_log_record_exporter_builder.h" #include "opentelemetry/sdk/configuration/otlp_file_log_record_exporter_configuration.h" #include "opentelemetry/sdk/configuration/otlp_file_push_metric_exporter_builder.h" @@ -256,6 +259,44 @@ static opentelemetry::sdk::metrics::CardinalityLimits ToCardinalityLimits( return limits; } +static std::uint32_t ToUint32Limit(std::size_t value) +{ + constexpr auto kMax = (std::numeric_limits::max)(); + if (value > kMax) + { + return kMax; + } + return static_cast(value); +} + +/// Resolve one limit per +/// https://opentelemetry.io/docs/specs/otel/common/#attribute-limits +/// model-specific if set, else general if set, else the model-specific default. +template +static T ResolveLimit(const OptionalValue &model_specific, + const OptionalValue &general, + T model_default) +{ + if (model_specific.HasValue()) + { + return model_specific.Value(); + } + if (general.HasValue()) + { + return general.Value(); + } + return model_default; +} + +static OptionalValue ToOptionalUint32(const OptionalValue &value) +{ + if (!value.HasValue()) + { + return OptionalValue{}; + } + return OptionalValue{ToUint32Limit(value.Value())}; +} + class ResourceAttributeValueSetter : public opentelemetry::sdk::configuration::AttributeValueConfigurationVisitor { @@ -1423,7 +1464,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 AttributeLimitsConfiguration *attribute_limits) const { std::unique_ptr sdk; @@ -1451,15 +1493,49 @@ std::unique_ptr SdkBuilder::CreateTra } opentelemetry::sdk::trace::SpanLimits span_limits; + OptionalValue model_attribute_value_length_limit; + OptionalValue model_attribute_count_limit; + OptionalValue model_event_count_limit; + OptionalValue model_link_count_limit; + OptionalValue model_event_attribute_count_limit; + OptionalValue model_link_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; - } + model_attribute_value_length_limit = model->limits->attribute_value_length_limit; + model_attribute_count_limit = model->limits->attribute_count_limit; + model_event_count_limit = model->limits->event_count_limit; + model_link_count_limit = model->limits->link_count_limit; + model_event_attribute_count_limit = model->limits->event_attribute_count_limit; + model_link_attribute_count_limit = model->limits->link_attribute_count_limit; + } + + OptionalValue general_attribute_value_length_limit; + OptionalValue general_attribute_count_limit; + if (attribute_limits) + { + general_attribute_value_length_limit = attribute_limits->attribute_value_length_limit; + general_attribute_count_limit = attribute_limits->attribute_count_limit; + } + + using SpanLimitDefaults = SpanLimitsConfiguration; + span_limits.attribute_value_length_limit = + ResolveLimit(model_attribute_value_length_limit, general_attribute_value_length_limit, + SpanLimitDefaults::kDefaultAttributeValueLengthLimit); + span_limits.attribute_count_limit = + ResolveLimit(model_attribute_count_limit, ToOptionalUint32(general_attribute_count_limit), + SpanLimitDefaults::kDefaultAttributeCountLimit); + span_limits.event_count_limit = + ResolveLimit(model_event_count_limit, OptionalValue{}, + SpanLimitDefaults::kDefaultEventCountLimit); + span_limits.link_count_limit = + ResolveLimit(model_link_count_limit, OptionalValue{}, + SpanLimitDefaults::kDefaultLinkCountLimit); + span_limits.event_attribute_count_limit = + ResolveLimit(model_event_attribute_count_limit, OptionalValue{}, + SpanLimitDefaults::kDefaultEventAttributeCountLimit); + span_limits.link_attribute_count_limit = + ResolveLimit(model_link_attribute_count_limit, OptionalValue{}, + SpanLimitDefaults::kDefaultLinkAttributeCountLimit); if (model->tracer_configurator) { @@ -2349,7 +2425,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 AttributeLimitsConfiguration *attribute_limits) const { std::unique_ptr sdk; @@ -2361,12 +2438,30 @@ std::unique_ptr SdkBuilder::CreateLogg } opentelemetry::sdk::logs::LogRecordLimits log_record_limits; + OptionalValue model_attribute_value_length_limit; + OptionalValue model_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; + model_attribute_value_length_limit = model->limits->attribute_value_length_limit; + model_attribute_count_limit = model->limits->attribute_count_limit; } + OptionalValue general_attribute_value_length_limit; + OptionalValue general_attribute_count_limit; + if (attribute_limits) + { + general_attribute_value_length_limit = attribute_limits->attribute_value_length_limit; + general_attribute_count_limit = attribute_limits->attribute_count_limit; + } + + using LogLimitDefaults = LogRecordLimitsConfiguration; + log_record_limits.attribute_value_length_limit = + ResolveLimit(model_attribute_value_length_limit, general_attribute_value_length_limit, + LogLimitDefaults::kDefaultAttributeValueLengthLimit); + log_record_limits.attribute_count_limit = + ResolveLimit(model_attribute_count_limit, general_attribute_count_limit, + LogLimitDefaults::kDefaultAttributeCountLimit); + std::unique_ptr> logger_configurator; @@ -2644,16 +2739,10 @@ 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 +2757,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..10e2f2117 100644 --- a/sdk/test/configuration/programmatic_configuration_test.cc +++ b/sdk/test/configuration/programmatic_configuration_test.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,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" @@ -69,6 +71,7 @@ #include "opentelemetry/sdk/configuration/meter_matcher_and_config_configuration.h" #include "opentelemetry/sdk/configuration/meter_provider_configuration.h" #include "opentelemetry/sdk/configuration/metric_reader_configuration.h" +#include "opentelemetry/sdk/configuration/optional_value.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" @@ -82,6 +85,7 @@ #include "opentelemetry/sdk/configuration/simple_log_record_processor_configuration.h" #include "opentelemetry/sdk/configuration/simple_span_processor_configuration.h" #include "opentelemetry/sdk/configuration/span_exporter_configuration.h" +#include "opentelemetry/sdk/configuration/span_limits_configuration.h" #include "opentelemetry/sdk/configuration/span_processor_configuration.h" #include "opentelemetry/sdk/configuration/tracer_config_configuration.h" #include "opentelemetry/sdk/configuration/tracer_configurator_configuration.h" @@ -98,6 +102,7 @@ #include "opentelemetry/sdk/metrics/meter_provider.h" #include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/span_data.h" +#include "opentelemetry/sdk/trace/span_limits.h" #include "opentelemetry/sdk/trace/tracer_provider.h" #include "config_test_common.h" @@ -217,6 +222,13 @@ class ProgrammaticConfigTest : public ::testing::Test } // namespace +TEST(OptionalValue, ValueThrowsWhenEmpty) +{ + config_sdk::OptionalValue value; + + EXPECT_THROW(value.Value(), std::runtime_error); +} + //--------------------------------------------------------------------------- // Resource configuration tests @@ -326,13 +338,171 @@ TEST_F(ProgrammaticConfigTest, LoggerProviderWithLogRecordLimits) auto *record = log_buffer_->front().get(); EXPECT_EQ(nostd::get(record->GetBody()), "test-message"); const auto &attributes = record->GetAttributes(); - EXPECT_EQ(attributes.size(), limits.attribute_count_limit); + EXPECT_EQ(attributes.size(), limits.attribute_count_limit.Value()); + for (const auto &attr : attributes) + { + EXPECT_EQ(nostd::get(attr.second).size(), + limits.attribute_value_length_limit.Value()); + } +} + +TEST_F(ProgrammaticConfigTest, AttributeLimitsApplyToLoggerProvider) +{ + auto attribute_limits = std::make_unique(); + attribute_limits->attribute_count_limit = 2; + attribute_limits->attribute_value_length_limit = 5; + + auto model = std::make_unique(); + model->attribute_limits = std::move(attribute_limits); + model->logger_provider = MakeLoggerProviderConfig(); + + 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(), 2); + for (const auto &attr : attributes) + { + EXPECT_EQ(nostd::get(attr.second).size(), 5); + } +} + +TEST_F(ProgrammaticConfigTest, LoggerProviderLimitsOverrideAttributeLimits) +{ + auto attribute_limits = std::make_unique(); + attribute_limits->attribute_count_limit = 1; + attribute_limits->attribute_value_length_limit = 3; + + config_sdk::LogRecordLimitsConfiguration limits; + limits.attribute_count_limit = 2; + limits.attribute_value_length_limit = 5; + + auto logger_provider_config = MakeLoggerProviderConfig(); + logger_provider_config->limits = + std::make_unique(limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attribute_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(), limits.attribute_count_limit.Value()); + for (const auto &attr : attributes) + { + EXPECT_EQ(nostd::get(attr.second).size(), + limits.attribute_value_length_limit.Value()); + } +} + +TEST_F(ProgrammaticConfigTest, LoggerProviderLimitsPartialOverrideAttributeLimits) +{ + auto attribute_limits = std::make_unique(); + attribute_limits->attribute_count_limit = 1; + attribute_limits->attribute_value_length_limit = 3; + + config_sdk::LogRecordLimitsConfiguration limits; + limits.attribute_value_length_limit = 5; + + auto logger_provider_config = MakeLoggerProviderConfig(); + logger_provider_config->limits = + std::make_unique(limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attribute_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(), 1); for (const auto &attr : attributes) { - EXPECT_EQ(nostd::get(attr.second).size(), limits.attribute_value_length_limit); + EXPECT_EQ(nostd::get(attr.second).size(), 5); } } +TEST_F(ProgrammaticConfigTest, AttributeLimitsApplyToTracerProvider) +{ + auto attribute_limits = std::make_unique(); + attribute_limits->attribute_count_limit = 7; + attribute_limits->attribute_value_length_limit = 9; + + auto model = std::make_unique(); + model->attribute_limits = std::move(attribute_limits); + model->tracer_provider = MakeTracerProviderConfig(); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->tracer_provider, nullptr); + + const auto limits = sdk_->tracer_provider->GetSpanLimits(); + const auto default_limits = opentelemetry::sdk::trace::SpanLimits{}; + EXPECT_EQ(limits.attribute_count_limit, 7); + EXPECT_EQ(limits.attribute_value_length_limit, 9); + EXPECT_EQ(limits.event_count_limit, default_limits.event_count_limit); + EXPECT_EQ(limits.link_count_limit, default_limits.link_count_limit); +} + +TEST_F(ProgrammaticConfigTest, TracerProviderLimitsOverrideAttributeLimits) +{ + auto attribute_limits = std::make_unique(); + attribute_limits->attribute_count_limit = 7; + attribute_limits->attribute_value_length_limit = 9; + + auto span_limits = std::make_unique(); + span_limits->attribute_count_limit = 22; + span_limits->attribute_value_length_limit = 11; + span_limits->event_count_limit = 33; + + auto tracer_provider_config = MakeTracerProviderConfig(); + tracer_provider_config->limits = std::move(span_limits); + + auto model = std::make_unique(); + model->attribute_limits = std::move(attribute_limits); + model->tracer_provider = std::move(tracer_provider_config); + + CreateAndInstallSdk(model); + ASSERT_NE(sdk_->tracer_provider, nullptr); + + const auto limits = sdk_->tracer_provider->GetSpanLimits(); + EXPECT_EQ(limits.attribute_count_limit, 22); + EXPECT_EQ(limits.attribute_value_length_limit, 11); + EXPECT_EQ(limits.event_count_limit, 33); +} + 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..44054a5e0 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" @@ -54,6 +55,7 @@ #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" +#include "opentelemetry/sdk/configuration/optional_value.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" @@ -120,6 +122,7 @@ using opentelemetry::sdk::common::unsetenv; # endif #endif +using opentelemetry::sdk::configuration::AttributeLimitsConfiguration; using opentelemetry::sdk::configuration::Registry; using opentelemetry::sdk::configuration::RegistryFactory; using opentelemetry::sdk::configuration::SdkBuilder; @@ -253,12 +256,110 @@ TEST(SdkBuilder, SpanLimitsConfiguration) ASSERT_NE(provider, nullptr); auto limits = provider->GetSpanLimits(); - EXPECT_EQ(limits.attribute_value_length_limit, model->limits->attribute_value_length_limit); - EXPECT_EQ(limits.attribute_count_limit, model->limits->attribute_count_limit); - EXPECT_EQ(limits.event_count_limit, model->limits->event_count_limit); - EXPECT_EQ(limits.link_count_limit, model->limits->link_count_limit); - EXPECT_EQ(limits.event_attribute_count_limit, model->limits->event_attribute_count_limit); - EXPECT_EQ(limits.link_attribute_count_limit, model->limits->link_attribute_count_limit); + EXPECT_EQ(limits.attribute_value_length_limit, + model->limits->attribute_value_length_limit.Value()); + EXPECT_EQ(limits.attribute_count_limit, model->limits->attribute_count_limit.Value()); + EXPECT_EQ(limits.event_count_limit, model->limits->event_count_limit.Value()); + EXPECT_EQ(limits.link_count_limit, model->limits->link_count_limit.Value()); + EXPECT_EQ(limits.event_attribute_count_limit, model->limits->event_attribute_count_limit.Value()); + EXPECT_EQ(limits.link_attribute_count_limit, model->limits->link_attribute_count_limit.Value()); +} + +TEST(SdkBuilder, SpanLimitsFromAttributeLimits) +{ + auto model = std::make_unique(); + model->limits = nullptr; + + AttributeLimitsConfiguration attribute_limits; + attribute_limits.attribute_count_limit = 7; + attribute_limits.attribute_value_length_limit = 9; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + auto provider = builder.CreateTracerProvider(model, resource, &attribute_limits); + ASSERT_NE(provider, nullptr); + + const auto limits = provider->GetSpanLimits(); + const auto default_limits = opentelemetry::sdk::trace::SpanLimits{}; + + EXPECT_EQ(limits.attribute_count_limit, attribute_limits.attribute_count_limit.Value()); + EXPECT_EQ(limits.attribute_value_length_limit, + attribute_limits.attribute_value_length_limit.Value()); + EXPECT_EQ(limits.event_count_limit, default_limits.event_count_limit); + EXPECT_EQ(limits.link_count_limit, default_limits.link_count_limit); + EXPECT_EQ(limits.event_attribute_count_limit, default_limits.event_attribute_count_limit); + EXPECT_EQ(limits.link_attribute_count_limit, default_limits.link_attribute_count_limit); +} + +TEST(SdkBuilder, SpanLimitsOverrideAttributeLimits) +{ + auto model = std::make_unique(); + model->limits = std::make_unique(); + model->limits->attribute_value_length_limit = 1111; + model->limits->attribute_count_limit = 2222; + model->limits->event_count_limit = 3333; + + AttributeLimitsConfiguration attribute_limits; + attribute_limits.attribute_count_limit = 7; + attribute_limits.attribute_value_length_limit = 9; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + auto provider = builder.CreateTracerProvider(model, resource, &attribute_limits); + ASSERT_NE(provider, nullptr); + + const auto limits = provider->GetSpanLimits(); + EXPECT_EQ(limits.attribute_value_length_limit, + model->limits->attribute_value_length_limit.Value()); + EXPECT_EQ(limits.attribute_count_limit, model->limits->attribute_count_limit.Value()); + EXPECT_EQ(limits.event_count_limit, model->limits->event_count_limit.Value()); +} + +TEST(SdkBuilder, SpanLimitsPerFieldAttributeLimits) +{ + auto model = std::make_unique(); + model->limits = std::make_unique(); + model->limits->event_count_limit = 64; + model->limits->link_count_limit = 64; + model->limits->event_attribute_count_limit = 8; + model->limits->link_attribute_count_limit = 8; + + AttributeLimitsConfiguration attribute_limits; + attribute_limits.attribute_value_length_limit = 4096; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + auto provider = builder.CreateTracerProvider(model, resource, &attribute_limits); + ASSERT_NE(provider, nullptr); + + const auto limits = provider->GetSpanLimits(); + const auto default_limits = opentelemetry::sdk::trace::SpanLimits{}; + EXPECT_EQ(limits.attribute_value_length_limit, 4096); + EXPECT_EQ(limits.attribute_count_limit, default_limits.attribute_count_limit); + EXPECT_EQ(limits.event_count_limit, 64); + EXPECT_EQ(limits.link_count_limit, 64); + EXPECT_EQ(limits.event_attribute_count_limit, 8); + EXPECT_EQ(limits.link_attribute_count_limit, 8); +} + +TEST(SdkBuilder, SpanLimitsPartialOverrideAttributeLimits) +{ + auto model = std::make_unique(); + model->limits = std::make_unique(); + model->limits->attribute_count_limit = 22; + + AttributeLimitsConfiguration attribute_limits; + attribute_limits.attribute_count_limit = 7; + attribute_limits.attribute_value_length_limit = 9; + + SdkBuilder builder(RegistryFactory::Create()); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + auto provider = builder.CreateTracerProvider(model, resource, &attribute_limits); + ASSERT_NE(provider, nullptr); + + const auto limits = provider->GetSpanLimits(); + EXPECT_EQ(limits.attribute_count_limit, 22); + EXPECT_EQ(limits.attribute_value_length_limit, 9); } #if defined(ENABLE_METRICS_EXEMPLAR_PREVIEW) && !defined(NO_GETENV) diff --git a/sdk/test/configuration/yaml_logs_test.cc b/sdk/test/configuration/yaml_logs_test.cc index 78ca46f62..1bd933ba0 100644 --- a/sdk/test/configuration/yaml_logs_test.cc +++ b/sdk/test/configuration/yaml_logs_test.cc @@ -17,6 +17,7 @@ #include "opentelemetry/sdk/configuration/logger_configurator_configuration.h" #include "opentelemetry/sdk/configuration/logger_matcher_and_config_configuration.h" #include "opentelemetry/sdk/configuration/logger_provider_configuration.h" +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/sdk/configuration/otlp_file_log_record_exporter_configuration.h" #include "opentelemetry/sdk/configuration/otlp_grpc_log_record_exporter_configuration.h" #include "opentelemetry/sdk/configuration/otlp_http_encoding.h" @@ -461,10 +462,8 @@ file_format: "1.0-logs" ASSERT_NE(config, nullptr); ASSERT_NE(config->logger_provider, nullptr); ASSERT_NE(config->logger_provider->limits, nullptr); - const auto defaults = opentelemetry::sdk::configuration::LogRecordLimitsConfiguration{}; - ASSERT_EQ(config->logger_provider->limits->attribute_value_length_limit, - defaults.attribute_value_length_limit); - ASSERT_EQ(config->logger_provider->limits->attribute_count_limit, 128); + ASSERT_FALSE(config->logger_provider->limits->attribute_value_length_limit.HasValue()); + ASSERT_FALSE(config->logger_provider->limits->attribute_count_limit.HasValue()); } TEST(YamlLogs, limits) @@ -485,8 +484,33 @@ file_format: "1.0-logs" ASSERT_NE(config, nullptr); ASSERT_NE(config->logger_provider, nullptr); ASSERT_NE(config->logger_provider->limits, nullptr); - ASSERT_EQ(config->logger_provider->limits->attribute_value_length_limit, 1111); - ASSERT_EQ(config->logger_provider->limits->attribute_count_limit, 2222); + ASSERT_TRUE(config->logger_provider->limits->attribute_value_length_limit.HasValue()); + ASSERT_EQ(config->logger_provider->limits->attribute_value_length_limit.Value(), 1111); + ASSERT_TRUE(config->logger_provider->limits->attribute_count_limit.HasValue()); + ASSERT_EQ(config->logger_provider->limits->attribute_count_limit.Value(), 2222); +} + +TEST(YamlLogs, limits_null_fields) +{ + std::string yaml = R"( +file_format: "1.0-logs" +logger_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_value_length_limit: 1024 + attribute_count_limit: null +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->logger_provider, nullptr); + ASSERT_NE(config->logger_provider->limits, nullptr); + ASSERT_TRUE(config->logger_provider->limits->attribute_value_length_limit.HasValue()); + ASSERT_EQ(config->logger_provider->limits->attribute_value_length_limit.Value(), 1024); + ASSERT_FALSE(config->logger_provider->limits->attribute_count_limit.HasValue()); } TEST(YamlLogs, no_logger_configurator) diff --git a/sdk/test/configuration/yaml_test.cc b/sdk/test/configuration/yaml_test.cc index 8a04886c9..647312fb8 100644 --- a/sdk/test/configuration/yaml_test.cc +++ b/sdk/test/configuration/yaml_test.cc @@ -8,6 +8,7 @@ #include "opentelemetry/sdk/configuration/attribute_limits_configuration.h" #include "opentelemetry/sdk/configuration/configuration.h" +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/sdk/configuration/severity_number.h" #include "opentelemetry/sdk/configuration/trace_id_ratio_based_sampler_configuration.h" #include "opentelemetry/sdk/configuration/tracer_provider_configuration.h" @@ -177,10 +178,8 @@ file_format: "1.0" ASSERT_NE(config, nullptr); ASSERT_EQ(config->file_format, "1.0"); ASSERT_NE(config->attribute_limits, nullptr); - const auto defaults = opentelemetry::sdk::configuration::AttributeLimitsConfiguration{}; - ASSERT_EQ(config->attribute_limits->attribute_value_length_limit, - defaults.attribute_value_length_limit); - ASSERT_EQ(config->attribute_limits->attribute_count_limit, 128); + ASSERT_FALSE(config->attribute_limits->attribute_value_length_limit.HasValue()); + ASSERT_FALSE(config->attribute_limits->attribute_count_limit.HasValue()); } TEST(Yaml, attribute_limits) @@ -196,8 +195,41 @@ file_format: "1.0" ASSERT_NE(config, nullptr); ASSERT_EQ(config->file_format, "1.0"); ASSERT_NE(config->attribute_limits, nullptr); - ASSERT_EQ(config->attribute_limits->attribute_value_length_limit, 1234); - ASSERT_EQ(config->attribute_limits->attribute_count_limit, 5678); + ASSERT_TRUE(config->attribute_limits->attribute_value_length_limit.HasValue()); + ASSERT_EQ(config->attribute_limits->attribute_value_length_limit.Value(), 1234); + ASSERT_TRUE(config->attribute_limits->attribute_count_limit.HasValue()); + ASSERT_EQ(config->attribute_limits->attribute_count_limit.Value(), 5678); +} + +TEST(Yaml, attribute_limits_null_fields) +{ + std::string yaml = R"( +file_format: "1.0" +attribute_limits: + attribute_value_length_limit: 4096 + attribute_count_limit: null +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->attribute_limits, nullptr); + ASSERT_TRUE(config->attribute_limits->attribute_value_length_limit.HasValue()); + ASSERT_EQ(config->attribute_limits->attribute_value_length_limit.Value(), 4096); + ASSERT_FALSE(config->attribute_limits->attribute_count_limit.HasValue()); +} + +TEST(Yaml, attribute_limits_tilde_null_field) +{ + std::string yaml = R"( +file_format: "1.0" +attribute_limits: + attribute_count_limit: ~ +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->attribute_limits, nullptr); + ASSERT_FALSE(config->attribute_limits->attribute_count_limit.HasValue()); } TEST(Yaml, no_optional_boolean) @@ -512,7 +544,7 @@ file_format: "1.0" auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->attribute_limits, nullptr); - ASSERT_EQ(config->attribute_limits->attribute_count_limit, 128); + ASSERT_FALSE(config->attribute_limits->attribute_count_limit.HasValue()); } TEST(Yaml, illegal_integer) @@ -540,7 +572,7 @@ file_format: "1.0" auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->attribute_limits, nullptr); - ASSERT_EQ(config->attribute_limits->attribute_count_limit, 128); + ASSERT_FALSE(config->attribute_limits->attribute_count_limit.HasValue()); } TEST(Yaml, empty_integer_substitution) @@ -556,7 +588,7 @@ file_format: "1.0" auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->attribute_limits, nullptr); - ASSERT_EQ(config->attribute_limits->attribute_count_limit, 128); + ASSERT_FALSE(config->attribute_limits->attribute_count_limit.HasValue()); } TEST(Yaml, with_integer_substitution) @@ -572,7 +604,8 @@ file_format: "1.0" auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->attribute_limits, nullptr); - ASSERT_EQ(config->attribute_limits->attribute_count_limit, 7777); + ASSERT_TRUE(config->attribute_limits->attribute_count_limit.HasValue()); + ASSERT_EQ(config->attribute_limits->attribute_count_limit.Value(), 7777); } TEST(Yaml, with_illegal_integer_substitution) diff --git a/sdk/test/configuration/yaml_trace_test.cc b/sdk/test/configuration/yaml_trace_test.cc index 1165f13ae..2a6f95bf4 100644 --- a/sdk/test/configuration/yaml_trace_test.cc +++ b/sdk/test/configuration/yaml_trace_test.cc @@ -25,6 +25,7 @@ #include "opentelemetry/sdk/configuration/headers_configuration.h" #include "opentelemetry/sdk/configuration/http_tls_configuration.h" #include "opentelemetry/sdk/configuration/jaeger_remote_sampler_configuration.h" +#include "opentelemetry/sdk/configuration/optional_value.h" #include "opentelemetry/sdk/configuration/otlp_file_span_exporter_configuration.h" #include "opentelemetry/sdk/configuration/otlp_grpc_span_exporter_configuration.h" #include "opentelemetry/sdk/configuration/otlp_http_encoding.h" @@ -605,14 +606,12 @@ file_format: "1.0-trace" ASSERT_NE(config, nullptr); ASSERT_NE(config->tracer_provider, nullptr); ASSERT_NE(config->tracer_provider->limits, nullptr); - const auto defaults = opentelemetry::sdk::configuration::SpanLimitsConfiguration{}; - ASSERT_EQ(config->tracer_provider->limits->attribute_value_length_limit, - defaults.attribute_value_length_limit); - ASSERT_EQ(config->tracer_provider->limits->attribute_count_limit, 128); - ASSERT_EQ(config->tracer_provider->limits->event_count_limit, 128); - ASSERT_EQ(config->tracer_provider->limits->link_count_limit, 128); - ASSERT_EQ(config->tracer_provider->limits->event_attribute_count_limit, 128); - ASSERT_EQ(config->tracer_provider->limits->link_attribute_count_limit, 128); + ASSERT_FALSE(config->tracer_provider->limits->attribute_value_length_limit.HasValue()); + ASSERT_FALSE(config->tracer_provider->limits->attribute_count_limit.HasValue()); + ASSERT_FALSE(config->tracer_provider->limits->event_count_limit.HasValue()); + ASSERT_FALSE(config->tracer_provider->limits->link_count_limit.HasValue()); + ASSERT_FALSE(config->tracer_provider->limits->event_attribute_count_limit.HasValue()); + ASSERT_FALSE(config->tracer_provider->limits->link_attribute_count_limit.HasValue()); } TEST(YamlTrace, limits) @@ -637,12 +636,43 @@ file_format: "1.0-trace" ASSERT_NE(config, nullptr); ASSERT_NE(config->tracer_provider, nullptr); ASSERT_NE(config->tracer_provider->limits, nullptr); - ASSERT_EQ(config->tracer_provider->limits->attribute_value_length_limit, 1111); - ASSERT_EQ(config->tracer_provider->limits->attribute_count_limit, 2222); - ASSERT_EQ(config->tracer_provider->limits->event_count_limit, 3333); - ASSERT_EQ(config->tracer_provider->limits->link_count_limit, 4444); - ASSERT_EQ(config->tracer_provider->limits->event_attribute_count_limit, 5555); - ASSERT_EQ(config->tracer_provider->limits->link_attribute_count_limit, 6666); + ASSERT_TRUE(config->tracer_provider->limits->attribute_value_length_limit.HasValue()); + ASSERT_EQ(config->tracer_provider->limits->attribute_value_length_limit.Value(), 1111); + ASSERT_TRUE(config->tracer_provider->limits->attribute_count_limit.HasValue()); + ASSERT_EQ(config->tracer_provider->limits->attribute_count_limit.Value(), 2222); + ASSERT_TRUE(config->tracer_provider->limits->event_count_limit.HasValue()); + ASSERT_EQ(config->tracer_provider->limits->event_count_limit.Value(), 3333); + ASSERT_TRUE(config->tracer_provider->limits->link_count_limit.HasValue()); + ASSERT_EQ(config->tracer_provider->limits->link_count_limit.Value(), 4444); + ASSERT_TRUE(config->tracer_provider->limits->event_attribute_count_limit.HasValue()); + ASSERT_EQ(config->tracer_provider->limits->event_attribute_count_limit.Value(), 5555); + ASSERT_TRUE(config->tracer_provider->limits->link_attribute_count_limit.HasValue()); + ASSERT_EQ(config->tracer_provider->limits->link_attribute_count_limit.Value(), 6666); +} + +TEST(YamlTrace, limits_null_fields) +{ + std::string yaml = R"( +file_format: "1.0-trace" +tracer_provider: + processors: + - simple: + exporter: + console: + limits: + attribute_value_length_limit: null + attribute_count_limit: null + event_count_limit: 64 +)"; + + auto config = DoParse(yaml); + ASSERT_NE(config, nullptr); + ASSERT_NE(config->tracer_provider, nullptr); + ASSERT_NE(config->tracer_provider->limits, nullptr); + ASSERT_FALSE(config->tracer_provider->limits->attribute_value_length_limit.HasValue()); + ASSERT_FALSE(config->tracer_provider->limits->attribute_count_limit.HasValue()); + ASSERT_TRUE(config->tracer_provider->limits->event_count_limit.HasValue()); + ASSERT_EQ(config->tracer_provider->limits->event_count_limit.Value(), 64); } TEST(YamlTrace, limits_with_invalid_values)