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 InstrumentationLibrary to Tracer #693

Merged
merged 13 commits into from
Apr 26, 2021
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Increment the:

## [Unreleased]

* [SDK] Add instrumentation library and multiple tracer support ([#693](https://github.com/open-telemetry/opentelemetry-cpp/pull/693))

## [0.5.0] 2021-04-26

* [SDK] Support custom span-id and trace-id generator ([#681](https://github.com/open-telemetry/opentelemetry-cpp/pull/681))
Expand Down
1 change: 1 addition & 0 deletions api/include/opentelemetry/trace/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
OPENTELEMETRY_BEGIN_NAMESPACE
namespace trace
{

/**
* Handles span creation and in-process context propagation.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2021, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE

namespace sdk
{
namespace instrumentationlibrary
{

class InstrumentationLibrary
{
public:
InstrumentationLibrary(const InstrumentationLibrary &) = default;

/**
* 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.
* @returns the newly created InstrumentationLibrary.
*/
static nostd::unique_ptr<InstrumentationLibrary> create(nostd::string_view name,
nostd::string_view version = "")
{
return nostd::unique_ptr<InstrumentationLibrary>(
new InstrumentationLibrary{std::string{name}, std::string{version}});
}

/**
* Compare 2 instrumentation libraries.
* @param other the instrumentation library to compare to.
* @returns true if the 2 instrumentation libraries are equal, false otherwise.
*/
bool operator==(const InstrumentationLibrary &other) const
{
return equal(other.name_, other.version_);
}

/**
* 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.
* @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
{
return this->name_ == name && this->version_ == version;
}

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

private:
InstrumentationLibrary(nostd::string_view name, nostd::string_view version)
: name_(name), version_(version)
{}

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

} // namespace instrumentationlibrary
} // namespace sdk

OPENTELEMETRY_END_NAMESPACE
19 changes: 16 additions & 3 deletions sdk/include/opentelemetry/sdk/trace/tracer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "opentelemetry/sdk/common/atomic_shared_ptr.h"
#include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
#include "opentelemetry/sdk/resource/resource.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/samplers/always_on.h"
Expand All @@ -16,11 +17,16 @@ namespace sdk
{
namespace trace
{

using namespace opentelemetry::sdk::instrumentationlibrary;

class Tracer final : public trace_api::Tracer, public std::enable_shared_from_this<Tracer>
{
public:
/** Construct a new Tracer with the given context pipeline. */
explicit Tracer(std::shared_ptr<sdk::trace::TracerContext> context) noexcept;
explicit Tracer(std::shared_ptr<sdk::trace::TracerContext> context,
std::unique_ptr<InstrumentationLibrary> instrumentation_library =
InstrumentationLibrary::create("")) noexcept;

nostd::shared_ptr<trace_api::Span> StartSpan(
nostd::string_view name,
Expand All @@ -33,16 +39,23 @@ class Tracer final : public trace_api::Tracer, public std::enable_shared_from_th
void CloseWithMicroseconds(uint64_t timeout) noexcept override;

/** Returns the currently active span processor. */
SpanProcessor &GetActiveProcessor() noexcept { return context_->GetActiveProcessor(); }
SpanProcessor &GetActiveProcessor() const noexcept { return context_->GetActiveProcessor(); }

/** Returns the configured Id generator */
IdGenerator &GetIdGenerator() noexcept { return context_->GetIdGenerator(); }
IdGenerator &GetIdGenerator() const noexcept { return context_->GetIdGenerator(); }

/** Returns the associated instruementation library */
const InstrumentationLibrary &GetInstrumentationLibrary() const noexcept
{
return *instrumentation_library_;
}

// Note: Test only
Sampler &GetSampler() { return context_->GetSampler(); }

private:
std::shared_ptr<sdk::trace::TracerContext> context_;
std::shared_ptr<InstrumentationLibrary> instrumentation_library_;
};
} // namespace trace
} // namespace sdk
Expand Down
5 changes: 4 additions & 1 deletion sdk/include/opentelemetry/sdk/trace/tracer_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <vector>

#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/sdk/resource/resource.h"
Expand Down Expand Up @@ -73,7 +75,8 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider

private:
std::shared_ptr<sdk::trace::TracerContext> context_;
std::shared_ptr<opentelemetry::trace::Tracer> tracer_;
std::vector<std::shared_ptr<opentelemetry::sdk::trace::Tracer>> tracers_;
std::mutex lock_;
};
} // namespace trace
} // namespace sdk
Expand Down
5 changes: 4 additions & 1 deletion sdk/src/trace/tracer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ namespace sdk
namespace trace
{

Tracer::Tracer(std::shared_ptr<sdk::trace::TracerContext> context) noexcept : context_{context} {}
Tracer::Tracer(std::shared_ptr<sdk::trace::TracerContext> context,
std::unique_ptr<InstrumentationLibrary> instrumentation_library) noexcept
: context_{context}, instrumentation_library_{std::move(instrumentation_library)}
{}

trace_api::SpanContext GetCurrentSpanContext(const trace_api::SpanContext &explicit_parent)
{
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/trace/tracer_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ TracerContext::TracerContext(std::unique_ptr<SpanProcessor> processor,

Sampler &TracerContext::GetSampler() const noexcept
{
return *sampler_.get();
return *sampler_;
}

const opentelemetry::sdk::resource::Resource &TracerContext::GetResource() const noexcept
Expand Down
24 changes: 21 additions & 3 deletions sdk/src/trace/tracer_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace sdk
namespace trace
{
TracerProvider::TracerProvider(std::shared_ptr<sdk::trace::TracerContext> context) noexcept
: context_{context}, tracer_(new Tracer(context))
: context_{context}
{}

TracerProvider::TracerProvider(std::unique_ptr<SpanProcessor> processor,
Expand All @@ -19,11 +19,29 @@ TracerProvider::TracerProvider(std::unique_ptr<SpanProcessor> processor,
std::move(id_generator)))
{}

opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> TracerProvider::GetTracer(
nostd::shared_ptr<opentelemetry::trace::Tracer> TracerProvider::GetTracer(
nostd::string_view library_name,
nostd::string_view library_version) noexcept
{
return opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer>(tracer_);
// if (library_name == "") {
// // TODO: log invalid library_name.
// }

const std::lock_guard<std::mutex> guard(lock_);

for (auto &tracer : tracers_)
lalitb marked this conversation as resolved.
Show resolved Hide resolved
{
auto &tracer_lib = tracer->GetInstrumentationLibrary();
if (tracer_lib.equal(library_name, library_version))
{
return nostd::shared_ptr<opentelemetry::trace::Tracer>{tracer};
}
}

auto lib = InstrumentationLibrary::create(library_name, library_version);
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()};
}

void TracerProvider::RegisterPipeline(std::unique_ptr<SpanProcessor> processor) noexcept
Expand Down
1 change: 1 addition & 0 deletions sdk/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ add_subdirectory(trace)
add_subdirectory(metrics)
add_subdirectory(logs)
add_subdirectory(resource)
add_subdirectory(instrumentationlibrary)
13 changes: 13 additions & 0 deletions sdk/test/instrumentationlibrary/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark")

cc_test(
name = "instrumentationlibrary_test",
srcs = [
"instrumentationlibrary_test.cc",
],
deps = [
"//api",
"//sdk:headers",
"@com_google_googletest//:gtest_main",
],
)
12 changes: 12 additions & 0 deletions sdk/test/instrumentationlibrary/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
include(GoogleTest)

foreach(testname instrumentationlibrary_test)
add_executable(${testname} "${testname}.cc")
target_link_libraries(
${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS}
${CMAKE_THREAD_LIBS_INIT} opentelemetry_api)
gtest_add_tests(
TARGET ${testname}
TEST_PREFIX instrumentationlibrary.
TEST_LIST ${testname})
endforeach()
34 changes: 34 additions & 0 deletions sdk/test/instrumentationlibrary/instrumentationlibrary_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2021, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"

#include <gtest/gtest.h>
#include <string>
#include <vector>

using namespace opentelemetry;
using namespace opentelemetry::sdk::instrumentationlibrary;

TEST(InstrumentationLibrary, CreateInstrumentationLibrary)
{

std::string library_name = "opentelemetry-cpp";
std::string library_version = "0.1.0";
auto instrumentation_library = InstrumentationLibrary::create(library_name, library_version);

EXPECT_EQ(instrumentation_library->GetName(), library_name);
EXPECT_EQ(instrumentation_library->GetVersion(), library_version);
}
15 changes: 12 additions & 3 deletions sdk/test/trace/tracer_provider_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ TEST(TracerProvider, GetTracer)

// Should return the same instance each time.
ASSERT_EQ(t1, t2);
// TODO: t3 should be a different instance.
ASSERT_EQ(t1, t3);
ASSERT_NE(t1, t3);

// Should be an sdk::trace::Tracer with the processor attached.
auto sdkTracer1 = dynamic_cast<Tracer *>(t1.get());
Expand All @@ -37,6 +36,16 @@ TEST(TracerProvider, GetTracer)
std::unique_ptr<IdGenerator>(new RandomIdGenerator)));
auto sdkTracer2 = dynamic_cast<Tracer *>(tp2.GetTracer("test").get());
ASSERT_EQ("AlwaysOffSampler", sdkTracer2->GetSampler().GetDescription());

auto instrumentation_library1 = sdkTracer1->GetInstrumentationLibrary();
ASSERT_EQ(instrumentation_library1.GetName(), "test");
ASSERT_EQ(instrumentation_library1.GetVersion(), "");

// Should be an sdk::trace::Tracer with the processor attached.
auto sdkTracer3 = dynamic_cast<Tracer *>(t3.get());
auto instrumentation_library3 = sdkTracer3->GetInstrumentationLibrary();
ASSERT_EQ(instrumentation_library3.GetName(), "different");
ASSERT_EQ(instrumentation_library3.GetVersion(), "1.0.0");
}

TEST(TracerProvider, Shutdown)
Expand All @@ -55,4 +64,4 @@ TEST(TracerProvider, ForceFlush)
TracerProvider tp1(std::move(processor1));

EXPECT_TRUE(tp1.ForceFlush());
}
}
2 changes: 1 addition & 1 deletion sdk/test/trace/tracer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -593,4 +593,4 @@ TEST(Tracer, ExpectParent)

EXPECT_EQ(spandata_first->GetSpanId(), spandata_second->GetParentSpanId());
EXPECT_EQ(spandata_second->GetSpanId(), spandata_third->GetParentSpanId());
}
}