summaryrefslogtreecommitdiffstats
path: root/include/opentracing/span.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/opentracing/span.h')
-rw-r--r--include/opentracing/span.h228
1 files changed, 228 insertions, 0 deletions
diff --git a/include/opentracing/span.h b/include/opentracing/span.h
new file mode 100644
index 0000000..a48b33c
--- /dev/null
+++ b/include/opentracing/span.h
@@ -0,0 +1,228 @@
+#ifndef OPENTRACING_SPAN_H
+#define OPENTRACING_SPAN_H
+
+#include <opentracing/string_view.h>
+#include <opentracing/util.h>
+#include <opentracing/value.h>
+#include <opentracing/version.h>
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace opentracing {
+BEGIN_OPENTRACING_ABI_NAMESPACE
+class Tracer;
+
+// SpanContext represents Span state that must propagate to descendant Spans and
+// across process boundaries (e.g., a <trace_id, span_id, sampled> tuple).
+class SpanContext {
+ public:
+ virtual ~SpanContext() = default;
+
+ // ForeachBaggageItem calls a function for each baggage item in the
+ // context. If the function returns false, it will not be called
+ // again and ForeachBaggageItem will return.
+ virtual void ForeachBaggageItem(
+ std::function<bool(const std::string& key, const std::string& value)> f)
+ const = 0;
+
+ // Clone creates a copy of SpanContext.
+ //
+ // Returns nullptr on failure.
+ virtual std::unique_ptr<SpanContext> Clone() const noexcept = 0;
+
+ // Return the ID of the trace.
+ //
+ // Should be globally unique. Every span in a trace shares this ID.
+ //
+ // An empty string will be returned if the tracer does not support this
+ // functionality or an error occurs (this is the case for no-op traces, for
+ // example).
+ virtual std::string ToTraceID() const noexcept { return {}; }
+
+ // Return the ID of the associated Span.
+ //
+ // Should be unique within a trace. Each span within a trace contains a
+ // different ID.
+ //
+ // An empty string will be returned if the tracer does not support this
+ // functionality or an error occurs (this is the case for no-op traces, for
+ // example).
+ virtual std::string ToSpanID() const noexcept { return {}; }
+};
+
+struct LogRecord {
+ using Field = std::pair<std::string, Value>;
+
+ SystemTime timestamp;
+ std::vector<Field> fields;
+};
+
+inline bool operator==(const LogRecord& lhs, const LogRecord& rhs) {
+ return lhs.timestamp == rhs.timestamp && lhs.fields == rhs.fields;
+}
+
+inline bool operator!=(const LogRecord& lhs, const LogRecord& rhs) {
+ return !(lhs == rhs);
+}
+
+// FinishOptions allows Span.Finish callers to override the finish
+// timestamp.
+struct FinishSpanOptions {
+ SteadyTime finish_steady_timestamp;
+
+ // log_records allows the caller to specify the contents of many Log() calls
+ // with a single vector. May be empty.
+ //
+ // None of the LogRecord.timestamp values may be SystemTime() (i.e., they must
+ // be set explicitly). Also, they must be >= the Span's start system timestamp
+ // and <= the finish_steady_timestamp converted to system timestamp
+ // (or SystemTime::now() if finish_steady_timestamp is default-constructed).
+ // Otherwise the behavior of FinishWithOptions() is unspecified.
+ std::vector<LogRecord> log_records;
+};
+
+// FinishSpanOption instances (zero or more) may be passed to Span.Finish.
+class FinishSpanOption {
+ public:
+ FinishSpanOption(const FinishSpanOption&) = delete;
+
+ virtual ~FinishSpanOption() = default;
+
+ virtual void Apply(FinishSpanOptions& options) const noexcept = 0;
+
+ protected:
+ FinishSpanOption() = default;
+};
+
+// Span represents an active, un-finished span in the OpenTracing system.
+//
+// Spans are created by the Tracer interface.
+class Span {
+ public:
+ // If Finish has not already been called for the Span, it's destructor must
+ // do so.
+ virtual ~Span() = default;
+
+ // Sets the end timestamp and finalizes Span state.
+ //
+ // If Finish is called a second time, it is guaranteed to do nothing.
+ void Finish(std::initializer_list<option_wrapper<FinishSpanOption>>
+ option_list = {}) noexcept {
+ FinishSpanOptions options;
+ options.finish_steady_timestamp = SteadyClock::now();
+ for (const auto& option : option_list) option.get().Apply(options);
+ FinishWithOptions(options);
+ }
+
+ virtual void FinishWithOptions(
+ const FinishSpanOptions& finish_span_options) noexcept = 0;
+
+ // Sets or changes the operation name.
+ //
+ // If SetOperationName is called after Finish it leaves the Span in a valid
+ // state, but its behavior is unspecified.
+ virtual void SetOperationName(string_view name) noexcept = 0;
+
+ // Adds a tag to the span.
+ //
+ // If there is a pre-existing tag set for `key`, it is overwritten.
+ //
+ // Tag values can be numeric types, strings, or bools. The behavior of
+ // other tag value types is undefined at the OpenTracing level. If a
+ // tracing system does not know how to handle a particular value type, it
+ // may ignore the tag, but shall not panic.
+ //
+ // If SetTag is called after Finish it leaves the Span in a valid state, but
+ // its behavior is unspecified.
+ virtual void SetTag(string_view key, const Value& value) noexcept = 0;
+
+ // SetBaggageItem sets a key:value pair on this Span and its SpanContext
+ // that also propagates to descendants of this Span.
+ //
+ // SetBaggageItem() enables powerful functionality given a full-stack
+ // opentracing integration (e.g., arbitrary application data from a mobile
+ // app can make it, transparently, all the way into the depths of a storage
+ // system), and with it some powerful costs: use this feature with care.
+ //
+ // IMPORTANT NOTE #1: SetBaggageItem() will only propagate baggage items to
+ // *future* causal descendants of the associated Span.
+ //
+ // IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and
+ // value is copied into every local *and remote* child of the associated
+ // Span, and that can add up to a lot of network and cpu overhead.
+ //
+ // If SetBaggageItem is called after Finish it leaves the Span in a valid
+ // state, but its behavior is unspecified.
+ virtual void SetBaggageItem(string_view restricted_key,
+ string_view value) noexcept = 0;
+
+ // Gets the value for a baggage item given its key. Returns the empty string
+ // if the value isn't found in this Span.
+ virtual std::string BaggageItem(string_view restricted_key) const
+ noexcept = 0;
+
+ // Log is an efficient and type-checked way to record key:value logging data
+ // about a Span. Here's an example:
+ //
+ // span.Log({
+ // {"event", "soft error"},
+ // {"type", "cache timeout"},
+ // {"waited.millis", 1500}});
+ virtual void Log(
+ std::initializer_list<std::pair<string_view, Value>> fields) noexcept = 0;
+
+ virtual void Log(
+ SystemTime timestamp,
+ std::initializer_list<std::pair<string_view, Value>> fields) noexcept = 0;
+
+ virtual void Log(
+ SystemTime timestamp,
+ const std::vector<std::pair<string_view, Value>>& fields) noexcept = 0;
+
+ // context() yields the SpanContext for this Span. Note that the return
+ // value of context() is still valid after a call to Span.Finish(), as is
+ // a call to Span.context() after a call to Span.Finish().
+ virtual const SpanContext& context() const noexcept = 0;
+
+ // Provides access to the Tracer that created this Span.
+ virtual const Tracer& tracer() const noexcept = 0;
+};
+
+// FinishTimestamp is a FinishSpanOption that sets an explicit finish timestamp
+// for a Span.
+class FinishTimestamp : public FinishSpanOption {
+ public:
+ explicit FinishTimestamp(SteadyTime steady_when) noexcept
+ : steady_when_(steady_when) {}
+
+ // Construct a timestamp using a duration from the epoch of std::time_t.
+ // From the documentation on std::time_t's epoch:
+ // Although not defined, this is almost always an integral value holding
+ // the number of seconds (not counting leap seconds) since 00:00, Jan 1
+ // 1970 UTC, corresponding to POSIX time
+ // See http://en.cppreference.com/w/cpp/chrono/c/time_t
+ template <class Rep, class Period>
+ explicit FinishTimestamp(
+ const std::chrono::duration<Rep, Period>& time_since_epoch) noexcept
+ : steady_when_(convert_time_point<SteadyClock>(
+ SystemClock::from_time_t(std::time_t(0)) +
+ std::chrono::duration_cast<SystemClock::duration>(
+ time_since_epoch))) {}
+
+ FinishTimestamp(const FinishTimestamp& other) noexcept
+ : FinishSpanOption(), steady_when_(other.steady_when_) {}
+
+ void Apply(FinishSpanOptions& options) const noexcept override {
+ options.finish_steady_timestamp = steady_when_;
+ }
+
+ private:
+ SteadyTime steady_when_;
+};
+END_OPENTRACING_ABI_NAMESPACE
+} // namespace opentracing
+
+#endif // OPENTRACING_SPAN_H