]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/opentracing-cpp/include/opentracing/span.h
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / opentracing-cpp / include / opentracing / span.h
CommitLineData
f67539c2
TL
1#ifndef OPENTRACING_SPAN_H
2#define OPENTRACING_SPAN_H
3
4#include <opentracing/string_view.h>
5#include <opentracing/util.h>
6#include <opentracing/value.h>
7#include <opentracing/version.h>
8#include <chrono>
9#include <functional>
10#include <memory>
11#include <string>
12#include <vector>
13
14namespace opentracing {
15BEGIN_OPENTRACING_ABI_NAMESPACE
16class Tracer;
17
18// SpanContext represents Span state that must propagate to descendant Spans and
19// across process boundaries (e.g., a <trace_id, span_id, sampled> tuple).
20class SpanContext {
21 public:
22 virtual ~SpanContext() = default;
23
24 // ForeachBaggageItem calls a function for each baggage item in the
25 // context. If the function returns false, it will not be called
26 // again and ForeachBaggageItem will return.
27 virtual void ForeachBaggageItem(
28 std::function<bool(const std::string& key, const std::string& value)> f)
29 const = 0;
30
31 // Clone creates a copy of SpanContext.
32 //
33 // Returns nullptr on failure.
34 virtual std::unique_ptr<SpanContext> Clone() const noexcept = 0;
35
36 // Return the ID of the trace.
37 //
38 // Should be globally unique. Every span in a trace shares this ID.
39 //
40 // An empty string will be returned if the tracer does not support this
41 // functionality or an error occurs (this is the case for no-op traces, for
42 // example).
43 virtual std::string ToTraceID() const noexcept { return {}; }
44
45 // Return the ID of the associated Span.
46 //
47 // Should be unique within a trace. Each span within a trace contains a
48 // different ID.
49 //
50 // An empty string will be returned if the tracer does not support this
51 // functionality or an error occurs (this is the case for no-op traces, for
52 // example).
53 virtual std::string ToSpanID() const noexcept { return {}; }
54};
55
56struct LogRecord {
57 using Field = std::pair<std::string, Value>;
58
59 SystemTime timestamp;
60 std::vector<Field> fields;
61};
62
63inline bool operator==(const LogRecord& lhs, const LogRecord& rhs) {
64 return lhs.timestamp == rhs.timestamp && lhs.fields == rhs.fields;
65}
66
67inline bool operator!=(const LogRecord& lhs, const LogRecord& rhs) {
68 return !(lhs == rhs);
69}
70
71// FinishOptions allows Span.Finish callers to override the finish
72// timestamp.
73struct FinishSpanOptions {
74 SteadyTime finish_steady_timestamp;
75
76 // log_records allows the caller to specify the contents of many Log() calls
77 // with a single vector. May be empty.
78 //
79 // None of the LogRecord.timestamp values may be SystemTime() (i.e., they must
80 // be set explicitly). Also, they must be >= the Span's start system timestamp
81 // and <= the finish_steady_timestamp converted to system timestamp
82 // (or SystemTime::now() if finish_steady_timestamp is default-constructed).
83 // Otherwise the behavior of FinishWithOptions() is unspecified.
84 std::vector<LogRecord> log_records;
85};
86
87// FinishSpanOption instances (zero or more) may be passed to Span.Finish.
88class FinishSpanOption {
89 public:
90 FinishSpanOption(const FinishSpanOption&) = delete;
91
92 virtual ~FinishSpanOption() = default;
93
94 virtual void Apply(FinishSpanOptions& options) const noexcept = 0;
95
96 protected:
97 FinishSpanOption() = default;
98};
99
100// Span represents an active, un-finished span in the OpenTracing system.
101//
102// Spans are created by the Tracer interface.
103class Span {
104 public:
105 // If Finish has not already been called for the Span, it's destructor must
106 // do so.
107 virtual ~Span() = default;
108
109 // Sets the end timestamp and finalizes Span state.
110 //
111 // If Finish is called a second time, it is guaranteed to do nothing.
112 void Finish(std::initializer_list<option_wrapper<FinishSpanOption>>
113 option_list = {}) noexcept {
114 FinishSpanOptions options;
115 options.finish_steady_timestamp = SteadyClock::now();
116 for (const auto& option : option_list) option.get().Apply(options);
117 FinishWithOptions(options);
118 }
119
120 virtual void FinishWithOptions(
121 const FinishSpanOptions& finish_span_options) noexcept = 0;
122
123 // Sets or changes the operation name.
124 //
125 // If SetOperationName is called after Finish it leaves the Span in a valid
126 // state, but its behavior is unspecified.
127 virtual void SetOperationName(string_view name) noexcept = 0;
128
129 // Adds a tag to the span.
130 //
131 // If there is a pre-existing tag set for `key`, it is overwritten.
132 //
133 // Tag values can be numeric types, strings, or bools. The behavior of
134 // other tag value types is undefined at the OpenTracing level. If a
135 // tracing system does not know how to handle a particular value type, it
136 // may ignore the tag, but shall not panic.
137 //
138 // If SetTag is called after Finish it leaves the Span in a valid state, but
139 // its behavior is unspecified.
140 virtual void SetTag(string_view key, const Value& value) noexcept = 0;
141
142 // SetBaggageItem sets a key:value pair on this Span and its SpanContext
143 // that also propagates to descendants of this Span.
144 //
145 // SetBaggageItem() enables powerful functionality given a full-stack
146 // opentracing integration (e.g., arbitrary application data from a mobile
147 // app can make it, transparently, all the way into the depths of a storage
148 // system), and with it some powerful costs: use this feature with care.
149 //
150 // IMPORTANT NOTE #1: SetBaggageItem() will only propagate baggage items to
151 // *future* causal descendants of the associated Span.
152 //
153 // IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and
154 // value is copied into every local *and remote* child of the associated
155 // Span, and that can add up to a lot of network and cpu overhead.
156 //
157 // If SetBaggageItem is called after Finish it leaves the Span in a valid
158 // state, but its behavior is unspecified.
159 virtual void SetBaggageItem(string_view restricted_key,
160 string_view value) noexcept = 0;
161
162 // Gets the value for a baggage item given its key. Returns the empty string
163 // if the value isn't found in this Span.
164 virtual std::string BaggageItem(string_view restricted_key) const
165 noexcept = 0;
166
167 // Log is an efficient and type-checked way to record key:value logging data
168 // about a Span. Here's an example:
169 //
170 // span.Log({
171 // {"event", "soft error"},
172 // {"type", "cache timeout"},
173 // {"waited.millis", 1500}});
174 virtual void Log(
175 std::initializer_list<std::pair<string_view, Value>> fields) noexcept = 0;
176
177 virtual void Log(
178 SystemTime timestamp,
179 std::initializer_list<std::pair<string_view, Value>> fields) noexcept = 0;
180
181 virtual void Log(
182 SystemTime timestamp,
183 const std::vector<std::pair<string_view, Value>>& fields) noexcept = 0;
184
185 // context() yields the SpanContext for this Span. Note that the return
186 // value of context() is still valid after a call to Span.Finish(), as is
187 // a call to Span.context() after a call to Span.Finish().
188 virtual const SpanContext& context() const noexcept = 0;
189
190 // Provides access to the Tracer that created this Span.
191 virtual const Tracer& tracer() const noexcept = 0;
192};
193
194// FinishTimestamp is a FinishSpanOption that sets an explicit finish timestamp
195// for a Span.
196class FinishTimestamp : public FinishSpanOption {
197 public:
198 explicit FinishTimestamp(SteadyTime steady_when) noexcept
199 : steady_when_(steady_when) {}
200
201 // Construct a timestamp using a duration from the epoch of std::time_t.
202 // From the documentation on std::time_t's epoch:
203 // Although not defined, this is almost always an integral value holding
204 // the number of seconds (not counting leap seconds) since 00:00, Jan 1
205 // 1970 UTC, corresponding to POSIX time
206 // See http://en.cppreference.com/w/cpp/chrono/c/time_t
207 template <class Rep, class Period>
208 explicit FinishTimestamp(
209 const std::chrono::duration<Rep, Period>& time_since_epoch) noexcept
210 : steady_when_(convert_time_point<SteadyClock>(
211 SystemClock::from_time_t(std::time_t(0)) +
212 std::chrono::duration_cast<SystemClock::duration>(
213 time_since_epoch))) {}
214
215 FinishTimestamp(const FinishTimestamp& other) noexcept
216 : FinishSpanOption(), steady_when_(other.steady_when_) {}
217
218 void Apply(FinishSpanOptions& options) const noexcept override {
219 options.finish_steady_timestamp = steady_when_;
220 }
221
222 private:
223 SteadyTime steady_when_;
224};
225END_OPENTRACING_ABI_NAMESPACE
226} // namespace opentracing
227
228#endif // OPENTRACING_SPAN_H