Skip to content

Commit

Permalink
[OTLP EXPORTER] include instrumentation scope attributes in otlp mess…
Browse files Browse the repository at this point in the history
…ages for metrics and traces
  • Loading branch information
dbarker committed Dec 4, 2024
1 parent 150256c commit 2f0740f
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -20,6 +21,7 @@ namespace v1
{
class AnyValue;
class KeyValue;
class InstrumentationScope;
} // namespace v1
} // namespace common

Expand Down Expand Up @@ -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;

Expand Down
6 changes: 5 additions & 1 deletion exporters/otlp/src/otlp_metric_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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_)
{
Expand Down
17 changes: 17 additions & 0 deletions exporters/otlp/src/otlp_populate_attribute_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions exporters/otlp/src/otlp_recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
9 changes: 4 additions & 5 deletions exporters/otlp/src/otlp_recordable_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down Expand Up @@ -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());
}
Expand Down
35 changes: 32 additions & 3 deletions exporters/otlp/test/otlp_file_exporter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<std::string, opentelemetry::common::AttributeValue>>
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();

Expand All @@ -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<std::string>();

const std::string received_schema_url = scope_span["schemaUrl"].get<std::string>();
const std::string received_instrumentation_scope_name = scope["name"].get<std::string>();
const std::string received_instrumentation_scope_version = scope["version"].get<std::string>();
const auto received_trace_id = span["traceId"].get<std::string>();

#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
Expand Down
29 changes: 23 additions & 6 deletions exporters/otlp/test/otlp_file_log_record_exporter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<std::string, opentelemetry::common::AttributeValue>>
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));
Expand Down Expand Up @@ -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<std::string>();
auto received_span_id = log["spanId"].get<std::string>();

const auto received_schema_url = scope_logs["schemaUrl"].get<std::string>();
const auto received_instrumentation_scope_name = scope["name"].get<std::string>();
const auto received_instrumentation_scope_version = scope["version"].get<std::string>();
const auto received_instrumentation_scope_attributes = scope["attributes"];
const auto received_trace_id = log["traceId"].get<std::string>();
const auto received_span_id = log["spanId"].get<std::string>();

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<std::string>());
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())
{
Expand Down
23 changes: 19 additions & 4 deletions exporters/otlp/test/otlp_file_metric_exporter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<std::string, opentelemetry::common::AttributeValue>>
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",
Expand All @@ -100,6 +111,7 @@ class OtlpFileMetricExporterTestPeer : public ::testing::Test
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>{
{opentelemetry::sdk::metrics::PointAttributes{{"a1", "b1"}}, sum_point_data},
{opentelemetry::sdk::metrics::PointAttributes{{"a2", "b2"}}, sum_point_data2}}};

data.scope_metric_data_ = std::vector<opentelemetry::sdk::metrics::ScopeMetrics>{
{scope.get(), std::vector<opentelemetry::sdk::metrics::MetricData>{metric_data}}};

Expand All @@ -111,15 +123,18 @@ 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);

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<std::string>());
EXPECT_EQ("1.5.0", scope["version"].get<std::string>());

EXPECT_EQ(instrumentation_scope_schema_url, scope_metrics["schemaUrl"].get<std::string>());
EXPECT_EQ(instrumentation_scope_name, scope["name"].get<std::string>());
EXPECT_EQ(instrumentation_scope_version, scope["version"].get<std::string>());

auto metric = *scope_metrics["metrics"].begin();
EXPECT_EQ("metrics_library_name", metric["name"].get<std::string>());
Expand Down
25 changes: 25 additions & 0 deletions exporters/otlp/test/otlp_recordable_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 2f0740f

Please sign in to comment.