diff --git a/CHANGELOG.md b/CHANGELOG.md index 105676c8db..9404671299 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,9 @@ Increment the: * [CONFIGURATION] File configuration - implement distribution [#3833](https://github.com/open-telemetry/opentelemetry-cpp/pull/3833) +* [CONFIGURATION] File configuration - exemplar filter + [#3837](https://github.com/open-telemetry/opentelemetry-cpp/pull/3837) + Breaking changes: * [CONFIGURATION] File configuration - remove zipkin diff --git a/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h b/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h index 6f5204c3f9..dc5a3b77ef 100644 --- a/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h +++ b/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h @@ -29,6 +29,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/exemplar_filter.h" #include "opentelemetry/sdk/configuration/explicit_bucket_histogram_aggregation_configuration.h" #include "opentelemetry/sdk/configuration/extension_log_record_exporter_configuration.h" #include "opentelemetry/sdk/configuration/extension_log_record_processor_configuration.h" @@ -227,6 +228,9 @@ class ConfigurationParser InstrumentType ParseInstrumentType(const std::unique_ptr &node, const std::string &name) const; + ExemplarFilter ParseExemplarFilter(const std::unique_ptr &node, + const std::string &name) const; + std::unique_ptr ParseViewSelectorConfiguration( const std::unique_ptr &node) const; diff --git a/sdk/include/opentelemetry/sdk/configuration/exemplar_filter.h b/sdk/include/opentelemetry/sdk/configuration/exemplar_filter.h new file mode 100644 index 0000000000..09abafe1dc --- /dev/null +++ b/sdk/include/opentelemetry/sdk/configuration/exemplar_filter.h @@ -0,0 +1,27 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace configuration +{ + +// YAML-SCHEMA: schema/meter_provider.yaml +// YAML-NODE: ExemplarFilter +enum class ExemplarFilter : std::uint8_t +{ + always_on, + always_off, + trace_based +}; + +} // namespace configuration +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/configuration/meter_provider_configuration.h b/sdk/include/opentelemetry/sdk/configuration/meter_provider_configuration.h index 6f57de4150..3ade70f7fc 100644 --- a/sdk/include/opentelemetry/sdk/configuration/meter_provider_configuration.h +++ b/sdk/include/opentelemetry/sdk/configuration/meter_provider_configuration.h @@ -6,6 +6,7 @@ #include #include +#include "opentelemetry/sdk/configuration/exemplar_filter.h" #include "opentelemetry/sdk/configuration/metric_reader_configuration.h" #include "opentelemetry/sdk/configuration/view_configuration.h" #include "opentelemetry/version.h" @@ -16,14 +17,14 @@ namespace sdk namespace configuration { -// YAML-SCHEMA: schema/meter_provider.json +// YAML-SCHEMA: schema/meter_provider.yaml // YAML-NODE: MeterProvider class MeterProviderConfiguration { public: std::vector> readers; std::vector> views; - // FIXME: exemplar_filter + ExemplarFilter exemplar_filter = ExemplarFilter::trace_based; // FIXME: meter_configurator }; diff --git a/sdk/src/configuration/configuration_parser.cc b/sdk/src/configuration/configuration_parser.cc index 7cef6e6fa7..702a093275 100644 --- a/sdk/src/configuration/configuration_parser.cc +++ b/sdk/src/configuration/configuration_parser.cc @@ -38,6 +38,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/exemplar_filter.h" #include "opentelemetry/sdk/configuration/explicit_bucket_histogram_aggregation_configuration.h" #include "opentelemetry/sdk/configuration/extension_log_record_exporter_configuration.h" #include "opentelemetry/sdk/configuration/extension_log_record_processor_configuration.h" @@ -1171,6 +1172,34 @@ InstrumentType ConfigurationParser::ParseInstrumentType(const std::unique_ptrLocation(), message); } +ExemplarFilter ConfigurationParser::ParseExemplarFilter(const std::unique_ptr &node, + const std::string &name) const +{ + if (name == "") + { + return ExemplarFilter::trace_based; + } + + if (name == "always_on") + { + return ExemplarFilter::always_on; + } + + if (name == "always_off") + { + return ExemplarFilter::always_off; + } + + if (name == "trace_based") + { + return ExemplarFilter::trace_based; + } + + std::string message("Illegal exemplar filter: "); + message.append(name); + throw InvalidSchemaException(node->Location(), message); +} + std::unique_ptr ConfigurationParser::ParseViewSelectorConfiguration( const std::unique_ptr &node) const { @@ -1384,7 +1413,8 @@ std::unique_ptr ConfigurationParser::ParseMeterProvi } } - // FIXME: exemplar_filter + std::string exemplar_filter = node->GetString("exemplar_filter", "trace_based"); + model->exemplar_filter = ParseExemplarFilter(node, exemplar_filter); // FIXME: meter_configurator/development diff --git a/sdk/src/configuration/sdk_builder.cc b/sdk/src/configuration/sdk_builder.cc index faffcf2301..17751ba7df 100644 --- a/sdk/src/configuration/sdk_builder.cc +++ b/sdk/src/configuration/sdk_builder.cc @@ -125,6 +125,7 @@ #include "opentelemetry/sdk/logs/processor.h" #include "opentelemetry/sdk/logs/simple_log_record_processor_factory.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation_config.h" +#include "opentelemetry/sdk/metrics/exemplar/filter_type.h" #include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_factory.h" #include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_options.h" #include "opentelemetry/sdk/metrics/instruments.h" @@ -155,6 +156,10 @@ #include "opentelemetry/sdk/trace/tracer_provider_factory.h" #include "opentelemetry/version.h" +#ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW +# include "opentelemetry/sdk/configuration/exemplar_filter.h" +#endif + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { @@ -1149,6 +1154,33 @@ static opentelemetry::sdk::metrics::InstrumentType ConvertInstrumentType( return sdk; } +#ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW + +static opentelemetry::sdk::metrics::ExemplarFilterType ConvertExemplarFilter( + enum opentelemetry::sdk::configuration::ExemplarFilter config) +{ + opentelemetry::sdk::metrics::ExemplarFilterType sdk{ + opentelemetry::sdk::metrics::ExemplarFilterType::kTraceBased}; + + switch (config) + { + case opentelemetry::sdk::configuration::ExemplarFilter::always_on: + sdk = opentelemetry::sdk::metrics::ExemplarFilterType::kAlwaysOn; + break; + case opentelemetry::sdk::configuration::ExemplarFilter::always_off: + sdk = opentelemetry::sdk::metrics::ExemplarFilterType::kAlwaysOff; + break; + case opentelemetry::sdk::configuration::ExemplarFilter::trace_based: + sdk = opentelemetry::sdk::metrics::ExemplarFilterType::kTraceBased; + break; + default: + break; + } + + return sdk; +} +#endif /* ENABLE_METRICS_EXEMPLAR_PREVIEW */ + std::unique_ptr SdkBuilder::CreateOtlpHttpPushMetricExporter( const opentelemetry::sdk::configuration::OtlpHttpPushMetricExporterConfiguration *model) const @@ -1500,6 +1532,17 @@ std::unique_ptr SdkBuilder::CreateMe meter_context->AddMetricReader(metric_reader); } +#ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW + auto sdk_exemplar_filter = ConvertExemplarFilter(model->exemplar_filter); + meter_context->SetExemplarFilter(sdk_exemplar_filter); +#else + /* Do not spam with warnings if disabled anyway. */ + if (model->exemplar_filter != ExemplarFilter::always_off) + { + OTEL_INTERNAL_LOG_WARN("ENABLE_METRICS_EXEMPLAR_PREVIEW not set, ignoring exemplar filter"); + } +#endif /* ENABLE_METRICS_EXEMPLAR_PREVIEW */ + sdk = opentelemetry::sdk::metrics::MeterProviderFactory::Create(std::move(meter_context)); return sdk; diff --git a/sdk/test/configuration/yaml_metrics_test.cc b/sdk/test/configuration/yaml_metrics_test.cc index f0f49a6943..5dff4e674c 100644 --- a/sdk/test/configuration/yaml_metrics_test.cc +++ b/sdk/test/configuration/yaml_metrics_test.cc @@ -11,6 +11,7 @@ #include "opentelemetry/sdk/configuration/cardinality_limits_configuration.h" #include "opentelemetry/sdk/configuration/configuration.h" #include "opentelemetry/sdk/configuration/default_histogram_aggregation.h" +#include "opentelemetry/sdk/configuration/exemplar_filter.h" #include "opentelemetry/sdk/configuration/explicit_bucket_histogram_aggregation_configuration.h" #include "opentelemetry/sdk/configuration/grpc_tls_configuration.h" #include "opentelemetry/sdk/configuration/headers_configuration.h" @@ -98,6 +99,8 @@ file_format: "1.0-metrics" auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->meter_provider, nullptr); + ASSERT_EQ(config->meter_provider->exemplar_filter, + opentelemetry::sdk::configuration::ExemplarFilter::trace_based); ASSERT_EQ(config->meter_provider->readers.size(), 1); auto *reader = config->meter_provider->readers[0].get(); ASSERT_NE(reader, nullptr); @@ -133,11 +136,14 @@ file_format: "1.0-metrics" observable_gauge: 600 observable_up_down_counter: 700 up_down_counter: 800 + exemplar_filter: always_on )"; auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->meter_provider, nullptr); + ASSERT_EQ(config->meter_provider->exemplar_filter, + opentelemetry::sdk::configuration::ExemplarFilter::always_on); ASSERT_EQ(config->meter_provider->readers.size(), 1); auto *reader = config->meter_provider->readers[0].get(); ASSERT_NE(reader, nullptr); @@ -170,11 +176,14 @@ file_format: "1.0-metrics" - pull: exporter: prometheus/development: + exemplar_filter: always_off )"; auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->meter_provider, nullptr); + ASSERT_EQ(config->meter_provider->exemplar_filter, + opentelemetry::sdk::configuration::ExemplarFilter::always_off); ASSERT_EQ(config->meter_provider->readers.size(), 1); auto *reader = config->meter_provider->readers[0].get(); ASSERT_NE(reader, nullptr); @@ -205,11 +214,14 @@ file_format: "1.0-metrics" observable_gauge: 600 observable_up_down_counter: 700 up_down_counter: 800 + exemplar_filter: trace_based )"; auto config = DoParse(yaml); ASSERT_NE(config, nullptr); ASSERT_NE(config->meter_provider, nullptr); + ASSERT_EQ(config->meter_provider->exemplar_filter, + opentelemetry::sdk::configuration::ExemplarFilter::trace_based); ASSERT_EQ(config->meter_provider->readers.size(), 1); auto *reader = config->meter_provider->readers[0].get(); ASSERT_NE(reader, nullptr);