diff options
Diffstat (limited to 'src/zentelemetry')
| -rw-r--r-- | src/zentelemetry/include/zentelemetry/otlptrace.h | 41 | ||||
| -rw-r--r-- | src/zentelemetry/otlptrace.cpp | 60 |
2 files changed, 70 insertions, 31 deletions
diff --git a/src/zentelemetry/include/zentelemetry/otlptrace.h b/src/zentelemetry/include/zentelemetry/otlptrace.h index ebecff91a..f191241ed 100644 --- a/src/zentelemetry/include/zentelemetry/otlptrace.h +++ b/src/zentelemetry/include/zentelemetry/otlptrace.h @@ -3,6 +3,7 @@ #pragma once #include <zenbase/refcount.h> +#include <zencore/memcmp.h> #include <zencore/uid.h> #include <span> @@ -30,8 +31,6 @@ using AttributeList = std::span<std::pair<std::string, std::string>>; class Tracer; -Tracer& GetTracer(); - // OLTP Span ID struct SpanId @@ -42,8 +41,16 @@ struct SpanId explicit SpanId(const std::span<const uint8_t, 8> Bytes) noexcept { std::copy(Bytes.begin(), Bytes.end(), Id); } explicit SpanId(const Oid& InId) noexcept { memcpy(Id, reinterpret_cast<const uint8_t*>(InId.OidBits), sizeof Id); } - auto operator<=>(const SpanId& Rhs) const = default; - inline operator bool() const { return *this != SpanId(); } + std::strong_ordering operator<=>(const SpanId& Rhs) const noexcept + { + int cmp = MemCmpFixed<kSize>(Id, Rhs.Id); + if (cmp < 0) + return std::strong_ordering::less; + if (cmp > 0) + return std::strong_ordering::greater; + return std::strong_ordering::equal; + } + inline operator bool() const { return *reinterpret_cast<const uint64_t*>(Id) != 0; } static SpanId NewSpanId(); @@ -64,8 +71,19 @@ struct TraceId inline TraceId() noexcept : Id{0} {} explicit TraceId(const std::span<const uint8_t, kSize> Bytes) noexcept { std::copy(Bytes.begin(), Bytes.end(), Id); } - auto operator<=>(const TraceId& Rhs) const = default; - inline operator bool() const { return *this != TraceId(); } + std::strong_ordering operator<=>(const TraceId& Rhs) const noexcept + { + int cmp = MemCmpFixed<kSize>(Id, Rhs.Id); + if (cmp < 0) + return std::strong_ordering::less; + if (cmp > 0) + return std::strong_ordering::greater; + return std::strong_ordering::equal; + } + inline operator bool() const + { + return !(reinterpret_cast<const uint64_t*>(Id)[0] == 0 && reinterpret_cast<const uint64_t*>(Id)[1] == 0); + } static TraceId NewTraceId(); @@ -194,7 +212,6 @@ private: uint64_t m_StartTime = 0; uint64_t m_EndTime = 0; Kind m_Kind = Kind::kInternal; - bool m_Ended = false; Span(MemoryArena& Arena, std::string_view Name, Span* SpanChain); ~Span(); @@ -209,6 +226,13 @@ class ScopedSpan final { public: ScopedSpan(std::string_view Name); + ScopedSpan(std::string_view Name, std::invocable<Span&> auto&& InitializerFunction) : ScopedSpan(Name) + { + if (m_Span) + { + InitializerFunction(*m_Span); + } + } ScopedSpan() = delete; ~ScopedSpan(); @@ -217,7 +241,8 @@ public: ScopedSpan(ScopedSpan&& Rhs) = default; ScopedSpan(const ScopedSpan& Rhs) = default; - Span* operator->() const { return m_Span.Get(); } + operator bool() const { return !!m_Span; } + void WithSpan(auto Func) const { Func(*m_Span); } private: ScopedSpan(Span* InSpan, Tracer* InTracer); diff --git a/src/zentelemetry/otlptrace.cpp b/src/zentelemetry/otlptrace.cpp index b634eacf6..f987afcfe 100644 --- a/src/zentelemetry/otlptrace.cpp +++ b/src/zentelemetry/otlptrace.cpp @@ -7,6 +7,7 @@ # include <zencore/endian.h> # include <zencore/memory/memoryarena.h> +# include <zencore/scopeguard.h> # include <zencore/session.h> # include <zencore/testing.h> # include <zencore/uid.h> @@ -106,16 +107,15 @@ Span::~Span() void Span::End() { - if (m_Ended) + if (m_EndTime) { return; } - ZEN_ASSERT(t_TraceState.ActiveSpan == this); + ZEN_ASSERT_SLOW(t_TraceState.ActiveSpan == this); - m_Ended = true; - t_TraceState.ActiveSpan = m_ParentSpan; m_EndTime = NowInNanoseconds(); + t_TraceState.ActiveSpan = m_ParentSpan; } Span* @@ -127,10 +127,10 @@ Span::GetCurrentSpan() SpanId Span::GetCurrentSpanId(TraceId& OutTraceId) { - if (t_TraceState.ActiveSpan) + if (const auto& State = t_TraceState; State.ActiveSpan) { - OutTraceId = t_TraceState.CurrentTraceId; - return t_TraceState.ActiveSpan->m_SpanId; + OutTraceId = State.CurrentTraceId; + return State.ActiveSpan->m_SpanId; } else { @@ -271,6 +271,14 @@ IsRecording() ////////////////////////////////////////////////////////////////////////// +std::atomic<bool> g_OtlpTraceEnabled{false}; + +inline bool +IsOtlpTraceEnabled() +{ + return g_OtlpTraceEnabled.load(); +} + thread_local Tracer* t_Tracer; struct Tracer::Impl @@ -325,22 +333,19 @@ Tracer::GetTracer() ScopedSpan Tracer::CreateSpan(std::string_view Name) { - Tracer* TracerPtr = GetTracer(); - - Impl* const ImplPtr = TracerPtr->m_Impl; - - Span* NewSpan = new (ImplPtr->m_Arena) Span(ImplPtr->m_Arena, Name, ImplPtr->m_SpanChain); - - ImplPtr->m_SpanChain = NewSpan; - ImplPtr->m_SpanCount.fetch_add(1); - - return ScopedSpan(NewSpan, TracerPtr); + return ScopedSpan(Name); } ////////////////////////////////////////////////////////////////////////// ScopedSpan::ScopedSpan(std::string_view Name) { + if (!IsOtlpTraceEnabled()) + { + // m_Tracer and m_Span remain null + return; + } + Tracer* TracerPtr = Tracer::GetTracer(); Tracer::Impl* const ImplPtr = TracerPtr->m_Impl; @@ -379,15 +384,24 @@ otlptrace_forcelink() TEST_CASE("otlp.trace") { + // Enable OTLP tracing for the duration of this test + auto _ = MakeGuard([PreviousState = zen::otel::g_OtlpTraceEnabled.load()]() { zen::otel::g_OtlpTraceEnabled.store(PreviousState); }); + zen::otel::g_OtlpTraceEnabled.store(true); + { - ScopedSpan Span = Tracer::CreateSpan("span0"); - Span->AddEvent("TestEvent1"sv); - Span->AddEvent("TestEvent2"sv); + ScopedSpan Span0("span0", [](Span& S) { + S.AddAttribute("attr1"sv, "value1"sv); + S.AddAttribute("attr2"sv, 42ULL); + S.AddEvent("TestEvent1"sv); + S.AddEvent("TestEvent2"sv); + }); { - ScopedSpan Span2 = Tracer::CreateSpan("span1"); - Span2->AddEvent("TestEvent3"sv); - Span2->AddEvent("TestEvent4"sv); + ScopedSpan Span1 = Tracer::CreateSpan("span1"); + Span1.WithSpan([](Span& S) { + S.AddEvent("TestEvent3"sv); + S.AddEvent("TestEvent4"sv); + }); } } } |