From 2f0740f0434677c800b18ae8b7dd2d6620552379 Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Wed, 4 Dec 2024 01:26:21 +0000 Subject: [PATCH 1/9] [OTLP EXPORTER] include instrumentation scope attributes in otlp messages for metrics and traces --- .../otlp/otlp_populate_attribute_utils.h | 6 ++++ exporters/otlp/src/otlp_metric_utils.cc | 6 +++- .../otlp/src/otlp_populate_attribute_utils.cc | 17 +++++++++ exporters/otlp/src/otlp_recordable.cc | 1 + exporters/otlp/src/otlp_recordable_utils.cc | 9 +++-- .../otlp/test/otlp_file_exporter_test.cc | 35 +++++++++++++++++-- .../otlp_file_log_record_exporter_test.cc | 29 +++++++++++---- .../test/otlp_file_metric_exporter_test.cc | 23 +++++++++--- exporters/otlp/test/otlp_recordable_test.cc | 25 +++++++++++++ 9 files changed, 132 insertions(+), 19 deletions(-) diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_populate_attribute_utils.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_populate_attribute_utils.h index 499aa3685f..441d1d3c58 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_populate_attribute_utils.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_populate_attribute_utils.h @@ -6,6 +6,7 @@ #include "opentelemetry/common/attribute_value.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/version.h" @@ -20,6 +21,7 @@ namespace v1 { class AnyValue; class KeyValue; +class InstrumentationScope; } // namespace v1 } // namespace common @@ -49,6 +51,10 @@ class OtlpPopulateAttributeUtils static void PopulateAttribute(opentelemetry::proto::resource::v1::Resource *proto, const opentelemetry::sdk::resource::Resource &resource) noexcept; + static void PopulateAttribute(opentelemetry::proto::common::v1::InstrumentationScope *proto, + const opentelemetry::sdk::instrumentationscope::InstrumentationScope + &instrumentation_scope) noexcept; + static void PopulateAnyValue(opentelemetry::proto::common::v1::AnyValue *proto_value, const opentelemetry::common::AttributeValue &value) noexcept; diff --git a/exporters/otlp/src/otlp_metric_utils.cc b/exporters/otlp/src/otlp_metric_utils.cc index c8502d65c5..35aaece190 100644 --- a/exporters/otlp/src/otlp_metric_utils.cc +++ b/exporters/otlp/src/otlp_metric_utils.cc @@ -242,6 +242,8 @@ void OtlpMetricUtils::PopulateResourceMetrics( OtlpPopulateAttributeUtils::PopulateAttribute(resource_metrics->mutable_resource(), *(data.resource_)); + resource_metrics->set_schema_url(data.resource_->GetSchemaURL()); + for (auto &scope_metrics : data.scope_metric_data_) { if (scope_metrics.scope_ == nullptr) @@ -252,7 +254,9 @@ void OtlpMetricUtils::PopulateResourceMetrics( proto::common::v1::InstrumentationScope *scope = scope_lib_metrics->mutable_scope(); scope->set_name(scope_metrics.scope_->GetName()); scope->set_version(scope_metrics.scope_->GetVersion()); - resource_metrics->set_schema_url(scope_metrics.scope_->GetSchemaURL()); + scope_lib_metrics->set_schema_url(scope_metrics.scope_->GetSchemaURL()); + + OtlpPopulateAttributeUtils::PopulateAttribute(scope, *scope_metrics.scope_); for (auto &metric_data : scope_metrics.metric_data_) { diff --git a/exporters/otlp/src/otlp_populate_attribute_utils.cc b/exporters/otlp/src/otlp_populate_attribute_utils.cc index 490e4c771b..c1a87080ed 100644 --- a/exporters/otlp/src/otlp_populate_attribute_utils.cc +++ b/exporters/otlp/src/otlp_populate_attribute_utils.cc @@ -15,6 +15,7 @@ #include "opentelemetry/nostd/utility.h" #include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/version.h" @@ -315,6 +316,22 @@ void OtlpPopulateAttributeUtils::PopulateAttribute( } } +void OtlpPopulateAttributeUtils::PopulateAttribute( + opentelemetry::proto::common::v1::InstrumentationScope *proto, + const opentelemetry::sdk::instrumentationscope::InstrumentationScope + &instrumentation_scope) noexcept +{ + if (nullptr == proto) + { + return; + } + + for (const auto &kv : instrumentation_scope.GetAttributes()) + { + OtlpPopulateAttributeUtils::PopulateAttribute(proto->add_attributes(), kv.first, kv.second); + } +} + } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/otlp/src/otlp_recordable.cc b/exporters/otlp/src/otlp_recordable.cc index 356472fb48..0cf3dbeb08 100644 --- a/exporters/otlp/src/otlp_recordable.cc +++ b/exporters/otlp/src/otlp_recordable.cc @@ -107,6 +107,7 @@ proto::common::v1::InstrumentationScope OtlpRecordable::GetProtoInstrumentationS { instrumentation_scope.set_name(instrumentation_scope_->GetName()); instrumentation_scope.set_version(instrumentation_scope_->GetVersion()); + OtlpPopulateAttributeUtils::PopulateAttribute(&instrumentation_scope, *instrumentation_scope_); } return instrumentation_scope; } diff --git a/exporters/otlp/src/otlp_recordable_utils.cc b/exporters/otlp/src/otlp_recordable_utils.cc index df29cca838..1be27204c7 100644 --- a/exporters/otlp/src/otlp_recordable_utils.cc +++ b/exporters/otlp/src/otlp_recordable_utils.cc @@ -107,6 +107,9 @@ void OtlpRecordableUtils::PopulateRequest( proto::common::v1::InstrumentationScope instrumentation_scope_proto; instrumentation_scope_proto.set_name(input_scope_spans.first->GetName()); instrumentation_scope_proto.set_version(input_scope_spans.first->GetVersion()); + OtlpPopulateAttributeUtils::PopulateAttribute(&instrumentation_scope_proto, + *input_scope_spans.first); + *scope_spans->mutable_scope() = instrumentation_scope_proto; scope_spans->set_schema_url(input_scope_spans.first->GetSchemaURL()); } @@ -170,11 +173,7 @@ void OtlpRecordableUtils::PopulateRequest( proto_scope->set_name(input_scope_log.first->GetName()); proto_scope->set_version(input_scope_log.first->GetVersion()); - for (auto &scope_attribute : input_scope_log.first->GetAttributes()) - { - OtlpPopulateAttributeUtils::PopulateAttribute( - proto_scope->add_attributes(), scope_attribute.first, scope_attribute.second); - } + OtlpPopulateAttributeUtils::PopulateAttribute(proto_scope, *input_scope_log.first); } output_scope_log->set_schema_url(input_scope_log.first->GetSchemaURL()); } diff --git a/exporters/otlp/test/otlp_file_exporter_test.cc b/exporters/otlp/test/otlp_file_exporter_test.cc index 575339c621..c61af6abfd 100644 --- a/exporters/otlp/test/otlp_file_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_exporter_test.cc @@ -108,11 +108,27 @@ class OtlpFileExporterTestPeer : public ::testing::Test new sdk::trace::TracerProvider(std::move(processor), resource)); std::string report_trace_id; + + const std::string instrumentation_scope_name{"test"}; + const std::string instrumentation_scope_version{"1.2.3"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + const std::vector> + instrumentation_scope_attributes{{"scope_key1", "scope_value"}, + { "scope_key2", + 2 }}; + auto tracer = provider->GetTracer(instrumentation_scope_name, instrumentation_scope_version, + schema_url, instrumentation_scope_attributes); +#else + auto tracer = + provider->GetTracer(instrumentation_scope_name, instrumentation_scope_version, schema_url); +#endif - char trace_id_hex[2 * trace_api::TraceId::kSize] = {0}; - auto tracer = provider->GetTracer("test"); auto parent_span = tracer->StartSpan("Test parent span"); + char trace_id_hex[2 * trace_api::TraceId::kSize] = {0}; + trace_api::StartSpanOptions child_span_opts = {}; child_span_opts.parent = parent_span->GetContext(); @@ -138,8 +154,21 @@ class OtlpFileExporterTestPeer : public ::testing::Test { auto resource_span = *check_json["resourceSpans"].begin(); auto scope_span = *resource_span["scopeSpans"].begin(); + auto scope = scope_span["scope"]; auto span = *scope_span["spans"].begin(); - auto received_trace_id = span["traceId"].get(); + + const std::string received_schema_url = scope_span["schemaUrl"].get(); + const std::string received_instrumentation_scope_name = scope["name"].get(); + const std::string received_instrumentation_scope_version = scope["version"].get(); + const auto received_trace_id = span["traceId"].get(); + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + const auto scope_attributes_json = scope["attributes"]; + EXPECT_EQ(scope_attributes_json.size(), instrumentation_scope_attributes.size()) << scope_attributes_json; +#endif + EXPECT_EQ(received_schema_url, schema_url); + EXPECT_EQ(received_instrumentation_scope_name, instrumentation_scope_name); + EXPECT_EQ(received_instrumentation_scope_version, instrumentation_scope_version); EXPECT_EQ(received_trace_id, report_trace_id); } else diff --git a/exporters/otlp/test/otlp_file_log_record_exporter_test.cc b/exporters/otlp/test/otlp_file_log_record_exporter_test.cc index 4bfd649069..0051b0850e 100644 --- a/exporters/otlp/test/otlp_file_log_record_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_log_record_exporter_test.cc @@ -100,9 +100,15 @@ class OtlpFileLogRecordExporterTestPeer : public ::testing::Test char span_id_hex[2 * opentelemetry::trace::SpanId::kSize] = {0}; opentelemetry::trace::SpanId span_id{span_id_bin}; + const std::string instrumentation_scope_name{"opentelelemtry_library"}; + const std::string instrumentation_scope_version{"1.2.3"}; const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; - auto logger = provider->GetLogger("test", "opentelelemtry_library", "", schema_url, - {{"scope_key1", "scope_value"}, {"scope_key2", 2}}); + const std::vector> + instrumentation_scope_attributes{{"scope_key1", "scope_value"}, + { "scope_key2", + 2 }}; + + auto logger = provider->GetLogger("test", instrumentation_scope_name, instrumentation_scope_version, schema_url, instrumentation_scope_attributes); trace_id.ToLowerBase16(MakeSpan(trace_id_hex)); report_trace_id.assign(trace_id_hex, sizeof(trace_id_hex)); @@ -143,16 +149,27 @@ class OtlpFileLogRecordExporterTestPeer : public ::testing::Test auto scope_logs = *resource_logs["scopeLogs"].begin(); auto scope = scope_logs["scope"]; auto log = *scope_logs["logRecords"].begin(); - auto received_trace_id = log["traceId"].get(); - auto received_span_id = log["spanId"].get(); + + const auto received_schema_url = scope_logs["schemaUrl"].get(); + const auto received_instrumentation_scope_name = scope["name"].get(); + const auto received_instrumentation_scope_version = scope["version"].get(); + const auto received_instrumentation_scope_attributes = scope["attributes"]; + const auto received_trace_id = log["traceId"].get(); + const auto received_span_id = log["spanId"].get(); + + EXPECT_EQ(received_instrumentation_scope_attributes.size(), instrumentation_scope_attributes.size()) + << received_instrumentation_scope_attributes; + EXPECT_EQ(received_schema_url, schema_url); + EXPECT_EQ(received_instrumentation_scope_name, instrumentation_scope_name); + EXPECT_EQ(received_instrumentation_scope_version, instrumentation_scope_version); + EXPECT_EQ(received_trace_id, report_trace_id); EXPECT_EQ(received_span_id, report_span_id); EXPECT_EQ("Log message", log["body"]["stringValue"].get()); EXPECT_LE(15, log["attributes"].size()); bool check_scope_attribute = false; - auto scope_attributes = scope["attributes"]; - for (auto &attribute : scope_attributes) + for (auto &attribute : received_instrumentation_scope_attributes) { if (!attribute.is_object()) { diff --git a/exporters/otlp/test/otlp_file_metric_exporter_test.cc b/exporters/otlp/test/otlp_file_metric_exporter_test.cc index f79e2280b6..dbf8c48754 100644 --- a/exporters/otlp/test/otlp_file_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_metric_exporter_test.cc @@ -88,8 +88,19 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test auto resource = opentelemetry::sdk::resource::Resource::Create( opentelemetry::sdk::resource::ResourceAttributes{}); data.resource_ = &resource; - auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create( - "library_name", "1.5.0"); + + const std::string instrumentation_scope_name{"library_name"}; + const std::string instrumentation_scope_version{"1.5.0"}; + const std::string instrumentation_scope_schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::vector> + instrumentation_scope_attributes{{"scope_key1", "scope_value"}, + { "scope_key2", + 2 }}; + + auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create( + instrumentation_scope_name, instrumentation_scope_version, instrumentation_scope_schema_url, + instrumentation_scope_attributes); + opentelemetry::sdk::metrics::MetricData metric_data{ opentelemetry::sdk::metrics::InstrumentDescriptor{ "metrics_library_name", "metrics_description", "metrics_unit", @@ -100,6 +111,7 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test std::vector{ {opentelemetry::sdk::metrics::PointAttributes{{"a1", "b1"}}, sum_point_data}, {opentelemetry::sdk::metrics::PointAttributes{{"a2", "b2"}}, sum_point_data2}}}; + data.scope_metric_data_ = std::vector{ {scope.get(), std::vector{metric_data}}}; @@ -111,6 +123,7 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test output.flush(); output.sync(); auto check_json_text = output.str(); + if (!check_json_text.empty()) { auto check_json = nlohmann::json::parse(check_json_text, nullptr, false); @@ -118,8 +131,10 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test auto resource_metrics = *check_json["resourceMetrics"].begin(); auto scope_metrics = *resource_metrics["scopeMetrics"].begin(); auto scope = scope_metrics["scope"]; - EXPECT_EQ("library_name", scope["name"].get()); - EXPECT_EQ("1.5.0", scope["version"].get()); + + EXPECT_EQ(instrumentation_scope_schema_url, scope_metrics["schemaUrl"].get()); + EXPECT_EQ(instrumentation_scope_name, scope["name"].get()); + EXPECT_EQ(instrumentation_scope_version, scope["version"].get()); auto metric = *scope_metrics["metrics"].begin(); EXPECT_EQ("metrics_library_name", metric["name"].get()); diff --git a/exporters/otlp/test/otlp_recordable_test.cc b/exporters/otlp/test/otlp_recordable_test.cc index 9e148e60ee..7cf5478ba2 100644 --- a/exporters/otlp/test/otlp_recordable_test.cc +++ b/exporters/otlp/test/otlp_recordable_test.cc @@ -119,6 +119,31 @@ TEST(OtlpRecordable, SetInstrumentationLibraryWithSchemaURL) EXPECT_EQ(expected_schema_url, rec.GetInstrumentationLibrarySchemaURL()); } +TEST(OtlpRecordable, SetInstrumentationScopeWithAttributes) +{ + exporter::otlp::OtlpRecordable rec; + const std::string expected_attribute_key{"test_key"}; + const std::string expected_attribute_value{"test_value"}; + + auto inst_lib = trace_sdk::InstrumentationScope::Create( + "test", "v1", "", {{expected_attribute_key, expected_attribute_value}}); + + ASSERT_EQ(inst_lib->GetAttributes().size(), 1); + + rec.SetInstrumentationScope(*inst_lib); + + const auto proto_instr_libr = rec.GetProtoInstrumentationScope(); + + ASSERT_EQ(proto_instr_libr.attributes_size(), 1); + + const auto &proto_attributes = proto_instr_libr.attributes(0); + + ASSERT_TRUE(proto_attributes.value().has_string_value()); + + EXPECT_EQ(expected_attribute_key, proto_attributes.key()); + EXPECT_EQ(expected_attribute_value, proto_attributes.value().string_value()); +} + TEST(OtlpRecordable, SetStartTime) { OtlpRecordable rec; From f18869b16d2b5b2e063cff40c2a13bb4e4d34ac1 Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Thu, 5 Dec 2024 00:05:22 +0000 Subject: [PATCH 2/9] clean up tests for setting metrics and traces instrumenation scope attributes with otlp exporters --- .../otlp/test/otlp_file_exporter_test.cc | 38 +++++++------------ .../otlp_file_log_record_exporter_test.cc | 29 +++----------- .../test/otlp_file_metric_exporter_test.cc | 19 +++++++--- exporters/otlp/test/otlp_recordable_test.cc | 32 ++++++++++------ 4 files changed, 53 insertions(+), 65 deletions(-) diff --git a/exporters/otlp/test/otlp_file_exporter_test.cc b/exporters/otlp/test/otlp_file_exporter_test.cc index c61af6abfd..be7674f6eb 100644 --- a/exporters/otlp/test/otlp_file_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_exporter_test.cc @@ -70,6 +70,7 @@ static nostd::span MakeSpan(T (&array)[N]) class OtlpFileExporterTestPeer : public ::testing::Test { public: + void ExportJsonIntegrationTest() { static ProtobufGlobalSymbolGuard global_symbol_guard; @@ -95,7 +96,7 @@ class OtlpFileExporterTestPeer : public ::testing::Test resource_attributes["vec_uint64_value"] = std::vector{7, 8}; resource_attributes["vec_double_value"] = std::vector{3.2, 3.3}; resource_attributes["vec_string_value"] = std::vector{"vector", "string"}; - auto resource = resource::Resource::Create(resource_attributes); + auto resource = resource::Resource::Create(resource_attributes, "resource_url"); auto processor_opts = sdk::trace::BatchSpanProcessorOptions(); processor_opts.max_export_batch_size = 5; @@ -109,20 +110,11 @@ class OtlpFileExporterTestPeer : public ::testing::Test std::string report_trace_id; - const std::string instrumentation_scope_name{"test"}; - const std::string instrumentation_scope_version{"1.2.3"}; - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - const std::vector> - instrumentation_scope_attributes{{"scope_key1", "scope_value"}, - { "scope_key2", - 2 }}; - auto tracer = provider->GetTracer(instrumentation_scope_name, instrumentation_scope_version, - schema_url, instrumentation_scope_attributes); +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url", {{"scope_key", "scope_value"}}); #else auto tracer = - provider->GetTracer(instrumentation_scope_name, instrumentation_scope_version, schema_url); + provider->GetTracer("scope_name", "scope_version", "scope_url"); #endif auto parent_span = tracer->StartSpan("Test parent span"); @@ -157,19 +149,17 @@ class OtlpFileExporterTestPeer : public ::testing::Test auto scope = scope_span["scope"]; auto span = *scope_span["spans"].begin(); - const std::string received_schema_url = scope_span["schemaUrl"].get(); - const std::string received_instrumentation_scope_name = scope["name"].get(); - const std::string received_instrumentation_scope_version = scope["version"].get(); - const auto received_trace_id = span["traceId"].get(); - #if OPENTELEMETRY_ABI_VERSION_NO >= 2 - const auto scope_attributes_json = scope["attributes"]; - EXPECT_EQ(scope_attributes_json.size(), instrumentation_scope_attributes.size()) << scope_attributes_json; + ASSERT_EQ(1, scope["attributes"].size()); + const auto scope_attribute = scope["attributes"].front(); + EXPECT_EQ("scope_key", scope_attribute["key"].get()); + EXPECT_EQ("scope_value", scope_attribute["value"]["stringValue"].get()); #endif - EXPECT_EQ(received_schema_url, schema_url); - EXPECT_EQ(received_instrumentation_scope_name, instrumentation_scope_name); - EXPECT_EQ(received_instrumentation_scope_version, instrumentation_scope_version); - EXPECT_EQ(received_trace_id, report_trace_id); + EXPECT_EQ("resource_url", resource_span["schemaUrl"].get()); + EXPECT_EQ("scope_url", scope_span["schemaUrl"].get()); + EXPECT_EQ("scope_name", scope["name"].get()); + EXPECT_EQ("scope_version", scope["version"].get()); + EXPECT_EQ(report_trace_id, span["traceId"].get()); } else { diff --git a/exporters/otlp/test/otlp_file_log_record_exporter_test.cc b/exporters/otlp/test/otlp_file_log_record_exporter_test.cc index 0051b0850e..4bfd649069 100644 --- a/exporters/otlp/test/otlp_file_log_record_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_log_record_exporter_test.cc @@ -100,15 +100,9 @@ class OtlpFileLogRecordExporterTestPeer : public ::testing::Test char span_id_hex[2 * opentelemetry::trace::SpanId::kSize] = {0}; opentelemetry::trace::SpanId span_id{span_id_bin}; - const std::string instrumentation_scope_name{"opentelelemtry_library"}; - const std::string instrumentation_scope_version{"1.2.3"}; const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; - const std::vector> - instrumentation_scope_attributes{{"scope_key1", "scope_value"}, - { "scope_key2", - 2 }}; - - auto logger = provider->GetLogger("test", instrumentation_scope_name, instrumentation_scope_version, schema_url, instrumentation_scope_attributes); + auto logger = provider->GetLogger("test", "opentelelemtry_library", "", schema_url, + {{"scope_key1", "scope_value"}, {"scope_key2", 2}}); trace_id.ToLowerBase16(MakeSpan(trace_id_hex)); report_trace_id.assign(trace_id_hex, sizeof(trace_id_hex)); @@ -149,27 +143,16 @@ class OtlpFileLogRecordExporterTestPeer : public ::testing::Test auto scope_logs = *resource_logs["scopeLogs"].begin(); auto scope = scope_logs["scope"]; auto log = *scope_logs["logRecords"].begin(); - - const auto received_schema_url = scope_logs["schemaUrl"].get(); - const auto received_instrumentation_scope_name = scope["name"].get(); - const auto received_instrumentation_scope_version = scope["version"].get(); - const auto received_instrumentation_scope_attributes = scope["attributes"]; - const auto received_trace_id = log["traceId"].get(); - const auto received_span_id = log["spanId"].get(); - - EXPECT_EQ(received_instrumentation_scope_attributes.size(), instrumentation_scope_attributes.size()) - << received_instrumentation_scope_attributes; - EXPECT_EQ(received_schema_url, schema_url); - EXPECT_EQ(received_instrumentation_scope_name, instrumentation_scope_name); - EXPECT_EQ(received_instrumentation_scope_version, instrumentation_scope_version); - + auto received_trace_id = log["traceId"].get(); + auto received_span_id = log["spanId"].get(); EXPECT_EQ(received_trace_id, report_trace_id); EXPECT_EQ(received_span_id, report_span_id); EXPECT_EQ("Log message", log["body"]["stringValue"].get()); EXPECT_LE(15, log["attributes"].size()); bool check_scope_attribute = false; - for (auto &attribute : received_instrumentation_scope_attributes) + auto scope_attributes = scope["attributes"]; + for (auto &attribute : scope_attributes) { if (!attribute.is_object()) { diff --git a/exporters/otlp/test/otlp_file_metric_exporter_test.cc b/exporters/otlp/test/otlp_file_metric_exporter_test.cc index dbf8c48754..699d73e21d 100644 --- a/exporters/otlp/test/otlp_file_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_metric_exporter_test.cc @@ -85,21 +85,20 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test opentelemetry::sdk::metrics::SumPointData sum_point_data2{}; sum_point_data2.value_ = 20.0; opentelemetry::sdk::metrics::ResourceMetrics data; + + const std::string resource_schema_url{"https://opentelemetry.io/schemas/1.2.1"}; + auto resource = opentelemetry::sdk::resource::Resource::Create( - opentelemetry::sdk::resource::ResourceAttributes{}); + opentelemetry::sdk::resource::ResourceAttributes{}, resource_schema_url); data.resource_ = &resource; const std::string instrumentation_scope_name{"library_name"}; const std::string instrumentation_scope_version{"1.5.0"}; const std::string instrumentation_scope_schema_url{"https://opentelemetry.io/schemas/1.2.0"}; - const std::vector> - instrumentation_scope_attributes{{"scope_key1", "scope_value"}, - { "scope_key2", - 2 }}; auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create( instrumentation_scope_name, instrumentation_scope_version, instrumentation_scope_schema_url, - instrumentation_scope_attributes); + {{"scope_key", "scope_value"}}); opentelemetry::sdk::metrics::MetricData metric_data{ opentelemetry::sdk::metrics::InstrumentDescriptor{ @@ -131,10 +130,18 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test auto resource_metrics = *check_json["resourceMetrics"].begin(); auto scope_metrics = *resource_metrics["scopeMetrics"].begin(); auto scope = scope_metrics["scope"]; + + + EXPECT_EQ(resource_schema_url, resource_metrics["schemaUrl"].get()); EXPECT_EQ(instrumentation_scope_schema_url, scope_metrics["schemaUrl"].get()); EXPECT_EQ(instrumentation_scope_name, scope["name"].get()); EXPECT_EQ(instrumentation_scope_version, scope["version"].get()); + ASSERT_EQ(1, scope["attributes"].size()); + const auto scope_attribute = scope["attributes"].front(); + EXPECT_EQ("scope_key", scope_attribute["key"].get()); + EXPECT_EQ("scope_value", scope_attribute["value"]["stringValue"].get()); + auto metric = *scope_metrics["metrics"].begin(); EXPECT_EQ("metrics_library_name", metric["name"].get()); diff --git a/exporters/otlp/test/otlp_recordable_test.cc b/exporters/otlp/test/otlp_recordable_test.cc index 7cf5478ba2..1b95298b29 100644 --- a/exporters/otlp/test/otlp_recordable_test.cc +++ b/exporters/otlp/test/otlp_recordable_test.cc @@ -122,26 +122,23 @@ TEST(OtlpRecordable, SetInstrumentationLibraryWithSchemaURL) TEST(OtlpRecordable, SetInstrumentationScopeWithAttributes) { exporter::otlp::OtlpRecordable rec; - const std::string expected_attribute_key{"test_key"}; - const std::string expected_attribute_value{"test_value"}; auto inst_lib = trace_sdk::InstrumentationScope::Create( - "test", "v1", "", {{expected_attribute_key, expected_attribute_value}}); + "test_scope_name", "test_version", "test_schema_url", {{"test_key", "test_value"}}); ASSERT_EQ(inst_lib->GetAttributes().size(), 1); rec.SetInstrumentationScope(*inst_lib); const auto proto_instr_libr = rec.GetProtoInstrumentationScope(); + EXPECT_EQ("test_scope_name", proto_instr_libr.name()); + EXPECT_EQ("test_version", proto_instr_libr.version()); ASSERT_EQ(proto_instr_libr.attributes_size(), 1); - const auto &proto_attributes = proto_instr_libr.attributes(0); - ASSERT_TRUE(proto_attributes.value().has_string_value()); - - EXPECT_EQ(expected_attribute_key, proto_attributes.key()); - EXPECT_EQ(expected_attribute_value, proto_attributes.value().string_value()); + EXPECT_EQ("test_key", proto_attributes.key()); + EXPECT_EQ("test_value", proto_attributes.value().string_value()); } TEST(OtlpRecordable, SetStartTime) @@ -349,7 +346,7 @@ TEST(OtlpRecordable, PopulateRequest) auto rec1 = std::unique_ptr(new OtlpRecordable); auto resource1 = resource::Resource::Create({{"service.name", "one"}}); rec1->SetResource(resource1); - auto inst_lib1 = trace_sdk::InstrumentationScope::Create("one", "1"); + auto inst_lib1 = trace_sdk::InstrumentationScope::Create("one", "1", "scope_schema", {{"scope_key", "scope_value"}}); rec1->SetInstrumentationScope(*inst_lib1); auto rec2 = std::unique_ptr(new OtlpRecordable); @@ -375,12 +372,23 @@ TEST(OtlpRecordable, PopulateRequest) EXPECT_EQ(req.resource_spans().size(), 2); for (const auto &resource_spans : req.resource_spans()) { - auto service_name = resource_spans.resource().attributes(0).value().string_value(); - auto scope_spans_size = resource_spans.scope_spans().size(); + ASSERT_GT(resource_spans.resource().attributes_size(), 0); + const auto service_name = resource_spans.resource().attributes(0).value().string_value(); + const auto scope_spans_size = resource_spans.scope_spans().size(); if (service_name == "one") { + ASSERT_GT(resource_spans.scope_spans_size(), 0); + const auto& scope_one = resource_spans.scope_spans(0).scope(); + EXPECT_EQ(scope_spans_size, 1); - EXPECT_EQ(resource_spans.scope_spans(0).scope().name(), "one"); + EXPECT_EQ(scope_one.name(), "one"); + EXPECT_EQ(scope_one.version(), "1"); + + ASSERT_EQ(scope_one.attributes_size(), 1); + const auto& scope_attribute = scope_one.attributes(0); + + EXPECT_EQ(scope_attribute.key(), "scope_key"); + EXPECT_EQ(scope_attribute.value().string_value(), "scope_value"); } if (service_name == "two") { From 61e5dff7504e8a1053126ee741699c2e450804a8 Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Thu, 5 Dec 2024 00:08:44 +0000 Subject: [PATCH 3/9] run clang-format --- exporters/otlp/src/otlp_metric_utils.cc | 2 +- .../otlp/test/otlp_file_exporter_test.cc | 32 +++++++++---------- .../test/otlp_file_metric_exporter_test.cc | 12 +++---- exporters/otlp/test/otlp_recordable_test.cc | 13 ++++---- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/exporters/otlp/src/otlp_metric_utils.cc b/exporters/otlp/src/otlp_metric_utils.cc index 35aaece190..521a7e2f10 100644 --- a/exporters/otlp/src/otlp_metric_utils.cc +++ b/exporters/otlp/src/otlp_metric_utils.cc @@ -254,7 +254,7 @@ void OtlpMetricUtils::PopulateResourceMetrics( proto::common::v1::InstrumentationScope *scope = scope_lib_metrics->mutable_scope(); scope->set_name(scope_metrics.scope_->GetName()); scope->set_version(scope_metrics.scope_->GetVersion()); - scope_lib_metrics->set_schema_url(scope_metrics.scope_->GetSchemaURL()); + scope_lib_metrics->set_schema_url(scope_metrics.scope_->GetSchemaURL()); OtlpPopulateAttributeUtils::PopulateAttribute(scope, *scope_metrics.scope_); diff --git a/exporters/otlp/test/otlp_file_exporter_test.cc b/exporters/otlp/test/otlp_file_exporter_test.cc index be7674f6eb..12fd41b9cd 100644 --- a/exporters/otlp/test/otlp_file_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_exporter_test.cc @@ -70,7 +70,6 @@ static nostd::span MakeSpan(T (&array)[N]) class OtlpFileExporterTestPeer : public ::testing::Test { public: - void ExportJsonIntegrationTest() { static ProtobufGlobalSymbolGuard global_symbol_guard; @@ -109,12 +108,13 @@ class OtlpFileExporterTestPeer : public ::testing::Test new sdk::trace::TracerProvider(std::move(processor), resource)); std::string report_trace_id; - -#if OPENTELEMETRY_ABI_VERSION_NO >= 2 - auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url", {{"scope_key", "scope_value"}}); + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url", + {{ "scope_key", + "scope_value" }}); #else - auto tracer = - provider->GetTracer("scope_name", "scope_version", "scope_url"); + auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url"); #endif auto parent_span = tracer->StartSpan("Test parent span"); @@ -146,19 +146,19 @@ class OtlpFileExporterTestPeer : public ::testing::Test { auto resource_span = *check_json["resourceSpans"].begin(); auto scope_span = *resource_span["scopeSpans"].begin(); - auto scope = scope_span["scope"]; + auto scope = scope_span["scope"]; auto span = *scope_span["spans"].begin(); - + #if OPENTELEMETRY_ABI_VERSION_NO >= 2 - ASSERT_EQ(1, scope["attributes"].size()); - const auto scope_attribute = scope["attributes"].front(); - EXPECT_EQ("scope_key", scope_attribute["key"].get()); - EXPECT_EQ("scope_value", scope_attribute["value"]["stringValue"].get()); + ASSERT_EQ(1, scope["attributes"].size()); + const auto scope_attribute = scope["attributes"].front(); + EXPECT_EQ("scope_key", scope_attribute["key"].get()); + EXPECT_EQ("scope_value", scope_attribute["value"]["stringValue"].get()); #endif - EXPECT_EQ("resource_url", resource_span["schemaUrl"].get()); - EXPECT_EQ("scope_url", scope_span["schemaUrl"].get()); - EXPECT_EQ("scope_name", scope["name"].get()); - EXPECT_EQ("scope_version", scope["version"].get()); + EXPECT_EQ("resource_url", resource_span["schemaUrl"].get()); + EXPECT_EQ("scope_url", scope_span["schemaUrl"].get()); + EXPECT_EQ("scope_name", scope["name"].get()); + EXPECT_EQ("scope_version", scope["version"].get()); EXPECT_EQ(report_trace_id, span["traceId"].get()); } else diff --git a/exporters/otlp/test/otlp_file_metric_exporter_test.cc b/exporters/otlp/test/otlp_file_metric_exporter_test.cc index 699d73e21d..3ee904daf5 100644 --- a/exporters/otlp/test/otlp_file_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_metric_exporter_test.cc @@ -92,8 +92,8 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test opentelemetry::sdk::resource::ResourceAttributes{}, resource_schema_url); data.resource_ = &resource; - const std::string instrumentation_scope_name{"library_name"}; - const std::string instrumentation_scope_version{"1.5.0"}; + const std::string instrumentation_scope_name{"library_name"}; + const std::string instrumentation_scope_version{"1.5.0"}; const std::string instrumentation_scope_schema_url{"https://opentelemetry.io/schemas/1.2.0"}; auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create( @@ -130,7 +130,6 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test auto resource_metrics = *check_json["resourceMetrics"].begin(); auto scope_metrics = *resource_metrics["scopeMetrics"].begin(); auto scope = scope_metrics["scope"]; - EXPECT_EQ(resource_schema_url, resource_metrics["schemaUrl"].get()); @@ -138,10 +137,9 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test EXPECT_EQ(instrumentation_scope_name, scope["name"].get()); EXPECT_EQ(instrumentation_scope_version, scope["version"].get()); ASSERT_EQ(1, scope["attributes"].size()); - const auto scope_attribute = scope["attributes"].front(); - EXPECT_EQ("scope_key", scope_attribute["key"].get()); - EXPECT_EQ("scope_value", scope_attribute["value"]["stringValue"].get()); - + const auto scope_attribute = scope["attributes"].front(); + EXPECT_EQ("scope_key", scope_attribute["key"].get()); + EXPECT_EQ("scope_value", scope_attribute["value"]["stringValue"].get()); auto metric = *scope_metrics["metrics"].begin(); EXPECT_EQ("metrics_library_name", metric["name"].get()); diff --git a/exporters/otlp/test/otlp_recordable_test.cc b/exporters/otlp/test/otlp_recordable_test.cc index 1b95298b29..0a58e52243 100644 --- a/exporters/otlp/test/otlp_recordable_test.cc +++ b/exporters/otlp/test/otlp_recordable_test.cc @@ -136,7 +136,7 @@ TEST(OtlpRecordable, SetInstrumentationScopeWithAttributes) ASSERT_EQ(proto_instr_libr.attributes_size(), 1); const auto &proto_attributes = proto_instr_libr.attributes(0); - ASSERT_TRUE(proto_attributes.value().has_string_value()); + ASSERT_TRUE(proto_attributes.value().has_string_value()); EXPECT_EQ("test_key", proto_attributes.key()); EXPECT_EQ("test_value", proto_attributes.value().string_value()); } @@ -346,7 +346,8 @@ TEST(OtlpRecordable, PopulateRequest) auto rec1 = std::unique_ptr(new OtlpRecordable); auto resource1 = resource::Resource::Create({{"service.name", "one"}}); rec1->SetResource(resource1); - auto inst_lib1 = trace_sdk::InstrumentationScope::Create("one", "1", "scope_schema", {{"scope_key", "scope_value"}}); + auto inst_lib1 = trace_sdk::InstrumentationScope::Create("one", "1", "scope_schema", + {{"scope_key", "scope_value"}}); rec1->SetInstrumentationScope(*inst_lib1); auto rec2 = std::unique_ptr(new OtlpRecordable); @@ -372,20 +373,20 @@ TEST(OtlpRecordable, PopulateRequest) EXPECT_EQ(req.resource_spans().size(), 2); for (const auto &resource_spans : req.resource_spans()) { - ASSERT_GT(resource_spans.resource().attributes_size(), 0); + ASSERT_GT(resource_spans.resource().attributes_size(), 0); const auto service_name = resource_spans.resource().attributes(0).value().string_value(); const auto scope_spans_size = resource_spans.scope_spans().size(); if (service_name == "one") { - ASSERT_GT(resource_spans.scope_spans_size(), 0); - const auto& scope_one = resource_spans.scope_spans(0).scope(); + ASSERT_GT(resource_spans.scope_spans_size(), 0); + const auto &scope_one = resource_spans.scope_spans(0).scope(); EXPECT_EQ(scope_spans_size, 1); EXPECT_EQ(scope_one.name(), "one"); EXPECT_EQ(scope_one.version(), "1"); ASSERT_EQ(scope_one.attributes_size(), 1); - const auto& scope_attribute = scope_one.attributes(0); + const auto &scope_attribute = scope_one.attributes(0); EXPECT_EQ(scope_attribute.key(), "scope_key"); EXPECT_EQ(scope_attribute.value().string_value(), "scope_value"); From 3e15cced88d1741cc61ff21bd49c156cc7e2424b Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Thu, 5 Dec 2024 01:26:41 +0000 Subject: [PATCH 4/9] add test for OtlpMetricUtils::PopulateRequest --- .../test/otlp_file_metric_exporter_test.cc | 19 +++------- .../test/otlp_metrics_serialization_test.cc | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/exporters/otlp/test/otlp_file_metric_exporter_test.cc b/exporters/otlp/test/otlp_file_metric_exporter_test.cc index 3ee904daf5..88079fd932 100644 --- a/exporters/otlp/test/otlp_file_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_metric_exporter_test.cc @@ -86,18 +86,12 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test sum_point_data2.value_ = 20.0; opentelemetry::sdk::metrics::ResourceMetrics data; - const std::string resource_schema_url{"https://opentelemetry.io/schemas/1.2.1"}; - auto resource = opentelemetry::sdk::resource::Resource::Create( - opentelemetry::sdk::resource::ResourceAttributes{}, resource_schema_url); + opentelemetry::sdk::resource::ResourceAttributes{}, "resource_url"); data.resource_ = &resource; - const std::string instrumentation_scope_name{"library_name"}; - const std::string instrumentation_scope_version{"1.5.0"}; - const std::string instrumentation_scope_schema_url{"https://opentelemetry.io/schemas/1.2.0"}; - auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create( - instrumentation_scope_name, instrumentation_scope_version, instrumentation_scope_schema_url, + "library_name", "1.5.0", "scope_url", {{"scope_key", "scope_value"}}); opentelemetry::sdk::metrics::MetricData metric_data{ @@ -131,11 +125,10 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test auto scope_metrics = *resource_metrics["scopeMetrics"].begin(); auto scope = scope_metrics["scope"]; - EXPECT_EQ(resource_schema_url, resource_metrics["schemaUrl"].get()); - - EXPECT_EQ(instrumentation_scope_schema_url, scope_metrics["schemaUrl"].get()); - EXPECT_EQ(instrumentation_scope_name, scope["name"].get()); - EXPECT_EQ(instrumentation_scope_version, scope["version"].get()); + EXPECT_EQ("resource_url", resource_metrics["schemaUrl"].get()); + EXPECT_EQ("library_name", scope["name"].get()); + EXPECT_EQ("1.5.0", scope["version"].get()); + EXPECT_EQ("scope_url", scope_metrics["schemaUrl"].get()); ASSERT_EQ(1, scope["attributes"].size()); const auto scope_attribute = scope["attributes"].front(); EXPECT_EQ("scope_key", scope_attribute["key"].get()); diff --git a/exporters/otlp/test/otlp_metrics_serialization_test.cc b/exporters/otlp/test/otlp_metrics_serialization_test.cc index 9f266e5e5f..30859a3db3 100644 --- a/exporters/otlp/test/otlp_metrics_serialization_test.cc +++ b/exporters/otlp/test/otlp_metrics_serialization_test.cc @@ -13,14 +13,17 @@ #include "opentelemetry/common/timestamp.h" #include "opentelemetry/exporters/otlp/otlp_metric_utils.h" #include "opentelemetry/exporters/otlp/otlp_preferred_temporality.h" +#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/metrics/data/metric_data.h" #include "opentelemetry/sdk/metrics/data/point_data.h" #include "opentelemetry/sdk/metrics/export/metric_producer.h" #include "opentelemetry/sdk/metrics/instruments.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/version.h" // clang-format off #include "opentelemetry/exporters/otlp/protobuf_include_prefix.h" // IWYU pragma: keep +#include "opentelemetry/proto/collector/metrics/v1/metrics_service.pb.h" #include "opentelemetry/proto/common/v1/common.pb.h" #include "opentelemetry/proto/metrics/v1/metrics.pb.h" #include "opentelemetry/exporters/otlp/protobuf_include_suffix.h" // IWYU pragma: keep @@ -302,6 +305,41 @@ TEST(OtlpMetricSerializationTest, ObservableUpDownCounter) EXPECT_EQ(1, 1); } +TEST(OtlpMetricSerializationTest, PopulateExportMetricsServiceRequest) +{ + const auto resource = resource::Resource::Create({{"service.name", "test_service_name"}}, "resource_schema_url"); + const auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create("scope_name", "scope_version", "scope_schema_url", + {{"scope_key", "scope_value"}}); + + metrics_sdk::ScopeMetrics scope_metrics{scope.get(), CreateSumAggregationData()}; + metrics_sdk::ResourceMetrics resource_metrics{&resource, scope_metrics}; + + proto::collector::metrics::v1::ExportMetricsServiceRequest request_proto; + otlp_exporter::OtlpMetricUtils::PopulateRequest(resource_metrics, &request_proto); + + ASSERT_EQ(1, request_proto.resource_metrics_size()); + const auto& resource_metrics_proto = request_proto.resource_metrics(0); + const auto& resource_proto = resource_metrics_proto.resource(); + EXPECT_EQ("resource_schema_url", resource_metrics_proto.schema_url()); + + ASSERT_EQ(1, resource_metrics_proto.scope_metrics_size()); + const auto& scope_metrics_proto = resource_metrics_proto.scope_metrics(0); + EXPECT_EQ("scope_schema_url", scope_metrics_proto.schema_url()); + + ASSERT_EQ(1, scope_metrics_proto.metrics_size()); + const auto& metric_proto = scope_metrics_proto.metrics(0); + EXPECT_EQ("Counter", metric_proto.name()); + + const auto& scope_proto = scope_metrics_proto.scope(); + EXPECT_EQ("scope_name", scope_proto.name()); + EXPECT_EQ("scope_version", scope_proto.version()); + + ASSERT_EQ(1, scope_proto.attributes_size()); + const auto& scope_attributes_proto = scope_proto.attributes(0); + EXPECT_EQ("scope_key", scope_attributes_proto.key()); + EXPECT_EQ("scope_value", scope_attributes_proto.value().string_value()); +} + } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE From dc98669db22729e4807e96c4978289b3dc4d946c Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Thu, 5 Dec 2024 01:29:21 +0000 Subject: [PATCH 5/9] clang format --- .../test/otlp_file_metric_exporter_test.cc | 3 +- .../test/otlp_metrics_serialization_test.cc | 47 ++++++++++--------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/exporters/otlp/test/otlp_file_metric_exporter_test.cc b/exporters/otlp/test/otlp_file_metric_exporter_test.cc index 88079fd932..86cce25869 100644 --- a/exporters/otlp/test/otlp_file_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_metric_exporter_test.cc @@ -91,8 +91,7 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test data.resource_ = &resource; auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create( - "library_name", "1.5.0", "scope_url", - {{"scope_key", "scope_value"}}); + "library_name", "1.5.0", "scope_url", {{"scope_key", "scope_value"}}); opentelemetry::sdk::metrics::MetricData metric_data{ opentelemetry::sdk::metrics::InstrumentDescriptor{ diff --git a/exporters/otlp/test/otlp_metrics_serialization_test.cc b/exporters/otlp/test/otlp_metrics_serialization_test.cc index 30859a3db3..41e9c0640e 100644 --- a/exporters/otlp/test/otlp_metrics_serialization_test.cc +++ b/exporters/otlp/test/otlp_metrics_serialization_test.cc @@ -307,37 +307,38 @@ TEST(OtlpMetricSerializationTest, ObservableUpDownCounter) TEST(OtlpMetricSerializationTest, PopulateExportMetricsServiceRequest) { - const auto resource = resource::Resource::Create({{"service.name", "test_service_name"}}, "resource_schema_url"); - const auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create("scope_name", "scope_version", "scope_schema_url", - {{"scope_key", "scope_value"}}); - - metrics_sdk::ScopeMetrics scope_metrics{scope.get(), CreateSumAggregationData()}; - metrics_sdk::ResourceMetrics resource_metrics{&resource, scope_metrics}; - + const auto resource = + resource::Resource::Create({{"service.name", "test_service_name"}}, "resource_schema_url"); + const auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create( + "scope_name", "scope_version", "scope_schema_url", {{"scope_key", "scope_value"}}); + + metrics_sdk::ScopeMetrics scope_metrics{scope.get(), CreateSumAggregationData()}; + metrics_sdk::ResourceMetrics resource_metrics{&resource, scope_metrics}; + proto::collector::metrics::v1::ExportMetricsServiceRequest request_proto; otlp_exporter::OtlpMetricUtils::PopulateRequest(resource_metrics, &request_proto); - ASSERT_EQ(1, request_proto.resource_metrics_size()); - const auto& resource_metrics_proto = request_proto.resource_metrics(0); - const auto& resource_proto = resource_metrics_proto.resource(); - EXPECT_EQ("resource_schema_url", resource_metrics_proto.schema_url()); - + ASSERT_EQ(1, request_proto.resource_metrics_size()); + const auto &resource_metrics_proto = request_proto.resource_metrics(0); + const auto &resource_proto = resource_metrics_proto.resource(); + EXPECT_EQ("resource_schema_url", resource_metrics_proto.schema_url()); + ASSERT_EQ(1, resource_metrics_proto.scope_metrics_size()); - const auto& scope_metrics_proto = resource_metrics_proto.scope_metrics(0); + const auto &scope_metrics_proto = resource_metrics_proto.scope_metrics(0); EXPECT_EQ("scope_schema_url", scope_metrics_proto.schema_url()); - ASSERT_EQ(1, scope_metrics_proto.metrics_size()); - const auto& metric_proto = scope_metrics_proto.metrics(0); - EXPECT_EQ("Counter", metric_proto.name()); + ASSERT_EQ(1, scope_metrics_proto.metrics_size()); + const auto &metric_proto = scope_metrics_proto.metrics(0); + EXPECT_EQ("Counter", metric_proto.name()); - const auto& scope_proto = scope_metrics_proto.scope(); - EXPECT_EQ("scope_name", scope_proto.name()); - EXPECT_EQ("scope_version", scope_proto.version()); + const auto &scope_proto = scope_metrics_proto.scope(); + EXPECT_EQ("scope_name", scope_proto.name()); + EXPECT_EQ("scope_version", scope_proto.version()); - ASSERT_EQ(1, scope_proto.attributes_size()); - const auto& scope_attributes_proto = scope_proto.attributes(0); - EXPECT_EQ("scope_key", scope_attributes_proto.key()); - EXPECT_EQ("scope_value", scope_attributes_proto.value().string_value()); + ASSERT_EQ(1, scope_proto.attributes_size()); + const auto &scope_attributes_proto = scope_proto.attributes(0); + EXPECT_EQ("scope_key", scope_attributes_proto.key()); + EXPECT_EQ("scope_value", scope_attributes_proto.value().string_value()); } } // namespace otlp From b59ac58bec812c4ce7cf9e70bd8c61864dbe5c74 Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Wed, 4 Dec 2024 20:35:39 -0700 Subject: [PATCH 6/9] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2025c36b59..4ec4535520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -149,6 +149,9 @@ Increment the: * [bazel] Update opentelemetry-proto in MODULE.bazel [#3163](https://github.com/open-telemetry/opentelemetry-cpp/pull/3163) +* [EXPORTER] Add instrumentation scope attributes to otlp proto messages for traces and metrics + [#3185](https://github.com/open-telemetry/opentelemetry-cpp/pull/3185) + Important changes: * [API] Jaeger Propagator should not be deprecated From 015fb00bd56f1d1dba56b8442f4d7f807e8ecf16 Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Wed, 4 Dec 2024 21:49:29 -0700 Subject: [PATCH 7/9] fix ci issues --- CHANGELOG.md | 2 +- exporters/otlp/test/otlp_file_exporter_test.cc | 10 +++++----- exporters/otlp/test/otlp_metrics_serialization_test.cc | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ec4535520..16873da8e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -149,7 +149,7 @@ Increment the: * [bazel] Update opentelemetry-proto in MODULE.bazel [#3163](https://github.com/open-telemetry/opentelemetry-cpp/pull/3163) -* [EXPORTER] Add instrumentation scope attributes to otlp proto messages for traces and metrics +* [EXPORTER] Add instrumentation scope attributes to otlp proto messages for traces and metrics [#3185](https://github.com/open-telemetry/opentelemetry-cpp/pull/3185) Important changes: diff --git a/exporters/otlp/test/otlp_file_exporter_test.cc b/exporters/otlp/test/otlp_file_exporter_test.cc index 12fd41b9cd..63c4c76de9 100644 --- a/exporters/otlp/test/otlp_file_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_exporter_test.cc @@ -117,7 +117,7 @@ class OtlpFileExporterTestPeer : public ::testing::Test auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url"); #endif - auto parent_span = tracer->StartSpan("Test parent span"); + auto parent_span = tracer->StartSpan("Test parent span"); char trace_id_hex[2 * trace_api::TraceId::kSize] = {0}; @@ -144,10 +144,10 @@ class OtlpFileExporterTestPeer : public ::testing::Test auto check_json = nlohmann::json::parse(check_json_text, nullptr, false); if (!check_json.is_discarded()) { - auto resource_span = *check_json["resourceSpans"].begin(); - auto scope_span = *resource_span["scopeSpans"].begin(); - auto scope = scope_span["scope"]; - auto span = *scope_span["spans"].begin(); + auto resource_span = *check_json["resourceSpans"].begin(); + auto scope_span = *resource_span["scopeSpans"].begin(); + auto scope = scope_span["scope"]; + auto span = *scope_span["spans"].begin(); #if OPENTELEMETRY_ABI_VERSION_NO >= 2 ASSERT_EQ(1, scope["attributes"].size()); diff --git a/exporters/otlp/test/otlp_metrics_serialization_test.cc b/exporters/otlp/test/otlp_metrics_serialization_test.cc index 41e9c0640e..55ab80d0ab 100644 --- a/exporters/otlp/test/otlp_metrics_serialization_test.cc +++ b/exporters/otlp/test/otlp_metrics_serialization_test.cc @@ -320,7 +320,6 @@ TEST(OtlpMetricSerializationTest, PopulateExportMetricsServiceRequest) ASSERT_EQ(1, request_proto.resource_metrics_size()); const auto &resource_metrics_proto = request_proto.resource_metrics(0); - const auto &resource_proto = resource_metrics_proto.resource(); EXPECT_EQ("resource_schema_url", resource_metrics_proto.schema_url()); ASSERT_EQ(1, resource_metrics_proto.scope_metrics_size()); From 5e07f05d489d8548cbb08e7dacf91fd22488a28f Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Wed, 4 Dec 2024 22:00:00 -0700 Subject: [PATCH 8/9] shorten changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16873da8e3..22176df917 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -149,7 +149,7 @@ Increment the: * [bazel] Update opentelemetry-proto in MODULE.bazel [#3163](https://github.com/open-telemetry/opentelemetry-cpp/pull/3163) -* [EXPORTER] Add instrumentation scope attributes to otlp proto messages for traces and metrics +* [EXPORTER] Fix scope attributes missing from otlp traces metrics [#3185](https://github.com/open-telemetry/opentelemetry-cpp/pull/3185) Important changes: From 69a1dc7ce07cbfeb78fe0a7c259c6cd0e084e51b Mon Sep 17 00:00:00 2001 From: Douglas Barker Date: Fri, 6 Dec 2024 16:45:58 -0700 Subject: [PATCH 9/9] address feedback --- exporters/otlp/src/otlp_populate_attribute_utils.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/exporters/otlp/src/otlp_populate_attribute_utils.cc b/exporters/otlp/src/otlp_populate_attribute_utils.cc index c1a87080ed..1388b73823 100644 --- a/exporters/otlp/src/otlp_populate_attribute_utils.cc +++ b/exporters/otlp/src/otlp_populate_attribute_utils.cc @@ -321,11 +321,6 @@ void OtlpPopulateAttributeUtils::PopulateAttribute( const opentelemetry::sdk::instrumentationscope::InstrumentationScope &instrumentation_scope) noexcept { - if (nullptr == proto) - { - return; - } - for (const auto &kv : instrumentation_scope.GetAttributes()) { OtlpPopulateAttributeUtils::PopulateAttribute(proto->add_attributes(), kv.first, kv.second);