From 2f228b0bfee55e207c50ab46333e74e0aee5854d Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 12 Mar 2020 21:17:10 -0700 Subject: [PATCH] Add interface for a trace recorder (#44) * Start Recorder api * Fill out Span api * Reformat * Fill out Tracer class * Add cmake build * Add commenting * Fix formatting * Reformat * Fix date * Make mutex mutable * s/mutex_/mu_/ * Remove AddEvent with steady timestamp * Fix typo * Fill in IsRecordable * Use namespace macros * Add thread-compatible note * Add commenting --- CMakeLists.txt | 3 + api/include/opentelemetry/plugin/tracer.h | 4 - api/include/opentelemetry/trace/noop.h | 1 - api/include/opentelemetry/trace/span.h | 1 - examples/plugin/plugin/tracer.cc | 2 - sdk/CMakeLists.txt | 1 + sdk/src/CMakeLists.txt | 1 + sdk/src/{opentelemetry => }/context/TBD | 0 .../distributedcontext/TBD | 0 sdk/src/{opentelemetry => }/internal/TBD | 0 sdk/src/{opentelemetry => }/logs/TBD | 0 sdk/src/{opentelemetry => }/metrics/TBD | 0 sdk/src/{opentelemetry => }/resource/TBD | 0 sdk/src/trace/BUILD | 25 ++++++ sdk/src/trace/CMakeLists.txt | 1 + sdk/src/trace/recordable.h | 48 ++++++++++++ sdk/src/trace/recorder.h | 31 ++++++++ sdk/src/trace/span.cc | 77 +++++++++++++++++++ sdk/src/trace/span.h | 46 +++++++++++ sdk/src/trace/tracer.cc | 20 +++++ sdk/src/trace/tracer.h | 32 ++++++++ 21 files changed, 285 insertions(+), 8 deletions(-) create mode 100644 sdk/CMakeLists.txt create mode 100644 sdk/src/CMakeLists.txt rename sdk/src/{opentelemetry => }/context/TBD (100%) rename sdk/src/{opentelemetry => }/distributedcontext/TBD (100%) rename sdk/src/{opentelemetry => }/internal/TBD (100%) rename sdk/src/{opentelemetry => }/logs/TBD (100%) rename sdk/src/{opentelemetry => }/metrics/TBD (100%) rename sdk/src/{opentelemetry => }/resource/TBD (100%) create mode 100644 sdk/src/trace/BUILD create mode 100644 sdk/src/trace/CMakeLists.txt create mode 100644 sdk/src/trace/recordable.h create mode 100644 sdk/src/trace/recorder.h create mode 100644 sdk/src/trace/span.cc create mode 100644 sdk/src/trace/span.h create mode 100644 sdk/src/trace/tracer.cc create mode 100644 sdk/src/trace/tracer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c34736db498..c10f92d39d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,4 +20,7 @@ endif() include_directories(api/include) add_subdirectory(api) +include_directories(sdk/include) +include_directories(sdk) +add_subdirectory(sdk) add_subdirectory(examples) diff --git a/api/include/opentelemetry/plugin/tracer.h b/api/include/opentelemetry/plugin/tracer.h index 4399a407ca4..5c327f8ee2a 100644 --- a/api/include/opentelemetry/plugin/tracer.h +++ b/api/include/opentelemetry/plugin/tracer.h @@ -24,10 +24,6 @@ class Span final : public trace::Span { span_->AddEvent(name, timestamp); } - void AddEvent(nostd::string_view name, core::SteadyTimestamp timestamp) noexcept override - { - span_->AddEvent(name, timestamp); - } void SetStatus(trace::CanonicalCode code, nostd::string_view description) noexcept override { diff --git a/api/include/opentelemetry/trace/noop.h b/api/include/opentelemetry/trace/noop.h index 8ebdd3c34c9..a3af68a55eb 100644 --- a/api/include/opentelemetry/trace/noop.h +++ b/api/include/opentelemetry/trace/noop.h @@ -26,7 +26,6 @@ class NoopSpan final : public Span void AddEvent(nostd::string_view name) noexcept override {} void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept override {} - void AddEvent(nostd::string_view name, core::SteadyTimestamp timestamp) noexcept override {} void SetStatus(CanonicalCode code, nostd::string_view description) noexcept override {} diff --git a/api/include/opentelemetry/trace/span.h b/api/include/opentelemetry/trace/span.h index 882116ec4f2..bed9e55afe5 100644 --- a/api/include/opentelemetry/trace/span.h +++ b/api/include/opentelemetry/trace/span.h @@ -76,7 +76,6 @@ class Span // Adds an event to the Span, with a custom timestamp. virtual void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept = 0; - virtual void AddEvent(nostd::string_view name, core::SteadyTimestamp timestamp) noexcept = 0; // TODO // Adds an event to the Span, with a custom timestamp, and attributes. diff --git a/examples/plugin/plugin/tracer.cc b/examples/plugin/plugin/tracer.cc index 02a828e0fae..5a0c861ea6a 100644 --- a/examples/plugin/plugin/tracer.cc +++ b/examples/plugin/plugin/tracer.cc @@ -26,8 +26,6 @@ class Span final : public trace::Span void AddEvent(nostd::string_view /*name*/, core::SystemTimestamp /*timestamp*/) noexcept override {} - void AddEvent(nostd::string_view /*name*/, core::SteadyTimestamp /*timestamp*/) noexcept override - {} void SetStatus(trace::CanonicalCode /*code*/, nostd::string_view /*description*/) noexcept override diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt new file mode 100644 index 00000000000..febd4f0ab6f --- /dev/null +++ b/sdk/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(src) diff --git a/sdk/src/CMakeLists.txt b/sdk/src/CMakeLists.txt new file mode 100644 index 00000000000..2cea47fa7bc --- /dev/null +++ b/sdk/src/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(trace) diff --git a/sdk/src/opentelemetry/context/TBD b/sdk/src/context/TBD similarity index 100% rename from sdk/src/opentelemetry/context/TBD rename to sdk/src/context/TBD diff --git a/sdk/src/opentelemetry/distributedcontext/TBD b/sdk/src/distributedcontext/TBD similarity index 100% rename from sdk/src/opentelemetry/distributedcontext/TBD rename to sdk/src/distributedcontext/TBD diff --git a/sdk/src/opentelemetry/internal/TBD b/sdk/src/internal/TBD similarity index 100% rename from sdk/src/opentelemetry/internal/TBD rename to sdk/src/internal/TBD diff --git a/sdk/src/opentelemetry/logs/TBD b/sdk/src/logs/TBD similarity index 100% rename from sdk/src/opentelemetry/logs/TBD rename to sdk/src/logs/TBD diff --git a/sdk/src/opentelemetry/metrics/TBD b/sdk/src/metrics/TBD similarity index 100% rename from sdk/src/opentelemetry/metrics/TBD rename to sdk/src/metrics/TBD diff --git a/sdk/src/opentelemetry/resource/TBD b/sdk/src/resource/TBD similarity index 100% rename from sdk/src/opentelemetry/resource/TBD rename to sdk/src/resource/TBD diff --git a/sdk/src/trace/BUILD b/sdk/src/trace/BUILD new file mode 100644 index 00000000000..f990c57425b --- /dev/null +++ b/sdk/src/trace/BUILD @@ -0,0 +1,25 @@ +# Copyright 2020, 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. + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "trace", + srcs = glob(["**/*.cc"]), + hdrs = glob(["**/*.h"]), + include_prefix = "src/trace", + deps = [ + "//api", + ], +) diff --git a/sdk/src/trace/CMakeLists.txt b/sdk/src/trace/CMakeLists.txt new file mode 100644 index 00000000000..62a2187c46e --- /dev/null +++ b/sdk/src/trace/CMakeLists.txt @@ -0,0 +1 @@ +add_library(opentelemetry_trace tracer.cc span.cc) diff --git a/sdk/src/trace/recordable.h b/sdk/src/trace/recordable.h new file mode 100644 index 00000000000..a7298200a58 --- /dev/null +++ b/sdk/src/trace/recordable.h @@ -0,0 +1,48 @@ +#pragma once + +#include "opentelemetry/core/timestamp.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/trace/canonical_code.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +namespace trace_api = opentelemetry::trace; + +/** + * Maintains a representation of a span in a format that can be processed by a recorder. + * + * This class is thread-compatible. + */ +class Recordable +{ +public: + virtual ~Recordable() = default; + + /** + * Add an event to a span. + * @param name the name of the event + * @param timestamp the timestamp of the event + */ + virtual void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept = 0; + + /** + * Set the status of the span. + * @param code the status code + * @param description a description of the status + */ + virtual void SetStatus(trace_api::CanonicalCode code, + nostd::string_view description) noexcept = 0; + + /** + * Set the name of the span. + * @param name the name to set + */ + virtual void SetName(nostd::string_view name) noexcept = 0; +}; +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/trace/recorder.h b/sdk/src/trace/recorder.h new file mode 100644 index 00000000000..b701c113d6a --- /dev/null +++ b/sdk/src/trace/recorder.h @@ -0,0 +1,31 @@ +#pragma once + +#include "opentelemetry/trace/span_id.h" +#include "opentelemetry/trace/trace_id.h" +#include "opentelemetry/version.h" +#include "src/trace/recordable.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +class Recorder +{ +public: + virtual ~Recorder() = default; + + /** + * @return a Recordable object to maintain a data representation of a span. + */ + virtual std::unique_ptr MakeRecordable() noexcept = 0; + + /** + * Record a span. + * @param recordable the data representation of the span. + */ + virtual void Record(std::unique_ptr &&recordable) noexcept = 0; +}; +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/trace/span.cc b/sdk/src/trace/span.cc new file mode 100644 index 00000000000..54fde5d81d3 --- /dev/null +++ b/sdk/src/trace/span.cc @@ -0,0 +1,77 @@ +#include "src/trace/span.h" + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +Span::Span(std::shared_ptr &&tracer, + nostd::string_view name, + const trace_api::StartSpanOptions &options) noexcept + : tracer_{std::move(tracer)}, recordable_{tracer_->recorder().MakeRecordable()} +{ + (void)options; + if (recordable_ == nullptr) + { + return; + } + recordable_->SetName(name); +} + +Span::~Span() +{ + End(); +} + +void Span::AddEvent(nostd::string_view name) noexcept +{ + (void)name; +} + +void Span::AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept +{ + (void)name; + (void)timestamp; +} + +void Span::SetStatus(trace_api::CanonicalCode code, nostd::string_view description) noexcept +{ + std::lock_guard lock_guard{mu_}; + if (recordable_ == nullptr) + { + return; + } + recordable_->SetStatus(code, description); +} + +void Span::UpdateName(nostd::string_view name) noexcept +{ + std::lock_guard lock_guard{mu_}; + if (recordable_ == nullptr) + { + return; + } + recordable_->SetName(name); +} + +void Span::End() noexcept +{ + std::lock_guard lock_guard{mu_}; + if (recordable_ == nullptr) + { + return; + } + tracer_->recorder().Record(std::move(recordable_)); + recordable_.reset(); +} + +bool Span::IsRecording() const noexcept +{ + std::lock_guard lock_guard{mu_}; + return recordable_ != nullptr; +} +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/trace/span.h b/sdk/src/trace/span.h new file mode 100644 index 00000000000..f4f924aa334 --- /dev/null +++ b/sdk/src/trace/span.h @@ -0,0 +1,46 @@ +#pragma once + +#include "opentelemetry/version.h" +#include "src/trace/tracer.h" + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +namespace trace_api = opentelemetry::trace; + +class Span final : public trace_api::Span +{ +public: + explicit Span(std::shared_ptr &&tracer, + nostd::string_view name, + const trace_api::StartSpanOptions &options) noexcept; + + ~Span() override; + + // trace_api::Span + void AddEvent(nostd::string_view name) noexcept override; + + void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept override; + + void SetStatus(trace_api::CanonicalCode code, nostd::string_view description) noexcept override; + + void UpdateName(nostd::string_view name) noexcept override; + + void End() noexcept override; + + bool IsRecording() const noexcept override; + + trace_api::Tracer &tracer() const noexcept override { return *tracer_; } + +private: + std::shared_ptr tracer_; + mutable std::mutex mu_; + std::unique_ptr recordable_; +}; +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/trace/tracer.cc b/sdk/src/trace/tracer.cc new file mode 100644 index 00000000000..4a4c484bc92 --- /dev/null +++ b/sdk/src/trace/tracer.cc @@ -0,0 +1,20 @@ +#include "src/trace/tracer.h" + +#include "opentelemetry/version.h" +#include "src/trace/span.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +nostd::unique_ptr Tracer::StartSpan( + nostd::string_view name, + const trace_api::StartSpanOptions &options) noexcept +{ + return nostd::unique_ptr{new (std::nothrow) + Span{this->shared_from_this(), name, options}}; +} +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/trace/tracer.h b/sdk/src/trace/tracer.h new file mode 100644 index 00000000000..c242b3c3a75 --- /dev/null +++ b/sdk/src/trace/tracer.h @@ -0,0 +1,32 @@ +#pragma once + +#include "opentelemetry/trace/tracer.h" +#include "opentelemetry/version.h" +#include "src/trace/recorder.h" + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +class Tracer final : public trace_api::Tracer, public std::enable_shared_from_this +{ +public: + // Note: recorder must be non-null + explicit Tracer(std::unique_ptr &&recorder) noexcept : recorder_{std::move(recorder)} {} + + Recorder &recorder() const noexcept { return *recorder_; } + + // trace_api::Tracer + nostd::unique_ptr StartSpan( + nostd::string_view name, + const trace_api::StartSpanOptions &options = {}) noexcept override; + +private: + std::unique_ptr recorder_; +}; +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE