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

Add schema_url support to both Resource and InstrumentationLibrary #979

Merged
merged 7 commits into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Increment the:
## [Unreleased]

* Support environment variables for both `OtlpGrpcExporter` and `OtlpHttpExporter` ([#983](https://github.com/open-telemetry/opentelemetry-cpp/pull/983))
* [API/SDK] Add schema_url support to both Resource and InstrumentationLibrary ([#979](https://github.com/open-telemetry/opentelemetry-cpp/pull/979))

## [1.0.0] 2021-09-16

Expand Down
6 changes: 3 additions & 3 deletions api/include/opentelemetry/trace/noop.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ class NoopTracerProvider final : public opentelemetry::trace::TracerProvider
new opentelemetry::trace::NoopTracer)}
{}

nostd::shared_ptr<opentelemetry::trace::Tracer> GetTracer(
nostd::string_view library_name,
nostd::string_view library_version) override
nostd::shared_ptr<opentelemetry::trace::Tracer> GetTracer(nostd::string_view library_name,
nostd::string_view library_version,
nostd::string_view schema_url) override
{
return tracer_;
}
Expand Down
3 changes: 2 additions & 1 deletion api/include/opentelemetry/trace/tracer_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class TracerProvider
* instance.
*/
virtual nostd::shared_ptr<Tracer> GetTracer(nostd::string_view library_name,
nostd::string_view library_version = "") = 0;
nostd::string_view library_version = "",
nostd::string_view schema_url = "") = 0;
};
} // namespace trace
OPENTELEMETRY_END_NAMESPACE
3 changes: 2 additions & 1 deletion api/test/trace/provider_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ class TestProvider : public TracerProvider
{
opentelemetry::nostd::shared_ptr<Tracer> GetTracer(
opentelemetry::nostd::string_view library_name,
opentelemetry::nostd::string_view library_version) override
opentelemetry::nostd::string_view library_version,
opentelemetry::nostd::string_view schema_url) override
{
return opentelemetry::nostd::shared_ptr<Tracer>(nullptr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1131,9 +1131,11 @@ class TracerProvider : public trace::TracerProvider
* @return
*/
nostd::shared_ptr<trace::Tracer> GetTracer(nostd::string_view name,
nostd::string_view args = "") override
nostd::string_view args = "",
nostd::string_view schema_url = "") override
{
UNREFERENCED_PARAMETER(args);
UNREFERENCED_PARAMETER(schema_url);
ETWProvider::EventFormat evtFmt = config_.encoding;
return nostd::shared_ptr<trace::Tracer>{new (std::nothrow) Tracer(*this, name, evtFmt)};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class OtlpRecordable final : public sdk::trace::Recordable
/** Dynamically converts the resource of this span into a proto. */
proto::resource::v1::Resource ProtoResource() const noexcept;

const std::string GetResourceSchemaURL() const noexcept;
const std::string GetInstrumentationLibrarySchemaURL() const noexcept;

proto::common::v1::InstrumentationLibrary GetProtoInstrumentationLibrary() const noexcept;

void SetIdentity(const opentelemetry::trace::SpanContext &span_context,
Expand Down
12 changes: 8 additions & 4 deletions exporters/otlp/src/otlp_grpc_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,22 @@ void PopulateRequest(const nostd::span<std::unique_ptr<sdk::trace::Recordable>>
{
auto resource_span = request->add_resource_spans();
auto instrumentation_lib = resource_span->add_instrumentation_library_spans();
bool has_resource = false;
bool first_pass = true;

for (auto &recordable : spans)
{
auto rec = std::unique_ptr<OtlpRecordable>(static_cast<OtlpRecordable *>(recordable.release()));
*instrumentation_lib->add_spans() = std::move(rec->span());
*instrumentation_lib->mutable_instrumentation_library() = rec->GetProtoInstrumentationLibrary();

if (!has_resource)
if (first_pass)
{
*resource_span->mutable_resource() = rec->ProtoResource();
has_resource = true;
*instrumentation_lib->mutable_schema_url() = rec->GetInstrumentationLibrarySchemaURL();

*resource_span->mutable_resource() = rec->ProtoResource();
*resource_span->mutable_schema_url() = rec->GetResourceSchemaURL();

first_pass = false;
}
}
}
Expand Down
22 changes: 22 additions & 0 deletions exporters/otlp/src/otlp_recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,28 @@ proto::resource::v1::Resource OtlpRecordable::ProtoResource() const noexcept
return proto;
}

const std::string OtlpRecordable::GetResourceSchemaURL() const noexcept
{
std::string schema_url;
if (resource_)
{
schema_url = resource_->GetSchemaURL();
}

return schema_url;
}

const std::string OtlpRecordable::GetInstrumentationLibrarySchemaURL() const noexcept
{
std::string schema_url;
if (instrumentation_library_)
{
schema_url = instrumentation_library_->GetSchemaURL();
}

return schema_url;
}

proto::common::v1::InstrumentationLibrary OtlpRecordable::GetProtoInstrumentationLibrary()
const noexcept
{
Expand Down
23 changes: 23 additions & 0 deletions exporters/otlp/test/otlp_recordable_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ TEST(OtlpRecordable, SetInstrumentationLibrary)
EXPECT_EQ(proto_instr_libr.version(), inst_lib->GetVersion());
}

TEST(OtlpRecordable, SetInstrumentationLibraryWithSchemaURL)
{
OtlpRecordable rec;
const std::string expected_schema_url{"https://opentelemetry.io/schemas/1.2.0"};
auto inst_lib =
opentelemetry::sdk::trace::InstrumentationLibrary::Create("test", "v1", expected_schema_url);
rec.SetInstrumentationLibrary(*inst_lib);
EXPECT_EQ(expected_schema_url, rec.GetInstrumentationLibrarySchemaURL());
}

TEST(OtlpRecordable, SetStartTime)
{
OtlpRecordable rec;
Expand Down Expand Up @@ -198,6 +208,19 @@ TEST(OtlpRecordable, SetResource)
EXPECT_TRUE(found_service_name);
}

TEST(OtlpRecordable, SetResourceWithSchemaURL)
{
OtlpRecordable rec;
const std::string service_name_key = "service.name";
const std::string service_name = "test-otlp";
const std::string expected_schema_url = "https://opentelemetry.io/schemas/1.2.0";
auto resource = opentelemetry::sdk::resource::Resource::Create({{service_name_key, service_name}},
expected_schema_url);
rec.SetResource(resource);

EXPECT_EQ(expected_schema_url, rec.GetResourceSchemaURL());
}

// Test non-int single types. Int single types are tested using templates (see IntAttributeTest)
TEST(OtlpRecordable, SetSingleAtrribute)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ class InstrumentationLibrary
* Returns a newly created InstrumentationLibrary with the specified library name and version.
* @param name name of the instrumentation library.
* @param version version of the instrumentation library.
* @param schema_url schema url of the telemetry emitted by the library.
* @returns the newly created InstrumentationLibrary.
*/
static nostd::unique_ptr<InstrumentationLibrary> Create(nostd::string_view name,
nostd::string_view version = "")
nostd::string_view version = "",
nostd::string_view schema_url = "")
{
return nostd::unique_ptr<InstrumentationLibrary>(
new InstrumentationLibrary{std::string{name}, std::string{version}});
return nostd::unique_ptr<InstrumentationLibrary>(new InstrumentationLibrary{
std::string{name}, std::string{version}, std::string{schema_url}});
}

/**
Expand All @@ -39,33 +41,40 @@ class InstrumentationLibrary
*/
bool operator==(const InstrumentationLibrary &other) const
{
return equal(other.name_, other.version_);
return equal(other.name_, other.version_, other.schema_url_);
}

/**
* Check whether the instrumentation library has given name and version.
* This could be used to check version equality and avoid heap allocation.
* @param name name of the instrumentation library to compare.
* @param version version of the instrumentatoin library to compare.
* @param schema_url schema url of the telemetry emitted by the library.
* @returns true if name and version in this instrumentation library are equal with the given name
* and version.
*/
bool equal(const nostd::string_view name, const nostd::string_view version) const
bool equal(const nostd::string_view name,
const nostd::string_view version,
const nostd::string_view schema_url = "") const
{
return this->name_ == name && this->version_ == version;
return this->name_ == name && this->version_ == version && this->schema_url_ == schema_url;
}

const std::string &GetName() const { return name_; }
const std::string &GetVersion() const { return version_; }
const std::string &GetSchemaURL() const { return schema_url_; }

private:
InstrumentationLibrary(nostd::string_view name, nostd::string_view version)
: name_(name), version_(version)
InstrumentationLibrary(nostd::string_view name,
nostd::string_view version,
nostd::string_view schema_url = "")
: name_(name), version_(version), schema_url_(schema_url)
{}

private:
std::string name_;
std::string version_;
std::string schema_url_;
};

} // namespace instrumentationlibrary
Expand Down
10 changes: 7 additions & 3 deletions sdk/include/opentelemetry/sdk/resource/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Resource
Resource(const Resource &) = default;

