// Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include "opentelemetry/common/attribute_value.h" #include "opentelemetry/common/key_value_iterable_view.h" #include "opentelemetry/nostd/span.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/type_traits.h" #include "opentelemetry/trace/span_context.h" #include "opentelemetry/trace/span_context_kv_iterable.h" #include "opentelemetry/trace/span_context_kv_iterable_view.h" #include "opentelemetry/trace/span_metadata.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace trace { class Tracer; /** * A Span represents a single operation within a Trace. * * Span attributes can be provided: * - at span creation time, using Tracer::StartSpan(), * - during the span lifetime, using Span::SetAttribute() * * Please note that head samplers, * in the SDK (@ref opentelemetry::sdk::trace::Sampler), * can only make sampling decisions based on data known * at span creation time. * * When attributes are known early, adding attributes * with @ref opentelemetry::trace::Tracer::StartSpan() is preferable. * * Attributes added or changed with Span::SetAttribute() * can not change a sampler decision. * * Likewise, links can be provided: * - at span creation time, using Tracer::StartSpan(), * - during the span lifetime, using Span::AddLink() or Span::AddLinks(). * * When links are known early, adding links * with @ref opentelemetry::trace::Tracer::StartSpan() is preferable. * * Links added with Span::AddLink() or Span::AddLinks() * can not change a sampler decision. */ class Span { public: // Note that Spans should be created using the Tracer class. Please refer to // tracer.h for documentation. Span() = default; // The Span destructor End()s the Span, if it hasn't been ended already. virtual ~Span() = default; // Not copiable or movable. Span(const Span &) = delete; Span(Span &&) = delete; Span &operator=(const Span &) = delete; Span &operator=(Span &&) = delete; /** * Sets an attribute on the Span (ABI). * * If the Span previously contained a mapping for the key, * the old value is replaced. * * See comments about sampling in @ref opentelemetry::trace::Span */ virtual void SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept = 0; // Adds an event to the Span. virtual void AddEvent(nostd::string_view name) noexcept = 0; // Adds an event to the Span, with a custom timestamp. virtual void AddEvent(nostd::string_view name, common::SystemTimestamp timestamp) noexcept = 0; // Adds an event to the Span, with a custom timestamp, and attributes. virtual void AddEvent(nostd::string_view name, common::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept = 0; virtual void AddEvent(nostd::string_view name, const common::KeyValueIterable &attributes) noexcept { this->AddEvent(name, std::chrono::system_clock::now(), attributes); } template ::value> * = nullptr> void AddEvent(nostd::string_view name, common::SystemTimestamp timestamp, const T &attributes) noexcept { this->AddEvent(name, timestamp, common::KeyValueIterableView{attributes}); } template ::value> * = nullptr> void AddEvent(nostd::string_view name, const T &attributes) noexcept { this->AddEvent(name, common::KeyValueIterableView{attributes}); } void AddEvent(nostd::string_view name, common::SystemTimestamp timestamp, std::initializer_list> attributes) noexcept { this->AddEvent(name, timestamp, nostd::span>{ attributes.begin(), attributes.end()}); } void AddEvent(nostd::string_view name, std::initializer_list> attributes) noexcept { this->AddEvent(name, std::chrono::system_clock::now(), nostd::span>{ attributes.begin(), attributes.end()}); } #if OPENTELEMETRY_ABI_VERSION_NO >= 2 /** * Add link (ABI). * * See comments about sampling in @ref opentelemetry::trace::Span * * @since ABI_VERSION 2 */ virtual void AddLink(const SpanContext &target, const common::KeyValueIterable &attrs) noexcept = 0; /** * Add links (ABI). * * See comments about sampling in @ref opentelemetry::trace::Span * * @since ABI_VERSION 2 */ virtual void AddLinks(const SpanContextKeyValueIterable &links) noexcept = 0; /** * Add link (API helper). * * See comments about sampling in @ref opentelemetry::trace::Span * * @since ABI_VERSION 2 */ template ::value> * = nullptr> void AddLink(const SpanContext &target, const U &attrs) { common::KeyValueIterableView view(attrs); this->AddLink(target, view); } /** * Add link (API helper). * * See comments about sampling in @ref opentelemetry::trace::Span * * @since ABI_VERSION 2 */ void AddLink(const SpanContext &target, std::initializer_list> attrs) { /* Build a container from std::initializer_list. */ nostd::span> container{ attrs.begin(), attrs.end()}; /* Build a view on the container. */ common::KeyValueIterableView< nostd::span>> view(container); return this->AddLink(target, view); } /** * Add links (API helper). * * See comments about sampling in @ref opentelemetry::trace::Span * * @since ABI_VERSION 2 */ template ::value> * = nullptr> void AddLinks(const U &links) { SpanContextKeyValueIterableView view(links); this->AddLinks(view); } /** * Add links (API helper). * * See comments about sampling in @ref opentelemetry::trace::Span * * @since ABI_VERSION 2 */ void AddLinks( std::initializer_list< std::pair>>> links) { /* Build a container from std::initializer_list. */ nostd::span>>> container{links.begin(), links.end()}; /* Build a view on the container. */ SpanContextKeyValueIterableView>>>> view(container); return this->AddLinks(view); } #endif /* OPENTELEMETRY_ABI_VERSION_NO */ // Sets the status of the span. The default status is Unset. Only the value of // the last call will be // recorded, and implementations are free to ignore previous calls. virtual void SetStatus(StatusCode code, nostd::string_view description = "") noexcept = 0; // Updates the name of the Span. If used, this will override the name provided // during creation. virtual void UpdateName(nostd::string_view name) noexcept = 0; /** * Mark the end of the Span. * Only the timing of the first End call for a given Span will be recorded, * and implementations are free to ignore all further calls. * @param options can be used to manually define span properties like the end * timestamp */ virtual void End(const trace::EndSpanOptions &options = {}) noexcept = 0; virtual trace::SpanContext GetContext() const noexcept = 0; // Returns true if this Span is recording tracing events (e.g. SetAttribute, // AddEvent). virtual bool IsRecording() const noexcept = 0; }; } // namespace trace OPENTELEMETRY_END_NAMESPACE