Skip to content

Commit

Permalink
Add InstrumentationLibrary to Tracer (#693)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomsonTan authored Apr 26, 2021
1 parent 7909008 commit 30434fa
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 13 deletions.
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_)
{
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());
}
}

0 comments on commit 30434fa

Please sign in to comment.