From: Pieter Lexis Date: Thu, 2 Oct 2025 15:35:52 +0000 (+0200) Subject: feat(dnsdist): Wrap Spans in the Tracer in LockGuarded X-Git-Tag: rec-5.4.0-alpha1~187^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4d840faec4034a545ec7500f9bccd36e9cccdc0;p=thirdparty%2Fpdns.git feat(dnsdist): Wrap Spans in the Tracer in LockGuarded --- diff --git a/pdns/dnsdistdist/dnsdist-opentelemetry.cc b/pdns/dnsdistdist/dnsdist-opentelemetry.cc index 9cd71478f6..27b3c3df27 100644 --- a/pdns/dnsdistdist/dnsdist-opentelemetry.cc +++ b/pdns/dnsdistdist/dnsdist-opentelemetry.cc @@ -31,7 +31,7 @@ namespace pdns::trace::dnsdist { -TracesData Tracer::getTracesData() const +TracesData Tracer::getTracesData() { #ifdef DISABLE_PROTOBUF return 0; @@ -51,27 +51,33 @@ TracesData Tracer::getTracesData() const d_attributes.begin(), d_attributes.end()); - for (auto const& preActivationTrace : d_preActivationSpans) { - otTrace.resource_spans.at(0).scope_spans.at(0).spans.push_back( - { - .trace_id = d_traceid, - .span_id = preActivationTrace.span_id, - .parent_span_id = preActivationTrace.parent_span_id, - .name = preActivationTrace.name, - .start_time_unix_nano = preActivationTrace.start_time_unix_nano, - .end_time_unix_nano = preActivationTrace.end_time_unix_nano, - }); - } + { + auto lockedPre = d_preActivationSpans.read_only_lock(); - otTrace.resource_spans.at(0).scope_spans.at(0).spans.insert( - otTrace.resource_spans.at(0).scope_spans.at(0).spans.end(), - d_postActivationSpans.begin(), - d_postActivationSpans.end()); + for (auto const& preActivationTrace : *lockedPre) { + otTrace.resource_spans.at(0).scope_spans.at(0).spans.push_back( + { + .trace_id = d_traceid, + .span_id = preActivationTrace.span_id, + .parent_span_id = preActivationTrace.parent_span_id, + .name = preActivationTrace.name, + .start_time_unix_nano = preActivationTrace.start_time_unix_nano, + .end_time_unix_nano = preActivationTrace.end_time_unix_nano, + }); + } + } + { + auto lockedPost = d_postActivationSpans.read_only_lock(); + otTrace.resource_spans.at(0).scope_spans.at(0).spans.insert( + otTrace.resource_spans.at(0).scope_spans.at(0).spans.end(), + lockedPost->begin(), + lockedPost->end()); + } return otTrace; #endif } -std::string Tracer::getOTProtobuf() const +std::string Tracer::getOTProtobuf() { #ifdef DISABLE_PROTOBUF return 0; @@ -97,7 +103,7 @@ SpanID Tracer::addSpan([[maybe_unused]] const std::string& name, [[maybe_unused] #else auto spanID = pdns::trace::randomSpanID(); if (d_activated) { - d_postActivationSpans.push_back({ + d_postActivationSpans.lock()->push_back({ .trace_id = d_traceid, .span_id = spanID, .parent_span_id = parentSpanID, @@ -108,7 +114,7 @@ SpanID Tracer::addSpan([[maybe_unused]] const std::string& name, [[maybe_unused] } // We're not activated, so we are in pre-activation. - d_preActivationSpans.push_back({ + d_preActivationSpans.lock()->push_back({ .name = name, .span_id = spanID, .parent_span_id = parentSpanID, @@ -141,11 +147,12 @@ void Tracer::closeSpan([[maybe_unused]] const SpanID& spanID) { #ifndef DISABLE_PROTOBUF if (d_activated) { + auto lockedPost = d_postActivationSpans.lock(); auto spanIt = std::find_if( - d_postActivationSpans.rbegin(), - d_postActivationSpans.rend(), + lockedPost->rbegin(), + lockedPost->rend(), [spanID](const pdns::trace::Span& span) { return span.span_id == spanID; }); - if (spanIt != d_postActivationSpans.rend()) { + if (spanIt != lockedPost->rend()) { if (spanIt->end_time_unix_nano == 0) { spanIt->end_time_unix_nano = pdns::trace::timestamp(); } @@ -153,11 +160,12 @@ void Tracer::closeSpan([[maybe_unused]] const SpanID& spanID) } } + auto lockedPre = d_preActivationSpans.lock(); auto spanIt = std::find_if( - d_preActivationSpans.rbegin(), - d_preActivationSpans.rend(), + lockedPre->rbegin(), + lockedPre->rend(), [spanID](const preActivationSpanInfo& span) { return span.span_id == spanID; }); - if (spanIt != d_preActivationSpans.rend() && spanIt->end_time_unix_nano == 0) { + if (spanIt != lockedPre->rend() && spanIt->end_time_unix_nano == 0) { spanIt->end_time_unix_nano = pdns::trace::timestamp(); return; } @@ -169,10 +177,11 @@ void Tracer::setSpanAttribute([[maybe_unused]] const SpanID& spanid, [[maybe_unu { #ifndef DISABLE_PROTOBUF if (d_activated) { - if (auto iter = std::find_if(d_postActivationSpans.rbegin(), - d_postActivationSpans.rend(), + auto lockedPost = d_postActivationSpans.lock(); + if (auto iter = std::find_if(lockedPost->rbegin(), + lockedPost->rend(), [spanid](const pdns::trace::Span& span) { return span.span_id == spanid; }); - iter != d_postActivationSpans.rend()) { + iter != lockedPost->rend()) { iter->attributes.push_back({key, value}); return; } @@ -181,40 +190,42 @@ void Tracer::setSpanAttribute([[maybe_unused]] const SpanID& spanid, [[maybe_unu #endif } -SpanID Tracer::getLastSpanID() const +SpanID Tracer::getLastSpanID() { #ifdef DISABLE_PROTOBUF return 0; #else - if (d_activated && d_postActivationSpans.size() != 0) { - return d_postActivationSpans.back().span_id; + if (d_activated && d_postActivationSpans.read_only_lock()->size() != 0) { + return d_postActivationSpans.read_only_lock()->back().span_id; } - if (d_preActivationSpans.size() != 0) { - return d_preActivationSpans.back().span_id; + if (d_preActivationSpans.read_only_lock()->size() != 0) { + return d_preActivationSpans.read_only_lock()->back().span_id; } return SpanID{}; #endif } -SpanID Tracer::getLastSpanIDForName([[maybe_unused]] const std::string& name) const +SpanID Tracer::getLastSpanIDForName([[maybe_unused]] const std::string& name) { #ifdef DISABLE_PROTOBUF return 0; #else - if (d_activated && d_postActivationSpans.size() != 0) { - if (auto iter = std::find_if(d_postActivationSpans.rbegin(), - d_postActivationSpans.rend(), + if (d_activated && d_postActivationSpans.read_only_lock()->size() != 0) { + auto lockedPost = d_postActivationSpans.read_only_lock(); + if (auto iter = std::find_if(lockedPost->rbegin(), + lockedPost->rend(), [name](const pdns::trace::Span& span) { return span.name == name; }); - iter != d_postActivationSpans.rend()) { + iter != lockedPost->rend()) { return iter->span_id; } } - if (d_preActivationSpans.size() != 0) { - if (auto iter = std::find_if(d_preActivationSpans.rbegin(), - d_preActivationSpans.rend(), + if (d_preActivationSpans.read_only_lock()->size() != 0) { + auto lockedPre = d_preActivationSpans.read_only_lock(); + if (auto iter = std::find_if(lockedPre->rbegin(), + lockedPre->rend(), [name](const preActivationSpanInfo& span) { return span.name == name; }); - iter != d_preActivationSpans.rend()) { + iter != lockedPre->rend()) { return iter->span_id; } } diff --git a/pdns/dnsdistdist/dnsdist-opentelemetry.hh b/pdns/dnsdistdist/dnsdist-opentelemetry.hh index 3e68371678..046a40b50c 100644 --- a/pdns/dnsdistdist/dnsdist-opentelemetry.hh +++ b/pdns/dnsdistdist/dnsdist-opentelemetry.hh @@ -40,6 +40,8 @@ using AnyValue = std::variant; using TracesData = int; #endif +#include "lock.hh" + /* * This namespace contains all the bits and pieces required to do OpenTelemetry * traces in dnsdist. It is contained in this header and cc-file to ensure the rest @@ -140,7 +142,7 @@ public: * * @return The last generated SpanID, or empty SpanID when none exist */ - [[nodiscard]] SpanID getLastSpanID() const; + [[nodiscard]] SpanID getLastSpanID(); /** * @brief Get the SpanID for the most recently added span with a name @@ -148,7 +150,7 @@ public: * @param name The name of the Span * @return The SpanID, or empty SpanID when none are found */ - [[nodiscard]] SpanID getLastSpanIDForName(const std::string& name) const; + [[nodiscard]] SpanID getLastSpanIDForName(const std::string& name); /** * @brief Retrieve the TraceID for this Tracer @@ -160,12 +162,12 @@ public: * * @return pdns::trace::TracesData */ - [[nodiscard]] TracesData getTracesData() const; + [[nodiscard]] TracesData getTracesData(); /** * @brief Get the TracesData as protobuf encoded OpenTelemetry data */ - [[nodiscard]] std::string getOTProtobuf() const; + [[nodiscard]] std::string getOTProtobuf(); /** * @class Closer @@ -295,11 +297,11 @@ private: /** * @brief Stores all preActivationSpanInfos. It is used until d_activated is true */ - std::vector d_preActivationSpans; + LockGuarded> d_preActivationSpans; /** * @brief Stores all Spans. It is used when d_activated is true */ - std::vector d_postActivationSpans; + LockGuarded> d_postActivationSpans; /** * @brief All attributes related to this Trace */