diff --git a/system/jlib/jthread.cpp b/system/jlib/jthread.cpp index 177e539e1e2..ef433a8f212 100644 --- a/system/jlib/jthread.cpp +++ b/system/jlib/jthread.cpp @@ -2684,12 +2684,14 @@ static TraceFlags defaultTraceFlags = TraceFlags::Standard; static thread_local LogMsgJobId defaultJobId = UnknownJob; static thread_local TraceFlags threadTraceFlags = TraceFlags::Standard; static thread_local const IContextLogger *default_thread_logctx = nullptr; +static thread_local ISpan * threadActiveSpan = nullptr; void saveThreadContext(SavedThreadContext & saveCtx) { saveCtx.jobId = defaultJobId; saveCtx.logctx = default_thread_logctx; saveCtx.traceFlags = threadTraceFlags; + saveCtx.activeSpan = threadActiveSpan; } void restoreThreadContext(const SavedThreadContext & saveCtx) @@ -2700,9 +2702,9 @@ void restoreThreadContext(const SavedThreadContext & saveCtx) defaultJobId = saveCtx.jobId; default_thread_logctx = saveCtx.logctx; threadTraceFlags = saveCtx.traceFlags; + threadActiveSpan = saveCtx.activeSpan; } - LogMsgJobId queryThreadedJobId() { return defaultJobId; @@ -2718,6 +2720,21 @@ const IContextLogger * queryThreadedContextLogger() return default_thread_logctx; } +ISpan * queryThreadedActiveSpan() +{ + ISpan * result = threadActiveSpan; + if (!result) + result = queryNullSpan(); + return result; +} + +ISpan * setThreadedActiveSpan(ISpan * span) +{ + ISpan * ret = threadActiveSpan; + threadActiveSpan = span; + return ret; +} + //--------------------------- bool doTrace(TraceFlags featureFlag, TraceFlags level) diff --git a/system/jlib/jthread.hpp b/system/jlib/jthread.hpp index 3390dacd27d..6172c87ad9b 100644 --- a/system/jlib/jthread.hpp +++ b/system/jlib/jthread.hpp @@ -36,16 +36,21 @@ // Functions used to reset thread-local context variables, when a threadpool starts typedef unsigned __int64 LogMsgJobId; interface IContextLogger; +interface ISpan; struct jlib_decl SavedThreadContext { const IContextLogger * logctx = nullptr; LogMsgJobId jobId = (LogMsgJobId)-1; TraceFlags traceFlags = queryDefaultTraceFlags(); + ISpan * activeSpan = nullptr; }; extern void restoreThreadContext(const SavedThreadContext & saveCtx); extern void saveThreadContext(SavedThreadContext & saveCtx); +extern jlib_decl ISpan * queryThreadedActiveSpan(); +extern jlib_decl ISpan * setThreadedActiveSpan(ISpan * span); + //-------------------------------------------------------------- interface jlib_decl IThread : public IInterface diff --git a/system/jlib/jtrace.cpp b/system/jlib/jtrace.cpp index 1d619407d4f..a1744ebad5c 100644 --- a/system/jlib/jtrace.cpp +++ b/system/jlib/jtrace.cpp @@ -1458,6 +1458,44 @@ ISpan * CTraceManager::createServerSpan(const char * name, const IProperties * h //--------------------------------------------------------------------------------------------------------------------- +OwnedSpanScope::OwnedSpanScope(ISpan * _ptr) : span(_ptr) +{ + if (_ptr) + prevSpan = setThreadedActiveSpan(_ptr); +} + +void OwnedSpanScope::setown(ISpan * _span) +{ + assertex(_span); + //Just in case the span is already set, ensure it is ended. + if (span) + span->endSpan(); + span.setown(_span); + prevSpan = setThreadedActiveSpan(_span); +} + +void OwnedSpanScope::set(ISpan * _span) +{ + setown(LINK(_span)); +} + +void OwnedSpanScope::clear() +{ + if (span) + { + setThreadedActiveSpan(prevSpan); + span->endSpan(); + span.clear(); + } +} + +OwnedSpanScope::~OwnedSpanScope() +{ + clear(); +} + +//--------------------------------------------------------------------------------------------------------------------- + MODULE_INIT(INIT_PRIORITY_STANDARD) { return true; @@ -1475,6 +1513,11 @@ ISpan * getNullSpan() return nullSpan.getLink(); } +ISpan * queryNullSpan() +{ + return nullSpan; +} + void initTraceManager(const char * componentName, const IPropertyTree * componentConfig, const IPropertyTree * globalConfig) { theTraceManager.query([=] () { return new CTraceManager(componentName, componentConfig, globalConfig); }); diff --git a/system/jlib/jtrace.hpp b/system/jlib/jtrace.hpp index 5ada18fc74b..fbdb6cc40ce 100644 --- a/system/jlib/jtrace.hpp +++ b/system/jlib/jtrace.hpp @@ -134,16 +134,24 @@ interface ISpan : extends IInterface virtual const char* queryLocalId() const = 0; }; -class OwnedSpanScope : public Owned +class jlib_decl OwnedSpanScope { public: - inline OwnedSpanScope() { } - inline OwnedSpanScope(ISpan * _ptr) : Owned(_ptr) { } - ~OwnedSpanScope() - { - if (get()) - get()->endSpan(); - } + OwnedSpanScope() = default; + OwnedSpanScope(ISpan * _ptr); + ~OwnedSpanScope(); + + inline ISpan * operator -> () const { return span; } + inline operator ISpan *() const { return span; } + + void clear(); + ISpan * query() const { return span; } + void set(ISpan * _span); + void setown(ISpan * _span); + +private: + Owned span; + ISpan * prevSpan = nullptr; }; extern jlib_decl IProperties * getClientHeaders(const ISpan * span); @@ -180,6 +188,7 @@ interface ITraceManager : extends IInterface virtual bool isTracingEnabled() const = 0; }; +extern jlib_decl ISpan * queryNullSpan(); extern jlib_decl ISpan * getNullSpan(); extern jlib_decl void initTraceManager(const char * componentName, const IPropertyTree * componentConfig, const IPropertyTree * globalConfig); extern jlib_decl ITraceManager & queryTraceManager();