diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h index 762dd56b22..b8d91cd050 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h @@ -71,6 +71,7 @@ class ETWTracerExporter final : public opentelemetry::sdk::trace::SpanExporter * @return Returns the result of the operation */ sdk::trace::ExportResult Export( + const opentelemetry::sdk::resource::Resource &resource, const nostd::span> &recordables) noexcept override { for (auto &recordable : recordables) diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index c07fa53cd8..85dfb518e8 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -88,7 +88,7 @@ TEST(ETWTracer, ExportUnitTest) recordable->SetName("MySpan"); nostd::span> batch(&recordable, 1); - auto result = exporter->Export(batch); + auto result = exporter->Export(sdk::resource::Resource::GetDefault(), batch); EXPECT_EQ(sdk::trace::ExportResult::kSuccess, result); } diff --git a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h index bf1ce497e6..113e599b94 100644 --- a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h +++ b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h @@ -1,5 +1,6 @@ #pragma once #include "opentelemetry/exporters/memory/in_memory_span_data.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/exporter.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -37,6 +38,7 @@ class InMemorySpanExporter final : public opentelemetry::sdk::trace::SpanExporte * @return Returns the result of the operation */ sdk::trace::ExportResult Export( + const opentelemetry::sdk::resource::Resource& resource, const nostd::span> &recordables) noexcept override { for (auto &recordable : recordables) diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h index 3caa906203..95865b3e91 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h @@ -1,6 +1,7 @@ #pragma once #include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/exporter.h" #include "opentelemetry/sdk/trace/span_data.h" #include "opentelemetry/version.h" @@ -35,6 +36,7 @@ class OStreamSpanExporter final : public sdktrace::SpanExporter std::unique_ptr MakeRecordable() noexcept override; sdktrace::ExportResult Export( + const opentelemetry::sdk::resource::Resource &resource, const nostd::span> &spans) noexcept override; bool Shutdown( diff --git a/exporters/ostream/src/span_exporter.cc b/exporters/ostream/src/span_exporter.cc index 31cd029ba5..3ebc4364ed 100644 --- a/exporters/ostream/src/span_exporter.cc +++ b/exporters/ostream/src/span_exporter.cc @@ -37,6 +37,7 @@ std::unique_ptr OStreamSpanExporter::MakeRecordable() noex } sdktrace::ExportResult OStreamSpanExporter::Export( + const opentelemetry::sdk::resource::Resource &resource, const nostd::span> &spans) noexcept { if (isShutdown_) diff --git a/exporters/otlp/BUILD b/exporters/otlp/BUILD index a10357a460..3177f25b4f 100644 --- a/exporters/otlp/BUILD +++ b/exporters/otlp/BUILD @@ -26,11 +26,28 @@ cc_library( ], strip_include_prefix = "include", deps = [ + ":shared_utils", "//sdk/src/trace", "@com_github_opentelemetry_proto//:trace_proto_cc", ], ) +cc_library( + name = "shared_utils", + srcs = [ + "src/shared_utils.cc", + ], + hdrs = [ + "include/opentelemetry/exporters/otlp/shared_utils.h", + ], + strip_include_prefix = "include", + deps = [ + "//sdk/src/trace", + "@com_github_opentelemetry_proto//:common_proto_cc", + ], +) + + cc_library( name = "otlp_exporter", srcs = [ @@ -42,6 +59,7 @@ cc_library( strip_include_prefix = "include", deps = [ ":recordable", + ":shared_utils", "//sdk/src/trace", # For gRPC diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_exporter.h index cb2b0066d2..69a82a218b 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_exporter.h @@ -1,6 +1,7 @@ #pragma once #include "opentelemetry/proto/collector/trace/v1/trace_service.grpc.pb.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/exporter.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -44,6 +45,7 @@ class OtlpExporter final : public opentelemetry::sdk::trace::SpanExporter * @param spans a span of unique pointers to span recordables */ sdk::trace::ExportResult Export( + const sdk::resource::Resource& resource, const nostd::span> &spans) noexcept override; /** diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/shared_utils.h b/exporters/otlp/include/opentelemetry/exporters/otlp/shared_utils.h new file mode 100644 index 0000000000..73d9fa7cda --- /dev/null +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/shared_utils.h @@ -0,0 +1,28 @@ +#pragma once + +#include "opentelemetry/proto/common/v1/common.pb.h" +#include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/resource/resource.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace otlp +{ +namespace internal +{ + +/** Maps from C++ attribute into OTLP proto attribute. */ +void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, + nostd::string_view key, + const opentelemetry::common::AttributeValue &value); + +/** Maps from C++ attribute into OTLP proto attribute. */ +void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, + nostd::string_view key, + const sdk::common::OwnedAttributeValue &value); + +} // namespace internal +} // namespace otlp +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE \ No newline at end of file diff --git a/exporters/otlp/src/otlp_exporter.cc b/exporters/otlp/src/otlp_exporter.cc index 63db30436c..7e06cc68e9 100644 --- a/exporters/otlp/src/otlp_exporter.cc +++ b/exporters/otlp/src/otlp_exporter.cc @@ -1,5 +1,6 @@ #include "opentelemetry/exporters/otlp/otlp_exporter.h" #include "opentelemetry/exporters/otlp/recordable.h" +#include "opentelemetry/exporters/otlp/shared_utils.h" #include #include @@ -12,15 +13,27 @@ namespace otlp // ----------------------------- Helper functions ------------------------------ +void PopulateResource(const sdk::resource::Resource& resource, + proto::resource::v1::Resource* proto) { + // TODO - Fill this out. + for (const auto& kv : resource.GetAttributes()) { + internal::PopulateAttribute(proto->add_attributes(), kv.first, kv.second); + } + +} + /** * Add span protobufs contained in recordables to request. * @param spans the spans to export * @param request the current request */ -void PopulateRequest(const nostd::span> &spans, +void PopulateRequest(const sdk::resource::Resource& resource, + const nostd::span> &spans, proto::collector::trace::v1::ExportTraceServiceRequest *request) { auto resource_span = request->add_resource_spans(); + PopulateResource(resource, resource_span->mutable_resource()); + auto instrumentation_lib = resource_span->add_instrumentation_library_spans(); for (auto &recordable : spans) @@ -61,11 +74,11 @@ std::unique_ptr OtlpExporter::MakeRecordable() noexcept } sdk::trace::ExportResult OtlpExporter::Export( + const opentelemetry::sdk::resource::Resource& resource, const nostd::span> &spans) noexcept { proto::collector::trace::v1::ExportTraceServiceRequest request; - - PopulateRequest(spans, &request); + PopulateRequest(resource, spans, &request); grpc::ClientContext context; proto::collector::trace::v1::ExportTraceServiceResponse response; diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index ebc9c3047b..a12148ffd2 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -1,4 +1,5 @@ #include "opentelemetry/exporters/otlp/recordable.h" +#include "opentelemetry/exporters/otlp/shared_utils.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter @@ -6,8 +7,6 @@ namespace exporter namespace otlp { -const int kAttributeValueSize = 14; - void Recordable::SetIds(trace::TraceId trace_id, trace::SpanId span_id, trace::SpanId parent_span_id) noexcept @@ -18,110 +17,11 @@ void Recordable::SetIds(trace::TraceId trace_id, trace::SpanId::kSize); } -void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, - nostd::string_view key, - const opentelemetry::common::AttributeValue &value) -{ - // Assert size of variant to ensure that this method gets updated if the variant - // definition changes - static_assert( - nostd::variant_size::value == kAttributeValueSize, - "AttributeValue contains unknown type"); - - attribute->set_key(key.data(), key.size()); - - if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_bool_value(nostd::get(value)); - } - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_int_value(nostd::get(value)); - } - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_int_value(nostd::get(value)); - } - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_int_value(nostd::get(value)); - } - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_int_value(nostd::get(value)); - } - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_double_value(nostd::get(value)); - } - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_string_value(nostd::get(value).data(), - nostd::get(value).size()); - } -#ifdef HAVE_CSTRING_TYPE - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_string_value(nostd::get(value)); - } -#endif - else if (nostd::holds_alternative>(value)) - { - for (const auto &val : nostd::get>(value)) - { - attribute->mutable_value()->mutable_array_value()->add_values()->set_bool_value(val); - } - } - else if (nostd::holds_alternative>(value)) - { - for (const auto &val : nostd::get>(value)) - { - attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); - } - } - else if (nostd::holds_alternative>(value)) - { - for (const auto &val : nostd::get>(value)) - { - attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); - } - } - else if (nostd::holds_alternative>(value)) - { - for (const auto &val : nostd::get>(value)) - { - attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); - } - } - else if (nostd::holds_alternative>(value)) - { - for (const auto &val : nostd::get>(value)) - { - attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); - } - } - else if (nostd::holds_alternative>(value)) - { - for (const auto &val : nostd::get>(value)) - { - attribute->mutable_value()->mutable_array_value()->add_values()->set_double_value(val); - } - } - else if (nostd::holds_alternative>(value)) - { - for (const auto &val : nostd::get>(value)) - { - attribute->mutable_value()->mutable_array_value()->add_values()->set_string_value(val.data(), - val.size()); - } - } -} - void Recordable::SetAttribute(nostd::string_view key, const opentelemetry::common::AttributeValue &value) noexcept { auto *attribute = span_.add_attributes(); - PopulateAttribute(attribute, key, value); + internal::PopulateAttribute(attribute, key, value); } void Recordable::AddEvent(nostd::string_view name, @@ -133,7 +33,7 @@ void Recordable::AddEvent(nostd::string_view name, event->set_time_unix_nano(timestamp.time_since_epoch().count()); attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept { - PopulateAttribute(event->add_attributes(), key, value); + internal::PopulateAttribute(event->add_attributes(), key, value); return true; }); } @@ -147,7 +47,7 @@ void Recordable::AddLink(const opentelemetry::trace::SpanContext &span_context, link->set_span_id(reinterpret_cast(span_context.span_id().Id().data()), trace::SpanId::kSize); attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept { - PopulateAttribute(link->add_attributes(), key, value); + internal::PopulateAttribute(link->add_attributes(), key, value); return true; }); diff --git a/exporters/otlp/src/shared_utils.cc b/exporters/otlp/src/shared_utils.cc new file mode 100644 index 0000000000..61d61a918a --- /dev/null +++ b/exporters/otlp/src/shared_utils.cc @@ -0,0 +1,220 @@ +#include "opentelemetry/exporters/otlp/shared_utils.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace otlp +{ +namespace internal +{ + +const int kAttributeValueSize = 14; +#ifdef HAVE_SPAN_BYTE +const int kOwnedAttributeValueSize = 15; +#else +const int kOwnedAttributeValueSize = 14; +#endif + +/** Maps from C++ attribute into OTLP proto attribute. */ +void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, + nostd::string_view key, + const opentelemetry::common::AttributeValue &value) { +// Assert size of variant to ensure that this method gets updated if the variant + // definition changes + static_assert( + nostd::variant_size::value == kAttributeValueSize, + "AttributeValue contains unknown type"); + + attribute->set_key(key.data(), key.size()); + + if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_bool_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_double_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_string_value(nostd::get(value).data(), + nostd::get(value).size()); + } +#ifdef HAVE_CSTRING_TYPE + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_string_value(nostd::get(value)); + } +#endif + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_bool_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_double_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_string_value(val.data(), + val.size()); + } + } +} + + + + +/** Maps from C++ attribute into OTLP proto attribute. */ +void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, + nostd::string_view key, + const sdk::common::OwnedAttributeValue &value) { + // Assert size of variant to ensure that this method gets updated if the variant + // definition changes + static_assert( + nostd::variant_size::value == kOwnedAttributeValueSize, + "AttributeValue contains unknown type"); + + attribute->set_key(key.data(), key.size()); + + if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_bool_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_double_value(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_string_value(nostd::get(value)); + } +#ifdef HAVE_SPAN_BYTE + else if (nostd::holds_alternative(value)) + { + attribute->mutable_value()->set_int_value(nostd::get(value)); + } +#endif + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_bool_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_double_value(val); + } + } + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_string_value(val); + } + } +} + +} // namespace internal +} // namespace otlp +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE \ No newline at end of file diff --git a/exporters/otlp/test/otlp_exporter_benchmark.cc b/exporters/otlp/test/otlp_exporter_benchmark.cc index 0accff0bf4..183a4b3d88 100644 --- a/exporters/otlp/test/otlp_exporter_benchmark.cc +++ b/exporters/otlp/test/otlp_exporter_benchmark.cc @@ -124,7 +124,9 @@ void BM_OtlpExporterEmptySpans(benchmark::State &state) { std::array, kBatchSize> recordables; CreateEmptySpans(recordables); - exporter->Export(nostd::span>(recordables)); + exporter->Export( + sdk::resource::Resource::GetDefault(), + nostd::span>(recordables)); } } BENCHMARK(BM_OtlpExporterEmptySpans); @@ -139,7 +141,9 @@ void BM_OtlpExporterSparseSpans(benchmark::State &state) { std::array, kBatchSize> recordables; CreateSparseSpans(recordables); - exporter->Export(nostd::span>(recordables)); + exporter->Export( + sdk::resource::Resource::GetDefault(), + nostd::span>(recordables)); } } BENCHMARK(BM_OtlpExporterSparseSpans); @@ -154,7 +158,9 @@ void BM_OtlpExporterDenseSpans(benchmark::State &state) { std::array, kBatchSize> recordables; CreateDenseSpans(recordables); - exporter->Export(nostd::span>(recordables)); + exporter->Export( + sdk::resource::Resource::GetDefault(), + nostd::span>(recordables)); } } BENCHMARK(BM_OtlpExporterDenseSpans); diff --git a/exporters/otlp/test/otlp_exporter_test.cc b/exporters/otlp/test/otlp_exporter_test.cc index a221365179..44723c6a82 100644 --- a/exporters/otlp/test/otlp_exporter_test.cc +++ b/exporters/otlp/test/otlp_exporter_test.cc @@ -1,5 +1,6 @@ #include "opentelemetry/exporters/otlp/otlp_exporter.h" #include "opentelemetry/proto/collector/trace/v1/trace_service_mock.grpc.pb.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/simple_processor.h" #include "opentelemetry/sdk/trace/tracer_provider.h" #include "opentelemetry/trace/provider.h" @@ -7,6 +8,7 @@ #include using namespace testing; +using opentelemetry::sdk::resource::Resource; OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter @@ -46,7 +48,7 @@ TEST_F(OtlpExporterTestPeer, ExportUnitTest) // Test successful RPC nostd::span> batch_1(&recordable_1, 1); EXPECT_CALL(*mock_stub, Export(_, _, _)).Times(Exactly(1)).WillOnce(Return(grpc::Status::OK)); - auto result = exporter->Export(batch_1); + auto result = exporter->Export(Resource::GetDefault(), batch_1); EXPECT_EQ(sdk::trace::ExportResult::kSuccess, result); // Test failed RPC @@ -54,7 +56,7 @@ TEST_F(OtlpExporterTestPeer, ExportUnitTest) EXPECT_CALL(*mock_stub, Export(_, _, _)) .Times(Exactly(1)) .WillOnce(Return(grpc::Status::CANCELLED)); - result = exporter->Export(batch_2); + result = exporter->Export(Resource::GetDefault(), batch_2); EXPECT_EQ(sdk::trace::ExportResult::kFailure, result); } @@ -91,6 +93,9 @@ TEST_F(OtlpExporterTestPeer, ConfigTest) std::unique_ptr exporter(new OtlpExporter(opts)); EXPECT_EQ(GetOptions(exporter).endpoint, "localhost:45454"); } + +// TODO - Test that proto is cosntructed with appropraite information. + } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/tracez_processor.h b/ext/include/opentelemetry/ext/zpages/tracez_processor.h index d0c8692a8c..9e1a02bb4f 100644 --- a/ext/include/opentelemetry/ext/zpages/tracez_processor.h +++ b/ext/include/opentelemetry/ext/zpages/tracez_processor.h @@ -43,6 +43,8 @@ class TracezSpanProcessor : public opentelemetry::sdk::trace::SpanProcessor return std::unique_ptr(new ThreadsafeSpanData); } + void SetResourceRef(const opentelemetry::sdk::resource::Resource*const resource_ref) noexcept override {} + /* * OnStart is called when a span starts; the recordable is cast to span_data and added to * running_spans. diff --git a/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h b/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h index 50788b4d65..ffbc3518ab 100644 --- a/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h @@ -3,6 +3,7 @@ #include "opentelemetry/sdk/common/circular_buffer.h" #include "opentelemetry/sdk/trace/exporter.h" #include "opentelemetry/sdk/trace/processor.h" +#include "opentelemetry/sdk/resource/resource.h" #include #include @@ -60,6 +61,10 @@ class BatchSpanProcessor : public SpanProcessor */ std::unique_ptr MakeRecordable() noexcept override; + void SetResourceRef(const opentelemetry::sdk::resource::Resource*const resource_ref) noexcept override { + resource_ = resource_ref; + } + /** * Called when a span is started. * @@ -148,6 +153,9 @@ class BatchSpanProcessor : public SpanProcessor /* The background worker thread */ std::thread worker_thread_; + + /** Pointer to the `Resource` associated with all spans being processed. */ + const opentelemetry::sdk::resource::Resource* resource_; }; } // namespace trace diff --git a/sdk/include/opentelemetry/sdk/trace/exporter.h b/sdk/include/opentelemetry/sdk/trace/exporter.h index f050c5f179..e8a78691fe 100644 --- a/sdk/include/opentelemetry/sdk/trace/exporter.h +++ b/sdk/include/opentelemetry/sdk/trace/exporter.h @@ -2,6 +2,7 @@ #include #include "opentelemetry/nostd/span.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/recordable.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -47,9 +48,11 @@ class SpanExporter /** * Exports a batch of span recordables. This method must not be called * concurrently for the same exporter instance. + * @param Resource the resource associated with all exported spans. * @param spans a span of unique pointers to span recordables */ virtual ExportResult Export( + const opentelemetry::sdk::resource::Resource& resource, const nostd::span> &spans) noexcept = 0; diff --git a/sdk/include/opentelemetry/sdk/trace/processor.h b/sdk/include/opentelemetry/sdk/trace/processor.h index e46cc6ac9c..7d481f915b 100644 --- a/sdk/include/opentelemetry/sdk/trace/processor.h +++ b/sdk/include/opentelemetry/sdk/trace/processor.h @@ -3,6 +3,7 @@ #include #include #include "opentelemetry/sdk/trace/recordable.h" +#include "opentelemetry/sdk/resource/resource.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -29,6 +30,15 @@ class SpanProcessor */ virtual std::unique_ptr MakeRecordable() noexcept = 0; + /** + * Associates the `Resource` of the SDK with this processor. All spans + * procesed are assumed to be from this `Resource`. + * + * Note: The `Resource` lifetime must be longer than the lifetime of the + * `SpanProcessor`. + */ + virtual void SetResourceRef(const opentelemetry::sdk::resource::Resource*const resource_ref) noexcept = 0; + /** * OnStart is called when a span is started. * @param span a recordable for a span that was just started diff --git a/sdk/include/opentelemetry/sdk/trace/simple_processor.h b/sdk/include/opentelemetry/sdk/trace/simple_processor.h index 92612ae800..a73c21feec 100644 --- a/sdk/include/opentelemetry/sdk/trace/simple_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/simple_processor.h @@ -4,6 +4,7 @@ #include #include "opentelemetry/common/spin_lock_mutex.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/exporter.h" #include "opentelemetry/sdk/trace/processor.h" @@ -37,6 +38,10 @@ class SimpleSpanProcessor : public SpanProcessor return exporter_->MakeRecordable(); } + void SetResourceRef(const opentelemetry::sdk::resource::Resource*const resource_ref) noexcept override { + resource_ = resource_ref; + } + void OnStart(Recordable &span, const opentelemetry::trace::SpanContext &parent_context) noexcept override {} @@ -45,7 +50,9 @@ class SimpleSpanProcessor : public SpanProcessor { nostd::span> batch(&span, 1); const std::lock_guard locked(lock_); - if (exporter_->Export(batch) == ExportResult::kFailure) + if (exporter_->Export( + (resource_ == nullptr) ? opentelemetry::sdk::resource::Resource::GetDefault() : *resource_, + batch) == ExportResult::kFailure) { /* Once it is defined how the SDK does logging, an error should be * logged in this case. */ @@ -75,6 +82,8 @@ class SimpleSpanProcessor : public SpanProcessor std::unique_ptr exporter_; opentelemetry::common::SpinLockMutex lock_; std::atomic_flag shutdown_latch_ = ATOMIC_FLAG_INIT; + /** Pointer to the `Resource` associated with all spans being processed. */ + const opentelemetry::sdk::resource::Resource* resource_; }; } // namespace trace } // namespace sdk diff --git a/sdk/src/trace/batch_span_processor.cc b/sdk/src/trace/batch_span_processor.cc index 40e82360a4..ad145e39ef 100644 --- a/sdk/src/trace/batch_span_processor.cc +++ b/sdk/src/trace/batch_span_processor.cc @@ -4,6 +4,7 @@ using opentelemetry::sdk::common::AtomicUniquePtr; using opentelemetry::sdk::common::CircularBuffer; using opentelemetry::sdk::common::CircularBufferRange; +using opentelemetry::sdk::resource::Resource; using opentelemetry::trace::SpanContext; OPENTELEMETRY_BEGIN_NAMESPACE @@ -153,7 +154,9 @@ void BatchSpanProcessor::Export(const bool was_force_flush_called) }); }); - exporter_->Export(nostd::span>(spans_arr.data(), spans_arr.size())); + exporter_->Export( + (resource_ == nullptr) ? Resource::GetDefault() : *resource_, + nostd::span>(spans_arr.data(), spans_arr.size())); // Notify the main thread in case this export was the result of a force flush. if (was_force_flush_called == true) diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index b37ae5de56..11663c7eb3 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -12,7 +12,9 @@ TracerProvider::TracerProvider(std::shared_ptr processor, tracer_(new Tracer(std::move(processor), resource, sampler)), sampler_(sampler), resource_(resource) -{} +{ + static_cast(tracer_.get())->GetProcessor()->SetResourceRef(&resource_); +} opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( nostd::string_view library_name, @@ -24,9 +26,10 @@ opentelemetry::nostd::shared_ptr TracerProvider::G void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept { processor_.store(processor); - auto sdkTracer = static_cast(tracer_.get()); sdkTracer->SetProcessor(processor); + // Note: We ensure the resource is kept alive for the length of the processor by our own lifecycle. + sdkTracer->GetProcessor()->SetResourceRef(&resource_); } std::shared_ptr TracerProvider::GetProcessor() const noexcept diff --git a/sdk/test/trace/batch_span_processor_test.cc b/sdk/test/trace/batch_span_processor_test.cc index 64925f8f23..3dcb86f067 100644 --- a/sdk/test/trace/batch_span_processor_test.cc +++ b/sdk/test/trace/batch_span_processor_test.cc @@ -32,6 +32,7 @@ class MockSpanExporter final : public sdk::trace::SpanExporter } sdk::trace::ExportResult Export( + const opentelemetry::sdk::resource::Resource& resource, const nostd::span> &recordables) noexcept override { *is_export_completed_ = false; diff --git a/sdk/test/trace/simple_processor_test.cc b/sdk/test/trace/simple_processor_test.cc index 0e86ac2471..06df1fa0cf 100644 --- a/sdk/test/trace/simple_processor_test.cc +++ b/sdk/test/trace/simple_processor_test.cc @@ -42,6 +42,7 @@ class RecordShutdownExporter final : public SpanExporter } ExportResult Export( + const opentelemetry::sdk::resource::Resource& resource, const opentelemetry::nostd::span> &recordables) noexcept override { return ExportResult::kSuccess;