tracer.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include <chrono>
  5. #include "opentelemetry/context/context.h"
  6. #include "opentelemetry/nostd/shared_ptr.h"
  7. #include "opentelemetry/nostd/string_view.h"
  8. #include "opentelemetry/trace/default_span.h"
  9. #include "opentelemetry/trace/scope.h"
  10. #include "opentelemetry/trace/span.h"
  11. #include "opentelemetry/trace/span_context_kv_iterable_view.h"
  12. #include "opentelemetry/trace/span_startoptions.h"
  13. #include "opentelemetry/version.h"
  14. OPENTELEMETRY_BEGIN_NAMESPACE
  15. namespace trace
  16. {
  17. /**
  18. * Handles span creation and in-process context propagation.
  19. *
  20. * This class provides methods for manipulating the context, creating spans, and controlling spans'
  21. * lifecycles.
  22. */
  23. class Tracer
  24. {
  25. public:
  26. virtual ~Tracer() = default;
  27. /**
  28. * Starts a span.
  29. *
  30. * Optionally sets attributes at Span creation from the given key/value pairs.
  31. *
  32. * Attributes will be processed in order, previous attributes with the same
  33. * key will be overwritten.
  34. */
  35. virtual nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
  36. const common::KeyValueIterable &attributes,
  37. const SpanContextKeyValueIterable &links,
  38. const StartSpanOptions &options = {}) noexcept = 0;
  39. nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
  40. const StartSpanOptions &options = {}) noexcept
  41. {
  42. return this->StartSpan(name, {}, {}, options);
  43. }
  44. template <class T,
  45. nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr>
  46. nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
  47. const T &attributes,
  48. const StartSpanOptions &options = {}) noexcept
  49. {
  50. return this->StartSpan(name, attributes, {}, options);
  51. }
  52. nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
  53. const common::KeyValueIterable &attributes,
  54. const StartSpanOptions &options = {}) noexcept
  55. {
  56. return this->StartSpan(name, attributes, NullSpanContext(), options);
  57. }
  58. template <class T,
  59. class U,
  60. nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr,
  61. nostd::enable_if_t<detail::is_span_context_kv_iterable<U>::value> * = nullptr>
  62. nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
  63. const T &attributes,
  64. const U &links,
  65. const StartSpanOptions &options = {}) noexcept
  66. {
  67. return this->StartSpan(name, common::KeyValueIterableView<T>(attributes),
  68. SpanContextKeyValueIterableView<U>(links), options);
  69. }
  70. nostd::shared_ptr<Span> StartSpan(
  71. nostd::string_view name,
  72. std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
  73. const StartSpanOptions &options = {}) noexcept
  74. {
  75. return this->StartSpan(name, attributes, {}, options);
  76. }
  77. template <class T,
  78. nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr>
  79. nostd::shared_ptr<Span> StartSpan(
  80. nostd::string_view name,
  81. const T &attributes,
  82. std::initializer_list<
  83. std::pair<SpanContext,
  84. std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>>>
  85. links,
  86. const StartSpanOptions &options = {}) noexcept
  87. {
  88. return this->StartSpan(
  89. name, attributes,
  90. nostd::span<const std::pair<SpanContext, std::initializer_list<std::pair<
  91. nostd::string_view, common::AttributeValue>>>>{
  92. links.begin(), links.end()},
  93. options);
  94. }
  95. template <class T,
  96. nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr>
  97. nostd::shared_ptr<Span> StartSpan(
  98. nostd::string_view name,
  99. std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
  100. const T &links,
  101. const StartSpanOptions &options = {}) noexcept
  102. {
  103. return this->StartSpan(name,
  104. nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
  105. attributes.begin(), attributes.end()},
  106. links, options);
  107. }
  108. nostd::shared_ptr<Span> StartSpan(
  109. nostd::string_view name,
  110. std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
  111. std::initializer_list<
  112. std::pair<SpanContext,
  113. std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>>>
  114. links,
  115. const StartSpanOptions &options = {}) noexcept
  116. {
  117. return this->StartSpan(
  118. name,
  119. nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{attributes.begin(),
  120. attributes.end()},
  121. nostd::span<const std::pair<SpanContext, std::initializer_list<std::pair<
  122. nostd::string_view, common::AttributeValue>>>>{
  123. links.begin(), links.end()},
  124. options);
  125. }
  126. /**
  127. * Set the active span. The span will remain active until the returned Scope
  128. * object is destroyed.
  129. * @param span the span that should be set as the new active span.
  130. * @return a Scope that controls how long the span will be active.
  131. */
  132. static Scope WithActiveSpan(nostd::shared_ptr<Span> &span) noexcept { return Scope{span}; }
  133. /**
  134. * Get the currently active span.
  135. * @return the currently active span, or an invalid default span if no span
  136. * is active.
  137. */
  138. static nostd::shared_ptr<Span> GetCurrentSpan() noexcept
  139. {
  140. context::ContextValue active_span = context::RuntimeContext::GetValue(kSpanKey);
  141. if (nostd::holds_alternative<nostd::shared_ptr<Span>>(active_span))
  142. {
  143. return nostd::get<nostd::shared_ptr<Span>>(active_span);
  144. }
  145. else
  146. {
  147. return nostd::shared_ptr<Span>(new DefaultSpan(SpanContext::GetInvalid()));
  148. }
  149. }
  150. #if OPENTELEMETRY_ABI_VERSION_NO >= 2
  151. /**
  152. * Reports if the tracer is enabled or not. A disabled tracer will not create spans.
  153. *
  154. * The instrumentation authors should call this method before creating a spans to
  155. * potentially avoid performing computationally expensive operations for disabled tracers.
  156. *
  157. * @since ABI_VERSION 2
  158. */
  159. bool Enabled() const noexcept { return OPENTELEMETRY_ATOMIC_READ_8(&this->enabled_) != 0; }
  160. #endif
  161. #if OPENTELEMETRY_ABI_VERSION_NO == 1
  162. /*
  163. * The following is removed from the API in ABI version 2.
  164. * It belongs to the SDK.
  165. */
  166. /**
  167. * Force any buffered spans to flush.
  168. * @param timeout to complete the flush
  169. */
  170. template <class Rep, class Period>
  171. void ForceFlush(std::chrono::duration<Rep, Period> timeout) noexcept
  172. {
  173. this->ForceFlushWithMicroseconds(static_cast<uint64_t>(
  174. std::chrono::duration_cast<std::chrono::microseconds>(timeout).count()));
  175. }
  176. virtual void ForceFlushWithMicroseconds(uint64_t timeout) noexcept = 0;
  177. /**
  178. * ForceFlush any buffered spans and stop reporting spans.
  179. * @param timeout to complete the flush
  180. */
  181. template <class Rep, class Period>
  182. void Close(std::chrono::duration<Rep, Period> timeout) noexcept
  183. {
  184. this->CloseWithMicroseconds(static_cast<uint64_t>(
  185. std::chrono::duration_cast<std::chrono::microseconds>(timeout).count()));
  186. }
  187. virtual void CloseWithMicroseconds(uint64_t timeout) noexcept = 0;
  188. #endif /* OPENTELEMETRY_ABI_VERSION_NO */
  189. protected:
  190. #if OPENTELEMETRY_ABI_VERSION_NO >= 2
  191. /**
  192. * Updates the enabled state of the tracer. Calling this method will affect the result of the
  193. * subsequent calls to {@code opentelemetry::v2::trace::Tracer::Enabled()}.
  194. *
  195. * This method should be used by SDK implementations to indicate the tracer's updated state
  196. * whenever a tracer transitions from enabled to disabled state and vice versa.
  197. *
  198. * @param enabled The new state of the tracer. False would indicate that the tracer is no longer
  199. * enabled and will not produce as
  200. *
  201. * @since ABI_VERSION 2
  202. */
  203. void UpdateEnabled(const bool enabled) noexcept
  204. {
  205. OPENTELEMETRY_ATOMIC_WRITE_8(&this->enabled_, enabled);
  206. }
  207. #endif
  208. private:
  209. #if OPENTELEMETRY_ABI_VERSION_NO >= 2
  210. // Variable to support implementation of Enabled method introduced in ABI V2.
  211. // Mutable allows enabled_ to be used as 'bool *' (instead of 'const bool *'), with the
  212. // OPENTELEMETRY_ATOMIC_READ_8 macro's internal casts when used from a const function.
  213. // std::atomic can not be used here because it is not ABI compatible for OpenTelemetry C++ API.
  214. mutable bool enabled_ = true;
  215. #endif
  216. };
  217. } // namespace trace
  218. OPENTELEMETRY_END_NAMESPACE