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 */
42 explicit Span(std::string name,
43 ReferenceType reference_type = ReferenceType::kChild,
44 logging::Level log_level = logging::Level::kInfo,
45 utils::impl::SourceLocation source_location =
46 utils::impl::SourceLocation::Current());
47
48 /// @cond
49 // For internal use only
50 explicit Span(Span::Impl& impl);
51 /// @endcond
52
53 Span(Span&& other) noexcept;
54
55 ~Span();
56
57 Span& operator=(const Span&) = delete;
58
59 Span& operator=(Span&&) = delete;
60
61 /// @brief Returns the Span of the current task.
62 ///
63 /// Should not be called in non-coroutine
64 /// context. Should not be called from a task with no alive Span.
65 ///
66 /// Rule of thumb: it is safe to call it from a task created by
67 /// utils::Async/utils::CriticalAsync/utils::PeriodicTask. If current task was
68 /// created with an explicit engine::impl::*Async(), you have to create a Span
69 /// beforehand.
70 static Span& CurrentSpan();
71
72 /// @brief Returns nullptr if called in non-coroutine context or from a task
73 /// with no alive Span; otherwise returns the Span of the current task.
74 static Span* CurrentSpanUnchecked();
75
76 /// @return A new Span attached to current Span (if any).
77 static Span MakeSpan(std::string name, std::string_view trace_id,
78 std::string_view parent_span_id);
79
80 /// @return A new Span attached to current Span (if any), sets `link`.
81 static Span MakeSpan(std::string name, std::string_view trace_id,
82 std::string_view parent_span_id, std::string link);
83
84 /// Create a child which can be used independently from the parent.
85 ///
86 /// The child shares no state with its parent. If you need to run code in
87 /// parallel, create a child span and use the child in a separate task.
88 Span CreateChild(std::string name) const;
89
90 Span CreateFollower(std::string name) const;
91
92 /// @brief Creates a tracing::ScopeTime attached to the span.
94
95 /// @brief Creates a tracing::ScopeTime attached to the Span and starts
96 /// measuring execution time.
97 ScopeTime CreateScopeTime(std::string name);
98
99 /// Returns total time elapsed for a certain scope of this span.
100 /// If there is no record for the scope, returns 0.
101 ScopeTime::Duration GetTotalDuration(const std::string& scope_name) const;
102
103 /// Returns total time elapsed for a certain scope of this span.
104 /// If there is no record for the scope, returns 0.
105 ///
106 /// Prefer using Span::GetTotalDuration()
108 const std::string& scope_name) const;
109
110 /// Add a tag that is used on each logging in this Span and all
111 /// future children.
112 void AddTag(std::string key, logging::LogExtra::Value value);
113
114 /// Add a tag that is used on each logging in this Span and all
115 /// future children. It will not be possible to change its value.
116 void AddTagFrozen(std::string key, logging::LogExtra::Value value);
117
118 /// Add a tag that is local to the Span (IOW, it is not propagated to
119 /// future children) and logged only once in the destructor of the Span.
120 void AddNonInheritableTag(std::string key, logging::LogExtra::Value value);
121
122 /// @brief Sets level for tags logging
123 void SetLogLevel(logging::Level log_level);
124
125 /// @brief Returns level for tags logging
127
128 /// @brief Sets the local log level that disables logging of this span if
129 /// the local log level set and greater than the main log level of the Span.
130 void SetLocalLogLevel(std::optional<logging::Level> log_level);
131
132 /// @brief Returns the local log level that disables logging of this span if
133 /// it is set and greater than the main log level of the Span.
134 std::optional<logging::Level> GetLocalLogLevel() const;
135
136 /// Set link. Can be called only once.
137 void SetLink(std::string link);
138
139 /// Set parent_link. Can be called only once.
140 void SetParentLink(std::string parent_link);
141
142 std::string GetLink() const;
143
144 std::string GetParentLink() const;
145
146 const std::string& GetTraceId() const;
147 const std::string& GetSpanId() const;
148 const std::string& GetParentId() const;
149
150 /// @returns true if this span would be logged with the current local and
151 /// global log levels to the default logger.
152 bool ShouldLogDefault() const noexcept;
153
154 /// Detach the Span from current engine::Task so it is not
155 /// returned by CurrentSpan() any more.
157
158 /// Attach the Span to current engine::Task so it is returned
159 /// by CurrentSpan().
161
162 std::chrono::system_clock::time_point GetStartSystemTime() const;
163
164 /// @cond
165 void AddTags(const logging::LogExtra&, utils::InternalTag);
166
167 void AddNonInheritableTags(const logging::LogExtra&, utils::InternalTag);
168
169 impl::TimeStorage& GetTimeStorage();
170
171 // For internal use only.
172 void LogTo(logging::impl::TagWriter writer) const&;
173 /// @endcond
174
175 private:
176 struct OptionalDeleter {
177 void operator()(Impl*) const noexcept;
178
179 static OptionalDeleter ShouldDelete() noexcept;
180
181 static OptionalDeleter DoNotDelete() noexcept;
182
183 private:
184 explicit OptionalDeleter(bool do_delete) : do_delete(do_delete) {}
185
186 const bool do_delete;
187 };
188
189 friend class SpanBuilder;
190
191 explicit Span(std::unique_ptr<Impl, OptionalDeleter>&& pimpl);
192
193 std::string GetTag(std::string_view tag) const;
194
195 std::unique_ptr<Impl, OptionalDeleter> pimpl_;
196};
197
198namespace impl {
199
200struct LogSpanAsLastNonCoro final {
201 const Span& span;
202};
203
204logging::LogHelper& operator<<(logging::LogHelper& lh,
205 LogSpanAsLastNonCoro span);
206
207} // namespace impl
208
209} // namespace tracing
210
211USERVER_NAMESPACE_END