1 #ifndef OPENTRACING_PROPAGATION_H
2 #define OPENTRACING_PROPAGATION_H
4 #include <opentracing/string_view.h>
5 #include <opentracing/symbols.h>
6 #include <opentracing/util.h>
7 #include <opentracing/version.h>
11 #include <system_error>
13 namespace opentracing
{
14 BEGIN_OPENTRACING_ABI_NAMESPACE
18 enum class SpanReferenceType
{
19 // ChildOfRef refers to a parent Span that caused *and* somehow depends
20 // upon the new child Span. Often (but not always), the parent Span cannot
21 // finish until the child Span does.
23 // An timing diagram for a ChildOfRef that's blocked on the new Span:
25 // [-Parent Span---------]
28 // See http://opentracing.io/spec/
30 // See opentracing.ChildOf()
33 // FollowsFromRef refers to a parent Span that does not depend in any way
34 // on the result of the new child Span. For instance, one might use
35 // FollowsFromRefs to describe pipeline stages separated by queues,
36 // or a fire-and-forget cache insert at the tail end of a web request.
38 // A FollowsFromRef Span is part of the same logical trace as the new Span:
39 // i.e., the new Span is somehow caused by the work of its FollowsFromRef.
41 // All of the following could be valid timing diagrams for children that
42 // "FollowFrom" a parent.
44 // [-Parent Span-] [-Child Span-]
54 // See http://opentracing.io/spec/
56 // See opentracing.FollowsFrom()
60 // Returns the std::error_category class used for opentracing propagation
64 // http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-1.html
65 // https://ned14.github.io/boost.outcome/md_doc_md_03-tutorial_b.html
66 OPENTRACING_API
const std::error_category
& propagation_error_category();
68 // `invalid_span_context_error` occurs when Tracer::Inject() is asked to operate
69 // on a SpanContext which it is not prepared to handle (for example, since it
70 // was created by a different tracer implementation).
71 const std::error_code
invalid_span_context_error(1,
72 propagation_error_category());
74 // `invalid_carrier_error` occurs when Tracer::Inject() or Tracer::Extract()
75 // implementations expect a different type of `carrier` than they are given.
76 const std::error_code
invalid_carrier_error(2, propagation_error_category());
78 // `span_context_corrupted_error` occurs when the `carrier` passed to
79 // Tracer::Extract() is of the expected type but is corrupted.
80 const std::error_code
span_context_corrupted_error(
81 3, propagation_error_category());
83 // `key_not_found_error` occurs when TextMapReader::LookupKey fails to find
84 // an entry for the provided key.
85 const std::error_code
key_not_found_error(4, propagation_error_category());
87 // `lookup_key_not_supported_error` occurs when TextMapReader::LookupKey is
88 // not supported for the provided key.
89 const std::error_code
lookup_key_not_supported_error(
90 5, propagation_error_category());
92 // TextMapReader is the Extract() carrier for the TextMap builtin format. With
93 // it, the caller can decode a SpanContext from entries in a propagated map of
96 // See the HTTPHeaders examples.
99 virtual ~TextMapReader() = default;
101 // LookupKey returns the value for the specified `key` if available. If no
102 // such key is present, it returns `key_not_found_error`.
104 // TextMapReaders are not required to implement this method. If not supported,
105 // the function returns `lookup_key_not_supported_error`.
107 // Tracers may use this as an alternative to `ForeachKey` as a faster way to
108 // extract span context.
109 virtual expected
<string_view
> LookupKey(string_view
/*key*/) const {
110 return make_unexpected(lookup_key_not_supported_error
);
113 // ForeachKey returns TextMap contents via repeated calls to the `f`
114 // function. If any call to `f` returns an error, ForeachKey terminates and
115 // returns that error.
117 // NOTE: The backing store for the TextMapReader may contain data unrelated
118 // to SpanContext. As such, Inject() and Extract() implementations that
119 // call the TextMapWriter and TextMapReader interfaces must agree on a
120 // prefix or other convention to distinguish their own key:value pairs.
122 // The "foreach" callback pattern reduces unnecessary copying in some cases
123 // and also allows implementations to hold locks while the map is read.
124 virtual expected
<void> ForeachKey(
125 std::function
<expected
<void>(string_view key
, string_view value
)> f
)
129 // TextMapWriter is the Inject() carrier for the TextMap builtin format. With
130 // it, the caller can encode a SpanContext for propagation as entries in a map
131 // of unicode strings.
133 // See the HTTPHeaders examples.
134 class TextMapWriter
{
136 virtual ~TextMapWriter() = default;
138 // Set a key:value pair to the carrier. Multiple calls to Set() for the
139 // same key leads to undefined behavior.
141 // NOTE: The backing store for the TextMapWriter may contain data unrelated
142 // to SpanContext. As such, Inject() and Extract() implementations that
143 // call the TextMapWriter and TextMapReader interfaces must agree on a
144 // prefix or other convention to distinguish their own key:value pairs.
145 virtual expected
<void> Set(string_view key
, string_view value
) const = 0;
148 // HTTPHeadersReader is the Extract() carrier for the HttpHeaders builtin
149 // format. With it, the caller can decode a SpanContext from entries in HTTP
152 // For example, Extract():
154 // const Tracer& tracer = /* some tracer */
155 // const HTTPHeadersReader& carrier_reader = /* some carrier */
156 // auto span_context_maybe = tracer.Extract(carrier_reader);
157 // if (!span_context_maybe) {
158 // throw std::runtime_error(span_context_maybe.error().message());
160 // auto span = tracer.StartSpan("op",
161 // { ChildOf(span_context_maybe->get()) });
162 class HTTPHeadersReader
: public TextMapReader
{};
164 // HTTPHeadersWriter is the Inject() carrier for the TextMap builtin format.
165 // With it, the caller can encode a SpanContext for propagation as entries in
166 // http request headers
168 // For example, Inject():
170 // const HTTPHeadersWriter& carrier_writer = /* some carrier */
171 // auto was_successful = span.tracer().Inject(span,
173 // if (!was_successful) {
174 // throw std::runtime_error(was_successful.error().message());
176 class HTTPHeadersWriter
: public TextMapWriter
{};
178 // CustomCarrierReader is the Extract() carrier for a custom format. With it,
179 // the caller can decode a SpanContext from entries in a custom protocol.
180 class CustomCarrierReader
{
182 virtual ~CustomCarrierReader() = default;
184 // Extract is expected to specialize on the tracer implementation so as to
185 // most efficiently decode its context.
186 virtual expected
<std::unique_ptr
<SpanContext
>> Extract(
187 const Tracer
& tracer
) const = 0;
190 // CustomCarrierWriter is the Inject() carrier for a custom format. With it,
191 // the caller can encode a SpanContext for propagation as entries in a custom
193 class CustomCarrierWriter
{
195 virtual ~CustomCarrierWriter() = default;
197 // Inject is expected to specialize on the tracer implementation so as to most
198 // efficiently encode its context.
199 virtual expected
<void> Inject(const Tracer
& tracer
,
200 const SpanContext
& sc
) const = 0;
202 END_OPENTRACING_ABI_NAMESPACE
203 } // namespace opentracing
205 #endif // OPENTRACING_PROPAGATION_H