Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EXPORTER] add instrumentation scope attributes to otlp proto messages for traces and metrics #3185

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());
dbarker marked this conversation as resolved.
Show resolved Hide resolved
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;
}
marcalff marked this conversation as resolved.
Show resolved Hide resolved

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
Loading