const ResourceAttributes &GetAttributes() const noexcept;
const std::string &GetSchemaURL() const noexcept;

/**
* Returns a new, merged {@link Resource} by merging the current Resource
Expand All @@ -48,7 +49,8 @@ class Resource
* @returns the newly created Resource.
*/

static Resource Create(const ResourceAttributes &attributes);
static Resource Create(const ResourceAttributes &attributes,
const std::string &schema_url = std::string{});

/**
* Returns an Empty resource.
Expand All @@ -69,14 +71,16 @@ class Resource
* Users should use the Create factory method to obtain a Resource
* instance.
*/
Resource(const ResourceAttributes &attributes = ResourceAttributes()) noexcept;
Resource(const ResourceAttributes &attributes = ResourceAttributes(),
const std::string &schema_url = std::string{}) noexcept;

private:
ResourceAttributes attributes_;
std::string schema_url_;

friend class OTELResourceDetector;
};

} // namespace resource
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
OPENTELEMETRY_END_NAMESPACE
3 changes: 2 additions & 1 deletion sdk/include/opentelemetry/sdk/trace/tracer_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider

opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> GetTracer(
nostd::string_view library_name,
nostd::string_view library_version = "") noexcept override;
nostd::string_view library_version = "",
nostd::string_view schema_url = "") noexcept override;

