Sfoglia il codice sorgente

HPCC-21258 Track CallerId through HPCC components

Also support "Global-Id", "Caller-Id" versions of the id tracking
HTTP headers.  Also remember the form of HTTP header used and use
the same in SOAPCALL and HTTPCALL.

Signed-off-by: Anthony Fishbeck <anthony.fishbeck@lexisnexis.com>
Anthony Fishbeck 6 anni fa
parent
commit
5288a7d3ca

+ 3 - 0
ecl/eclagent/eclagent.cpp

@@ -2084,7 +2084,10 @@ void EclAgent::runProcess(IEclProcess *process)
             SCMStringBuffer txId;
             queryWorkUnit()->getDebugValue("CallerId", txId);
             if (txId.length())
+            {
+                updateDummyContextLogger().setCallerId(txId.str());
                 msg.append(", CallerId: ").append(txId.str());
+            }
             txId.set(updateDummyContextLogger().queryLocalId());
             if (txId.length())
                 msg.append(", LocalId: ").append(txId.str());

+ 8 - 0
ecllibrary/std/system/Log.ecl

@@ -58,6 +58,14 @@ EXPORT addWorkunitError(varstring text, unsigned code=0) := lib_logging.Logging.
 EXPORT getGlobalId() := lib_logging.Logging.getGlobalId();
 
 /*
+ * Gets the Caller Id associated with the current query or workunit.
+ *
+ * Returns the Caller Id
+ */
+
+EXPORT getCallerId() := lib_logging.Logging.getCallerId();
+
+/*
  * Gets the Local Id associated with the current query or workunit.
  *
  * Returns the Local Id

+ 13 - 9
esp/services/ws_ecl/ws_ecl_service.cpp

@@ -234,10 +234,10 @@ bool CWsEclService::init(const char * name, const char * type, IPropertyTree * c
         workunitTimeout = WAIT_FOREVER;
 
     const char *headerName = serviceTree->queryProp("HttpGlobalIdHeader");
-    if (headerName && *headerName && !streq(headerName, "HPCC-Global-Id")) //default will be checked anyway
+    if (headerName && *headerName && !streq(headerName, "Global-Id") && !streq(headerName, "HPCC-Global-Id")) //defaults will be checked anyway
         globalIdHttpHeader.set(headerName);
     headerName = serviceTree->queryProp("HttpCallerIdHeader");
-    if (headerName && *headerName && !streq(headerName, "HPCC-Caller-Id")) //default will be checked anyway
+    if (headerName && *headerName && !streq(headerName, "Caller-Id") && !streq(headerName, "HPCC-Caller-Id")) //defaults will be checked anyway
         callerIdHttpHeader.set(headerName);
 
     Owned<IPropertyTreeIterator> cfgTargets = serviceTree->getElements("Targets/Target");
@@ -1891,16 +1891,19 @@ int CWsEclBinding::submitWsEclWorkunit(IEspContext & context, WsEclWuInfo &wsinf
     if (httpreq)
     {
         StringBuffer globalId, callerId;
-        wsecl->getHttpGlobalIdHeader(httpreq, globalId);
-        wsecl->getHttpCallerIdHeader(httpreq, callerId);
+        StringAttr globalIdHeader, callerIdHeader;
+        wsecl->getHttpGlobalIdHeader(httpreq, globalId, globalIdHeader);
+        wsecl->getHttpCallerIdHeader(httpreq, callerId, callerIdHeader);
         if (globalId.length())
         {
             workunit->setDebugValue("GlobalId", globalId.str(), true);
+            workunit->setDebugValue("GlobalIdHeader", globalIdHeader.str(), true);  //use same header received
 
             SocketEndpoint ep;
             StringBuffer localId;
             appendLocalId(localId, httpreq->getSocket()->getEndpoint(ep), 0);
             workunit->setDebugValue("CallerId", localId.str(), true); //our localId becomes caller id for the next hop
+            workunit->setDebugValue("CallerIdHeader", callerIdHeader.str(), true); //use same header received
             DBGLOG("GlobalId: %s, CallerId: %s, LocalId: %s, Wuid: %s", globalId.str(), callerId.str(), localId.str(), wuid.str());
         }
     }
@@ -1986,23 +1989,24 @@ void CWsEclBinding::sendRoxieRequest(const char *target, StringBuffer &req, Stri
         if (httpreq)
         {
             StringBuffer globalId, callerId;
-            wsecl->getHttpGlobalIdHeader(httpreq, globalId);
-            wsecl->getHttpCallerIdHeader(httpreq, callerId);
+            StringAttr globalIdHeader, callerIdHeader;
+            wsecl->getHttpGlobalIdHeader(httpreq, globalId, globalIdHeader);
+            wsecl->getHttpCallerIdHeader(httpreq, callerId, callerIdHeader);
 
             if (globalId.length())
             {
                 headers.setown(createProperties());
-                headers->setProp(wsecl->queryGlobalIdHeaderName(), globalId);
+                headers->setProp(globalIdHeader, globalId);
 
                 SocketEndpoint ep;
                 StringBuffer localId;
                 appendLocalId(localId, httpreq->getSocket()->getEndpoint(ep), 0);
                 if (localId.length())
-                    headers->setProp(wsecl->queryCallerIdHeaderName(), localId);
+                    headers->setProp(callerIdHeader, localId);
                 DBGLOG("GlobalId: %s, CallerId: %s, LocalId: %s", globalId.str(), callerId.str(), localId.str());
             }
         }
-        if (0 > httpclient->sendRequest("POST", contentType, req, resp, status))
+        if (0 > httpclient->sendRequest(headers, "POST", contentType, req, resp, status))
             throw MakeStringException(-1, "Roxie cluster communication error: %s", target);
     }
     catch (IException *e)

+ 26 - 10
esp/services/ws_ecl/ws_ecl_service.hpp

@@ -122,20 +122,36 @@ public:
     virtual bool init(const char * name, const char * type, IPropertyTree * cfg, const char * process);
     virtual void setContainer(IEspContainer * container){}
 
-    StringBuffer &getHttpGlobalIdHeader(CHttpRequest *request, StringBuffer &value)
+    inline bool getHttpIdHeader(CHttpRequest *request, const char *header, StringBuffer &value, StringAttr &nameused)
     {
-        if (!globalIdHttpHeader.isEmpty())
-            request->getHeader(globalIdHttpHeader, value);
-        if (value.isEmpty())
-            request->getHeader("HPCC-Global-Id", value); //always support receiving HPCC default
+        if (!header || !*header)
+            return false;
+
+        request->getHeader(header, value.clear());
+        if (value.length())
+        {
+            nameused.set(header);
+            return true;
+        }
+        return false;
+    }
+
+    StringBuffer &getHttpGlobalIdHeader(CHttpRequest *request, StringBuffer &value, StringAttr &nameused)
+    {
+        if (!getHttpIdHeader(request, globalIdHttpHeader, value, nameused))
+        {
+            if (!getHttpIdHeader(request, "Global-Id", value, nameused))
+                getHttpIdHeader(request, "HPCC-Global-Id", value, nameused);
+        }
         return value;
     }
-    StringBuffer &getHttpCallerIdHeader(CHttpRequest *request, StringBuffer &value)
+    StringBuffer &getHttpCallerIdHeader(CHttpRequest *request, StringBuffer &value, StringAttr &nameused)
     {
-        if (!callerIdHttpHeader.isEmpty())
-            request->getHeader(callerIdHttpHeader, value);
-        if (value.isEmpty())
-            request->getHeader("HPCC-Caller-Id", value); //always support receiving HPCC default
+        if (!getHttpIdHeader(request, callerIdHttpHeader, value, nameused))
+        {
+            if (!getHttpIdHeader(request, "Caller-Id", value, nameused))
+                getHttpIdHeader(request, "HPCC-Caller-Id", value, nameused);
+        }
         return value;
     }
     const char *queryGlobalIdHeaderName()

+ 7 - 0
plugins/logging/logging.cpp

@@ -36,6 +36,7 @@ static const char * EclDefinition =
 "  addWorkunitError(const varstring txt, unsigned code=0, unsigned severity=2, const varstring source='user') : ctxmethod,action,entrypoint='addWuException'; \n"
 "  varstring getGlobalId() : c,context,entrypoint='logGetGlobalId'; \n"
 "  varstring getLocalId() : c,context,entrypoint='logGetLocalId'; \n"
+"  varstring getCallerId() : c,context,entrypoint='logGetCallerId'; \n"
 "END;";
 
 LOGGING_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb) 
@@ -74,3 +75,9 @@ LOGGING_API char *  LOGGING_CALL logGetLocalId(ICodeContext *ctx)
     StringBuffer ret = ctx->queryContextLogger().queryLocalId();
     return ret.detach();
 }
+
+LOGGING_API char *  LOGGING_CALL logGetCallerId(ICodeContext *ctx)
+{
+    StringBuffer ret = ctx->queryContextLogger().queryCallerId();
+    return ret.detach();
+}

+ 1 - 0
plugins/logging/logging.hpp

@@ -37,6 +37,7 @@ extern "C" {
 LOGGING_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb);
 LOGGING_API void LOGGING_CALL logDbgLog(unsigned srcLen, const char * src);
 LOGGING_API char * LOGGING_CALL logGetGlobalId(ICodeContext *ctx);
+LOGGING_API char * LOGGING_CALL logGetCallerId(ICodeContext *ctx);
 LOGGING_API char * LOGGING_CALL logGetLocalId(ICodeContext *ctx);
 }
 

+ 10 - 1
roxie/ccd/ccd.hpp

@@ -480,6 +480,7 @@ private:
     StringAttr globalIdHeader = "HPCC-Global-Id";
     StringAttr callerIdHeader = "HPCC-Caller-Id";
     StringAttr globalId;
+    StringAttr callerId;
     StringBuffer localId;
     ContextLogger(const ContextLogger &);  // Disable copy constructor
 public:
@@ -613,15 +614,23 @@ public:
     {
         stats.reset();
     }
-    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid)
+    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid) override
     {
         globalId.set(id);
         appendLocalId(localId.clear(), ep, pid);
     }
+    virtual void setCallerId(const char *id) override
+    {
+        callerId.set(id);
+    }
     virtual const char *queryGlobalId() const
     {
         return globalId.get();
     }
+    virtual const char *queryCallerId() const override
+    {
+        return callerId.get();
+    }
     virtual const char *queryLocalId() const
     {
         return localId.str();

+ 9 - 1
roxie/ccd/ccdcontext.cpp

@@ -1327,14 +1327,22 @@ public:
     {
         return logctx.queryTraceLevel();
     }
-    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid)
+    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid) override
     {
         const_cast<IRoxieContextLogger&>(logctx).setGlobalId(id, ep, pid);
     }
+    virtual void setCallerId(const char *id) override
+    {
+        const_cast<IRoxieContextLogger&>(logctx).setCallerId(id);
+    }
     virtual const char *queryGlobalId() const
     {
         return logctx.queryGlobalId();
     }
+    virtual const char *queryCallerId() const override
+    {
+        return logctx.queryCallerId();
+    }
     virtual const char *queryLocalId() const
     {
         return logctx.queryLocalId();

+ 27 - 3
roxie/ccd/ccdlistener.cpp

@@ -1173,7 +1173,11 @@ public:
             SCMStringBuffer globalId;
             SocketEndpoint ep;
             ep.setLocalHost(0);
+            SCMStringBuffer callerId;
             logctx->setGlobalId(wu->getDebugValue("GlobalId", globalId).str(), ep, GetCurrentProcessId());
+            wu->getDebugValue("CallerId", callerId);
+            if (callerId.length())
+                logctx->setCallerId(callerId.str());
         }
         Owned<IQueryFactory> queryFactory;
         try
@@ -1414,7 +1418,7 @@ public:
         return *cascade;
     }
 
-    virtual void setTransactionId(const char *id, bool global)
+    virtual void setTransactionId(const char *id, const char *caller, bool global) override
     {
         if (!id || !*id)
             return;
@@ -1422,10 +1426,30 @@ public:
         ensureContextLogger();
         if (!isEmptyString(logctx->queryGlobalId())) //globalId wins
             return;
+        StringBuffer s;
+        ep.getIpText(s).appendf(":%u{%s}", ep.port, uid.str()); //keep no matter what for existing log parsers
         if (global)
+        {
+            s.append('[');
             logctx->setGlobalId(id, ep, 0);
-        StringBuffer s;
-        logctx->set(ep.getIpText(s).appendf(":%u{%s}", ep.port, uid.str()).str());
+            if (caller && *caller)
+            {
+                setCallerId(caller);
+                logctx->setCallerId(caller);
+            }
+            if (callerId.length())
+                s.appendf("caller:%s", callerId.str());
+
+            const char *local = logctx->queryLocalId(); //generated in setGlobalId above
+            if (local && *local)
+            {
+                if (callerId.length())
+                    s.append(',');
+                s.appendf("local:%s", local);
+            }
+            s.append("]");
+        }
+        logctx->set(s.str());
     }
     virtual void setCallerId(const char *id)
     {

+ 41 - 11
roxie/ccd/ccdprotocol.cpp

@@ -1697,6 +1697,37 @@ private:
             }
         }
     }
+    const char *queryRequestIdHeader(HttpHelper &httpHelper, const char *header, StringAttr &headerused)
+    {
+        const char *id = httpHelper.queryRequestHeader(header);
+        if (id && *id)
+            headerused.set(header);
+        return id;
+    }
+
+    const char *queryRequestGlobalIdHeader(HttpHelper &httpHelper, IContextLogger &logctx, StringAttr &headerused)
+    {
+        const char *id = queryRequestIdHeader(httpHelper, logctx.queryGlobalIdHttpHeader(), headerused);
+        if (!id || !*id)
+        {
+            id = queryRequestIdHeader(httpHelper, "Global-Id", headerused);
+            if (!id || !*id)
+                id = queryRequestIdHeader(httpHelper, "HPCC-Global-Id", headerused);
+        }
+        return id;
+    }
+
+    const char *queryRequestCallerIdHeader(HttpHelper &httpHelper, IContextLogger &logctx, StringAttr &headerused)
+    {
+        const char *id = queryRequestIdHeader(httpHelper, logctx.queryCallerIdHttpHeader(), headerused);
+        if (!id || !*id)
+        {
+            id = queryRequestIdHeader(httpHelper, "Caller-Id", headerused);
+            if (!id || !*id)
+                id = queryRequestIdHeader(httpHelper, "HPCC-Caller-Id", headerused);
+        }
+        return id;
+    }
 
     void doMain(const char *runQuery)
     {
@@ -1769,16 +1800,15 @@ readAnother:
             {
                 mlResponseFmt = httpHelper.queryResponseMlFormat();
                 mlRequestFmt = httpHelper.queryRequestMlFormat();
-                const char *value = httpHelper.queryRequestHeader(logctx.queryGlobalIdHttpHeader());
-                if (!value || !*value)
-                    value = httpHelper.queryRequestHeader("HPCC-Global-Id"); //always support receiving in the HPCC form
-                if (value && *value)
-                    msgctx->setTransactionId(value, true);  //logged and forwarded through SOAPCALL/HTTPCALL
-                value = httpHelper.queryRequestHeader(logctx.queryCallerIdHttpHeader());
-                if (!value || !*value)
-                    value = httpHelper.queryRequestHeader("HPCC-Caller-Id");
-                if (value && *value)
-                    msgctx->setCallerId(value);  //only logged
+
+                StringAttr globalIdHeader, callerIdHeader;
+                const char *globalId = queryRequestGlobalIdHeader(httpHelper, logctx, globalIdHeader);
+                const char *callerId = queryRequestCallerIdHeader(httpHelper, logctx, callerIdHeader);
+                logctx.setHttpIdHeaders(globalIdHeader, callerIdHeader);
+                if (globalId && *globalId)
+                    msgctx->setTransactionId(globalId, callerId, true);  //logged and forwarded through SOAPCALL/HTTPCALL
+                else if (callerId && *callerId)
+                    msgctx->setCallerId(callerId); //may not matter, but maintain old behavior
             }
         }
 
@@ -1881,7 +1911,7 @@ readAnother:
                 uid = NULL;
                 sanitizeQuery(queryPT, queryName, sanitizedText, httpHelper, uid, isBlind, isDebug);
                 if (uid)
-                    msgctx->setTransactionId(uid, false);
+                    msgctx->setTransactionId(uid, nullptr, false);
                 else
                     uid = "-";
 

+ 19 - 2
roxie/ccd/ccdserver.cpp

@@ -253,14 +253,22 @@ public:
     {
         return ctx->isBlind();
     }
-    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid)
+    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid) override
     {
         ctx->setGlobalId(id, ep, pid);
     }
+    virtual void setCallerId(const char *id) override
+    {
+        ctx->setCallerId(id);
+    }
     virtual const char *queryGlobalId() const
     {
         return ctx->queryGlobalId();
     }
+    virtual const char *queryCallerId() const override
+    {
+        return ctx->queryCallerId();
+    }
     virtual const char *queryLocalId() const
     {
         return ctx->queryLocalId();
@@ -1208,15 +1216,24 @@ public:
             return traceLevel;
     }
 
-    virtual void setGlobalId(const char *id, SocketEndpoint&ep, unsigned pid)
+    virtual void setGlobalId(const char *id, SocketEndpoint&ep, unsigned pid) override
     {
         if (ctx)
             ctx->setGlobalId(id, ep, pid);
     }
+    virtual void setCallerId(const char *id) override
+    {
+        if (ctx)
+            ctx->setCallerId(id);
+    }
     virtual const char *queryGlobalId() const
     {
         return ctx ? ctx->queryGlobalId() : nullptr;
     }
+    virtual const char *queryCallerId() const override
+    {
+        return ctx ? ctx->queryCallerId() : nullptr;
+    }
     virtual const char *queryLocalId() const
     {
         return ctx ? ctx->queryLocalId() : nullptr;

+ 1 - 1
roxie/ccd/hpccprotocol.hpp

@@ -41,7 +41,7 @@ interface IHpccProtocolMsgContext : extends IInterface
     virtual bool getIntercept() = 0;
     virtual void outputLogXML(IXmlStreamFlusher &out) = 0;
     virtual void writeLogXML(IXmlWriter &writer) = 0;
-    virtual void setTransactionId(const char *id, bool global) = 0;
+    virtual void setTransactionId(const char *id, const char *caller, bool global) = 0;
     virtual void setCallerId(const char *id) = 0;
 };
 

+ 10 - 1
system/jlib/jlog.cpp

@@ -2537,6 +2537,7 @@ class DummyLogCtx : implements IContextLogger
 {
 private:
     StringAttr globalId;
+    StringAttr callerId;
     StringBuffer localId;
     StringAttr globalIdHeader;
     StringAttr callerIdHeader;
@@ -2576,15 +2577,23 @@ public:
     {
         return 0;
     }
-    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid)
+    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid) override
     {
         globalId.set(id);
         appendLocalId(localId.clear(), ep, pid);
     }
+    virtual void setCallerId(const char *id) override
+    {
+        callerId.set(id);
+    }
     virtual const char *queryGlobalId() const
     {
         return globalId.get();
     }
+    virtual const char *queryCallerId() const override
+    {
+        return callerId.str();
+    }
     virtual const char *queryLocalId() const
     {
         return localId.str();

+ 2 - 0
system/jlib/jlog.hpp

@@ -998,6 +998,8 @@ interface jlib_decl IContextLogger : extends IInterface
     virtual const char *queryLocalId() const = 0;
     virtual const char *queryGlobalIdHttpHeader() const = 0;
     virtual const char *queryCallerIdHttpHeader() const = 0;
+    virtual void setCallerId(const char *id) = 0;
+    virtual const char *queryCallerId() const = 0;
 };
 
 extern jlib_decl StringBuffer &appendLocalId(StringBuffer &s, const SocketEndpoint &ep, unsigned pid);

+ 26 - 0
testing/regress/ecl/globalid.ecl

@@ -0,0 +1,26 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+import lib_logging;
+import lib_workunitservices;
+
+#option('CallerId', 'PkAntaCLkY4MknCnXA');
+#option('GlobalId', 'xPSDvT9akc1fGSTZWJKb');
+
+OUTPUT(logging.getGlobalId(), NAMED('GlobalId'));
+OUTPUT(logging.getCallerId(), NAMED('CallerId'));
+

+ 6 - 0
testing/regress/ecl/key/globalid.xml

@@ -0,0 +1,6 @@
+<Dataset name='GlobalId'>
+ <Row><GlobalId>xPSDvT9akc1fGSTZWJKb</GlobalId></Row>
+</Dataset>
+<Dataset name='CallerId'>
+ <Row><CallerId>PkAntaCLkY4MknCnXA</CallerId></Row>
+</Dataset>

+ 1 - 1
testing/regress/ecl/soapcall.ecl

@@ -73,7 +73,7 @@ END;
 // Test some failure cases
 
 output(SORT(SOAPCALL(d, blacklistedTargetURL,'soapbase', { unkname }, DATASET(ServiceOutRecord), onFail(doError(LEFT)),RETRY(0), log('SOAP: ' + unkname),TIMEOUT(1)), record));
-output(SORT(SOAPCALL(targetURL,'soapbase', { string unkname := 'FAIL' }, dataset(ServiceOutRecord),onFail(doError2),RETRY(0), LOG(MIN), HTTPHEADER('HPCC-Global-Id','12345678900'), HTTPHEADER('HPCC-Caller-Id','4444')),record));
+output(SORT(SOAPCALL(targetURL,'soapbase', { string unkname := 'FAIL' }, dataset(ServiceOutRecord),onFail(doError2),RETRY(0), LOG(MIN), HTTPHEADER('Global-Id','12345678900'), HTTPHEADER('Caller-Id','4444')),record));
 output(SORT(SOAPCALL(d, targetURL,'soapbaseNOSUCHQUERY', { unkname }, DATASET(ServiceOutRecord), onFail(doError3(LEFT)),MERGE(25),PARALLEL(1),RETRY(0), LOG(MIN)), record));
 
 childRecord := record

+ 10 - 1
thorlcr/graph/thgraph.cpp

@@ -2524,6 +2524,7 @@ class CThorContextLogger : implements IContextLogger, public CSimpleInterface
     StringAttr globalIdHeader;
     StringAttr callerIdHeader;
     StringAttr globalId;
+    StringAttr callerId;
     StringBuffer localId;
 public:
     IMPLEMENT_IINTERFACE_USING(CSimpleInterface);
@@ -2564,11 +2565,15 @@ public:
     {
         return traceLevel;
     }
-    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid)
+    virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid) override
     {
         globalId.set(id);
         appendLocalId(localId.clear(), ep, pid);
     }
+    virtual void setCallerId(const char *id) override
+    {
+        callerId.set(id);
+    }
     virtual const char *queryGlobalId() const
     {
         return globalId.get();
@@ -2577,6 +2582,10 @@ public:
     {
         return localId.str();
     }
+    virtual const char *queryCallerId() const override
+    {
+        return callerId.str();
+    }
     virtual void setHttpIdHeaders(const char *global, const char *caller)
     {
         if (global && *global)

+ 5 - 0
thorlcr/graph/thgraphmaster.cpp

@@ -1310,6 +1310,11 @@ CJobMaster::CJobMaster(IConstWorkUnit &_workunit, const char *graphName, ILoaded
             thorEp.setLocalHost(getMachinePortBase());
             logctx->setGlobalId(txId.str(), thorEp, 0);
 
+            SCMStringBuffer callerId;
+            workunit->getDebugValue("CallerId", callerId);
+            if (callerId.length())
+                logctx->setCallerId(callerId.str());
+
             VStringBuffer msg("GlobalId: %s", txId.str());
             workunit->getDebugValue("CallerId", txId);
             if (txId.length())

+ 5 - 1
thorlcr/graph/thgraphslave.cpp

@@ -1622,12 +1622,16 @@ CJobSlave::CJobSlave(ISlaveWatchdog *_watchdog, IPropertyTree *_workUnitInfo, co
         {
             SocketEndpoint thorEp;
             thorEp.setLocalHost(getMachinePortBase());
-            logctx->setGlobalId(globalId, thorEp, 0);
 
             VStringBuffer msg("GlobalId: %s", globalId);
+            logctx->setGlobalId(globalId, thorEp, 0);
+
             const char *callerId = workUnitInfo->queryProp("debug/callerid");
             if (callerId && *callerId)
+            {
                 msg.append(", CallerId: ").append(callerId);
+                logctx->setCallerId(callerId);
+            }
             const char *localId = logctx->queryLocalId();
             if (localId && *localId)
                 msg.append(", LocalId: ").append(localId);