userver: userver/tracing/span.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
span.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/tracing/span.hpp
4/// @brief @copybrief tracing::Span
5
6#include <optional>
7#include <string_view>
8
9#include <userver/logging/log.hpp>
10#include <userver/logging/log_extra.hpp>
11#include <userver/tracing/scope_time.hpp>
12#include <userver/tracing/tracer_fwd.hpp>
13#include <userver/utils/impl/source_location.hpp>
14#include <userver/utils/internal_tag_fwd.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace tracing {
19
20class SpanBuilder;
21
22/// @brief Measures the execution time of the current code block, links it with
23/// the parent tracing::Spans and stores that info in the log.
24///
25/// See @ref scripts/docs/en/userver/logging.md for usage examples and more
26/// descriptions.
27///
28/// @warning Shall be created only as a local variable. Do not use it as a
29/// class member!
30class Span final {
31 public:
32 class Impl;
33
34 explicit Span(TracerPtr tracer, std::string name, const Span* parent,
35 ReferenceType reference_type,
36 logging::Level log_level = logging::Level::kInfo,
37 utils::impl::SourceLocation source_location =
38 utils::impl::SourceLocation::Current());
39
40 /// Use default tracer and implicit coro local storage for parent
41 /// identification, takes TraceID from the parent.
42 ///
43 /// For extremely rare cases where a new Trace ID is required use
44 /// tracing::Span::MakeSpan().
45 explicit Span(std::string name,
46 ReferenceType reference_type = ReferenceType::kChild,
47 logging::Level log_level = logging::Level::kInfo,
48 utils::impl::SourceLocation source_location =
50
51 /// @cond
52 // For internal use only
53 explicit Span(Span::Impl& impl);
54 /// @endcond
55
56 Span(Span&& other) noexcept;
57
58 ~Span();
59
60 Span& operator=(const Span&) = delete;
61
62 Span& operator=(Span&&) = delete;
63
64 /// @brief Returns the Span of the current task.
65 ///
66 /// Should not be called in non-coroutine
67 /// context. Should not be called from a task with no alive Span.
68 ///
69 /// Rule of thumb: it is safe to call it from a task created by
70 /// utils::Async/utils::CriticalAsync/utils::PeriodicTask. If current task was
71 /// created with an explicit engine::impl::*Async(), you have to create a Span
72 /// beforehand.
73 static Span& CurrentSpan();
74
75 /// @brief Returns nullptr if called in non-coroutine context or from a task
76 /// with no alive Span; otherwise returns the Span of the current task.
77 static Span* CurrentSpanUnchecked();
78
79 /// Factory function for extremely rare cases of creating a Span with custom
80 /// IDs; prefer Span constructor instead.
81 ///
82 /// @return A new Span attached to current Span (if any) but with a new
83 /// Trace ID.
84 /// @param name Name of a new Span
85 /// @param trace_id New Trace ID; if empty then the Trce ID is autogenerated
86 /// @param parent_span_id Id of the parent Span, could be empty.
87 static Span MakeSpan(std::string name, std::string_view trace_id,
88 std::string_view parent_span_id);
89
90 /// Factory function for extremely rare cases of creating a Span with custom
91 /// IDs; prefer Span constructor instead.
92 ///
93 /// @return A new Span attached to current Span (if any), sets `link`.
94 /// @param name Name of a new Span
95 /// @param trace_id New Trace ID; if empty then the Trce ID is autogenerated
96 /// @param parent_span_id Id of the parent Span, could be empty.
97 /// @param link The new link
98 static Span MakeSpan(std::string name, std::string_view trace_id,
99 std::string_view parent_span_id, std::string link);
100
101 /// Factory function for rare cases of creating a root Span that starts
102 /// the trace_id chain, ignoring `CurrentSpan`, if any. Useful
103 /// in background jobs, periodics, distlock tasks, cron tasks, etc.
104 /// The result of such jobs is not directly requested by anything.
105 ///
106 /// @return A new Span that is the root of a new Span hierarchy.
107 /// @param name Name of a new Span
108 /// @param log_level Log level for the span's own log record
109 static Span MakeRootSpan(std::string name,
110 logging::Level log_level = logging::Level::kInfo);
111
112 /// Create a child which can be used independently from the parent.
113 ///
114 /// The child shares no state with its parent. If you need to run code in
115 /// parallel, create a child span and use the child in a separate task.
116 Span CreateChild(std::string name) const;
117
118 Span CreateFollower(std::string name) const;
119
120 /// @brief Creates a tracing::ScopeTime attached to the span.
122
123 /// @brief Creates a tracing::ScopeTime attached to the Span and starts
124 /// measuring execution time.
125 ScopeTime CreateScopeTime(std::string name);
126
127 /// Returns total time elapsed for a certain scope of this span.
128 /// If there is no record for the scope, returns 0.
129 ScopeTime::Duration GetTotalDuration(const std::string& scope_name) const;
130
131 /// Returns total time elapsed for a certain scope of this span.
132 /// If there is no record for the scope, returns 0.
133 ///
134 /// Prefer using Span::GetTotalDuration()
136 const std::string& scope_name) const;
137
138 /// Add a tag that is used on each logging in this Span and all
139 /// future children.
140 void AddTag(std::string key, logging::LogExtra::Value value);
141
142 /// Add a tag that is used on each logging in this Span and all
143 /// future children. It will not be possible to change its value.
144 void AddTagFrozen(std::string key, logging::LogExtra::Value value);
145
146 /// Add a tag that is local to the Span (IOW, it is not propagated to
147 /// future children) and logged only once in the destructor of the Span.
148 void AddNonInheritableTag(std::string key, logging::LogExtra::Value value);
149
150 /// @brief Sets level for tags logging
151 void SetLogLevel(logging::Level log_level);
152
153 /// @brief Returns level for tags logging
155
156 /// @brief Sets the local log level that disables logging of this span if
157 /// the local log level set and greater than the main log level of the Span.
158 void SetLocalLogLevel(std::optional<logging::Level> log_level);
159
160 /// @brief Returns the local log level that disables logging of this span if
161 /// it is set and greater than the main log level of the Span.
162 std::optional<logging::Level> GetLocalLogLevel() const;
163
164 /// Set link - a request ID within a service. Can be called only once.
165 ///
166 /// Propagates within a single service, but not from client to server. A new
167 /// link is generated for the "root" request handling task
168 void SetLink(std::string link);
169
170 /// Set parent_link - an ID . Can be called only once.
171 void SetParentLink(std::string parent_link);
172
173 /// Get link - a request ID within the service.
174 ///
175 /// Propagates within a single service, but not from client to server. A new
176 /// link is generated for the "root" request handling task
177 std::string GetLink() const;
178
179 std::string GetParentLink() const;
180
181 /// An ID of the request that does not change from service to service.
182 ///
183 /// Propagates both to sub-spans within a single service, and from client
184 /// to server
185 const std::string& GetTraceId() const;
186
187 /// Identifies a specific span. It does not propagate
188 const std::string& GetSpanId() const;
189 const std::string& GetParentId() const;
190
191 /// @returns true if this span would be logged with the current local and
192 /// global log levels to the default logger.
193 bool ShouldLogDefault() const noexcept;
194
195 /// Detach the Span from current engine::Task so it is not
196 /// returned by CurrentSpan() any more.
198
199 /// Attach the Span to current engine::Task so it is returned
200 /// by CurrentSpan().
202
203 std::chrono::system_clock::time_point GetStartSystemTime() const;
204
205 /// @cond
206 void AddTags(const logging::LogExtra&, utils::InternalTag);
207
208 void AddNonInheritableTags(const logging::LogExtra&, utils::InternalTag);
209
210 impl::TimeStorage& GetTimeStorage();
211
212 // For internal use only.
213 void LogTo(logging::impl::TagWriter writer) const&;
214 /// @endcond
215
216 private:
217 struct OptionalDeleter {
218 void operator()(Impl*) const noexcept;
219
220 static OptionalDeleter ShouldDelete() noexcept;
221
222 static OptionalDeleter DoNotDelete() noexcept;
223
224 private:
225 explicit OptionalDeleter(bool do_delete) : do_delete(do_delete) {}
226
227 const bool do_delete;
228 };
229
230 friend class SpanBuilder;
231 friend class TagScope;
232
233 explicit Span(std::unique_ptr<Impl, OptionalDeleter>&& pimpl);
234
235 std::string GetTag(std::string_view tag) const;
236
237 std::unique_ptr<Impl, OptionalDeleter> pimpl_;
238};
239
240namespace impl {
241
242struct LogSpanAsLastNonCoro final {
243 const Span& span;
244};
245
246logging::LogHelper& operator<<(logging::LogHelper& lh,
247 LogSpanAsLastNonCoro span);
248
249} // namespace impl
250
251} // namespace tracing
252
253USERVER_NAMESPACE_END