/**
* Attaches a span processor to list of configured processors for this tracer provider.
Expand Down
19 changes: 14 additions & 5 deletions sdk/src/resource/resource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ const std::string kTelemetrySdkVersion = "telemetry.sdk.version";
const std::string kServiceName = "service.name";
const std::string kProcessExecutableName = "process.executable.name";

Resource::Resource(const ResourceAttributes &attributes) noexcept : attributes_(attributes) {}
Resource::Resource(const ResourceAttributes &attributes, const std::string &schema_url) noexcept
: attributes_(attributes), schema_url_(schema_url)
{}

Resource Resource::Merge(const Resource &other) noexcept
{
ResourceAttributes merged_resource_attributes(other.attributes_);
merged_resource_attributes.insert(attributes_.begin(), attributes_.end());
return Resource(merged_resource_attributes);
return Resource(merged_resource_attributes, other.schema_url_);
}

Resource Resource::Create(const ResourceAttributes &attributes)
Resource Resource::Create(const ResourceAttributes &attributes, const std::string &schema_url)
{
static auto otel_resource = OTELResourceDetector().Detect();
auto resource = Resource::GetDefault().Merge(otel_resource).Merge(Resource(attributes));
auto resource =
Resource::GetDefault().Merge(otel_resource).Merge(Resource{attributes, schema_url});

if (resource.attributes_.find(OTEL_CPP_GET_ATTR(AttrServiceName)) == resource.attributes_.end())
{
Expand All @@ -58,7 +61,8 @@ Resource &Resource::GetDefault()
static Resource default_resource(
{{OTEL_CPP_GET_ATTR(AttrTelemetrySdkLanguage), "cpp"},
{OTEL_CPP_GET_ATTR(AttrTelemetrySdkName), "opentelemetry"},
{OTEL_CPP_GET_ATTR(AttrTelemetrySdkVersion), OPENTELEMETRY_SDK_VERSION}});
{OTEL_CPP_GET_ATTR(AttrTelemetrySdkVersion), OPENTELEMETRY_SDK_VERSION}},
std::string{});
return default_resource;
}

Expand All @@ -67,6 +71,11 @@ const ResourceAttributes &Resource::GetAttributes() const noexcept
return attributes_;
}

const std::string &Resource::GetSchemaURL() const noexcept
{
return schema_url_;
}

} // namespace resource
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
10 changes: 6 additions & 4 deletions sdk/src/trace/tracer_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ TracerProvider::TracerProvider(std::vector<std::unique_ptr<SpanProcessor>> &&pro

nostd::shared_ptr<opentelemetry::trace::Tracer> TracerProvider::GetTracer(
nostd::string_view library_name,
nostd::string_view library_version) noexcept
nostd::string_view library_version,
nostd::string_view schema_url) noexcept
{
if (library_name.data() == nullptr)
{
OTEL_INTERNAL_LOG_ERROR("[TracerProvider::GetTracer] Library name is null.");
library_name = "";
}
if (library_name == "")
else if (library_name == "")
{
OTEL_INTERNAL_LOG_ERROR("[TracerProvider::GetTracer] Library name is empty.");
}
Expand All @@ -51,13 +53,13 @@ nostd::shared_ptr<opentelemetry::trace::Tracer> TracerProvider::GetTracer(
for (auto &tracer : tracers_)
{
auto &tracer_lib = tracer->GetInstrumentationLibrary();
if (tracer_lib.equal(library_name, library_version))
if (tracer_lib.equal(library_name, library_version, schema_url))
{
return nostd::shared_ptr<opentelemetry::trace::Tracer>{tracer};
}
}

auto lib = InstrumentationLibrary::Create(library_name, library_version);
auto lib = InstrumentationLibrary::Create(library_name, library_version, schema_url);
tracers_.push_back(std::shared_ptr<opentelemetry::sdk::trace::Tracer>(
new sdk::trace::Tracer(context_, std::move(lib))));
return nostd::shared_ptr<opentelemetry::trace::Tracer>{tracers_.back()};
Expand Down
12 changes: 11 additions & 1 deletion sdk/test/resource/resource_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class TestResource : public Resource

TEST(ResourceTest, create_without_servicename)
{

ResourceAttributes expected_attributes = {
{"service", "backend"},
{"version", (uint32_t)1},
Expand Down Expand Up @@ -112,6 +111,17 @@ TEST(ResourceTest, create_with_emptyatrributes)
}
EXPECT_EQ(received_attributes.size(), expected_attributes.size()); // for missing service.name
}

TEST(ResourceTest, create_with_schemaurl)
{
const std::string schema_url = "https://opentelemetry.io/schemas/1.2.0";
ResourceAttributes attributes = {};
auto resource = Resource::Create(attributes, schema_url);
auto received_schema_url = resource.GetSchemaURL();

EXPECT_EQ(received_schema_url, schema_url);
}

TEST(ResourceTest, Merge)
{
TestResource resource1(ResourceAttributes({{"service", "backend"}}));
Expand Down
3 changes: 3 additions & 0 deletions sdk/test/trace/tracer_provider_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ TEST(TracerProvider, GetTracer)
auto t3 = tp1.GetTracer("different", "1.0.0");
auto t4 = tp1.GetTracer("");
auto t5 = tp1.GetTracer(opentelemetry::nostd::string_view{});
auto t6 = tp1.GetTracer("different", "1.0.0", "https://opentelemetry.io/schemas/1.2.0");
ASSERT_NE(nullptr, t1);
ASSERT_NE(nullptr, t2);
ASSERT_NE(nullptr, t3);
ASSERT_NE(nullptr, t6);

// Should return the same instance each time.
ASSERT_EQ(t1, t2);
ASSERT_NE(t1, t3);
ASSERT_EQ(t4, t5);
ASSERT_NE(t3, t6);

// Should be an sdk::trace::Tracer with the processor attached.
auto sdkTracer1 = dynamic_cast<Tracer *>(t1.get());
Expand Down