From 2a84727ea22cf7a34f2d90781c1f4bf9ae79c9a3 Mon Sep 17 00:00:00 2001 From: M Kelly Date: Mon, 23 Sep 2024 15:58:35 -0400 Subject: [PATCH] HPCC-31755 Soapcall LOG multi-line separator Signed-off-by: M Kelly --- common/thorhelper/thorsoapcall.cpp | 33 +++++++++++++++++++++++------- common/thorhelper/thorsoapcall.hpp | 1 + ecl/hthor/hthor.cpp | 5 +++++ roxie/ccd/ccdmain.cpp | 2 ++ roxie/ccd/ccdstate.cpp | 5 +++++ thorlcr/graph/thgraph.cpp | 2 ++ thorlcr/thorutil/thormisc.hpp | 1 + 7 files changed, 42 insertions(+), 7 deletions(-) diff --git a/common/thorhelper/thorsoapcall.cpp b/common/thorhelper/thorsoapcall.cpp index 4e9170e2ec3..02085279a37 100644 --- a/common/thorhelper/thorsoapcall.cpp +++ b/common/thorhelper/thorsoapcall.cpp @@ -50,6 +50,7 @@ using roxiemem::OwnedRoxieString; #define CONNECTION "Connection" unsigned soapTraceLevel = 1; +StringBuffer soapSepString(""); #define WSCBUFFERSIZE 0x10000 #define MAXWSCTHREADS 50 //Max Web Service Call Threads @@ -1014,7 +1015,6 @@ class CWSCHelper : implements IWSCHelper, public CInterface logXML = (flags & SOAPFlog) != 0; logUserMsg = (flags & SOAPFlogusermsg) != 0; logUserTailMsg = (flags & SOAPFlogusertail) != 0; - double dval = helper->getTimeout(); // In seconds, but may include fractions of a second... if (dval < 0.0) //not provided, or out of range timeoutMS = 300*1000; // 300 second default @@ -1940,10 +1940,19 @@ class CWSCAsyncFor : implements IWSCAsyncFor, public CInterface, public CAsyncFo { if (soapTraceLevel > 6 || master->logXML) { - if (!contentEncoded) - master->logctx.mCTXLOG("%s: request(%s)", master->wscCallTypeText(), request.str()); + StringBuffer contentStr(""); + if (contentEncoded) + contentStr.append(", content encoded."); + if ( (master->logXML) && (soapSepString.length() > 0) ) + { + StringBuffer request2(request); + request2.replaceString("\r\n", soapSepString.str()); + request2.replaceString("\r", soapSepString.str()); + request2.replaceString("\n", soapSepString.str()); + master->logctx.mCTXLOG("%s: request(%s)%s", master->wscCallTypeText(), request2.str(), contentStr.str()); + } else - master->logctx.mCTXLOG("%s: request(%s), content encoded.", master->wscCallTypeText(), request.str()); + master->logctx.mCTXLOG("%s: request(%s)%s", master->wscCallTypeText(), request.str(), contentStr.str()); } } @@ -2247,9 +2256,19 @@ class CWSCAsyncFor : implements IWSCAsyncFor, public CInterface, public CAsyncFo if (checkContentDecoding(dbgheader, response, contentEncoding)) decodeContent(contentEncoding.str(), response); if (soapTraceLevel > 6 || master->logXML) - master->logctx.mCTXLOG("%s: LEN=%d %sresponse(%s%s)", getWsCallTypeName(master->wscType),response.length(),chunked?"CHUNKED ":"", dbgheader.str(), response.str()); - else if (soapTraceLevel > 8) - master->logctx.mCTXLOG("%s: LEN=%d %sresponse(%s)", getWsCallTypeName(master->wscType),response.length(),chunked?"CHUNKED ":"", response.str()); // not sure this is that useful but... + { + if ( (master->logXML) && (soapSepString.length() > 0) ) + { + StringBuffer response2(dbgheader); + response2.append(response); + response2.replaceString("\r\n", soapSepString.str()); + response2.replaceString("\r", soapSepString.str()); + response2.replaceString("\n", soapSepString.str()); + master->logctx.mCTXLOG("%s: LEN=%d %sresponse(%s)", getWsCallTypeName(master->wscType),response.length(),chunked?"CHUNKED ":"", response2.str()); + } + else + master->logctx.mCTXLOG("%s: LEN=%d %sresponse(%s%s)", getWsCallTypeName(master->wscType),response.length(),chunked?"CHUNKED ":"", dbgheader.str(), response.str()); + } return rval; } diff --git a/common/thorhelper/thorsoapcall.hpp b/common/thorhelper/thorsoapcall.hpp index aa1c97a6c22..398b5d2a158 100644 --- a/common/thorhelper/thorsoapcall.hpp +++ b/common/thorhelper/thorsoapcall.hpp @@ -86,5 +86,6 @@ interface IRoxieAbortMonitor extern THORHELPER_API unsigned soapTraceLevel; extern THORHELPER_API IWSCHelper * createSoapCallHelper(IWSCRowProvider *, IEngineRowAllocator * outputAllocator, const char *authToken, SoapCallMode scMode, ClientCertificate *clientCert, const IContextLogger &logctx, IRoxieAbortMonitor * roxieAbortMonitor); extern THORHELPER_API IWSCHelper * createHttpCallHelper(IWSCRowProvider *, IEngineRowAllocator * outputAllocator, const char *authToken, SoapCallMode scMode, ClientCertificate *clientCert, const IContextLogger &logctx, IRoxieAbortMonitor * roxieAbortMonitor); +extern THORHELPER_API StringBuffer soapSepString; #endif /* __THORSOAPCALL_HPP_ */ diff --git a/ecl/hthor/hthor.cpp b/ecl/hthor/hthor.cpp index e00fb39bcb7..6f5ce9ec833 100644 --- a/ecl/hthor/hthor.cpp +++ b/ecl/hthor/hthor.cpp @@ -7738,6 +7738,11 @@ void CHThorWSCBaseActivity::init() JBASE64_Encode(uidpair.str(), uidpair.length(), authToken, false); } soapTraceLevel = agent.queryWorkUnit()->getDebugValueInt("soapTraceLevel", 1); + StringBuffer soapSepStr; + StringBufferAdaptor soapSepAdaptor(soapSepStr); + agent.queryWorkUnit()->getDebugValue("soapSepString", soapSepAdaptor); + if (!soapSepStr.isEmpty()) + soapSepString.clear().append(soapSepStr); } //--------------------------------------------------------------------------- diff --git a/roxie/ccd/ccdmain.cpp b/roxie/ccd/ccdmain.cpp index 9d2680aa8ee..984672b782f 100644 --- a/roxie/ccd/ccdmain.cpp +++ b/roxie/ccd/ccdmain.cpp @@ -888,6 +888,8 @@ int CCD_API roxie_main(int argc, const char *argv[], const char * defaultYaml) udpTraceLevel = topology->getPropInt("@udpTraceLevel", runOnce ? 0 : 1); roxiemem::setMemTraceLevel(topology->getPropInt("@memTraceLevel", runOnce ? 0 : 1)); soapTraceLevel = topology->getPropInt("@soapTraceLevel", runOnce ? 0 : 1); + if (topology->hasProp("@soapSepString")) + topology->getProp("@soapSepString", soapSepString); miscDebugTraceLevel = topology->getPropInt("@miscDebugTraceLevel", 0); traceRemoteFiles = topology->getPropBool("@traceRemoteFiles", false); testAgentFailure = topology->getPropInt("expert/@testAgentFailure", testAgentFailure); diff --git a/roxie/ccd/ccdstate.cpp b/roxie/ccd/ccdstate.cpp index 1b239971d9c..4449da6fdc8 100644 --- a/roxie/ccd/ccdstate.cpp +++ b/roxie/ccd/ccdstate.cpp @@ -2925,6 +2925,11 @@ class CRoxiePackageSetManager : implements IRoxieQueryPackageManagerSet, impleme soapTraceLevel = control->getPropInt("@level", 0); topology->setPropInt("@soapTraceLevel", soapTraceLevel); } + else if (stricmp(queryName, "control:soapSepString")==0) + { + if (control->hasProp("@string")) + control->getProp("@string", soapSepString); + } else if (stricmp(queryName, "control:socketCheckInterval")==0) { socketCheckInterval = (unsigned) control->getPropInt64("@val", 0); diff --git a/thorlcr/graph/thgraph.cpp b/thorlcr/graph/thgraph.cpp index 414b2ec22e2..c7fd6c9159a 100644 --- a/thorlcr/graph/thgraph.cpp +++ b/thorlcr/graph/thgraph.cpp @@ -2750,6 +2750,8 @@ void CJobBase::init() failOnLeaks = getOptBool(THOROPT_FAIL_ON_LEAKS); maxLfnBlockTimeMins = getOptInt(THOROPT_MAXLFN_BLOCKTIME_MINS, DEFAULT_MAXLFN_BLOCKTIME_MINS); soapTraceLevel = getOptInt(THOROPT_SOAP_TRACE_LEVEL, 1); + getOpt(THOROPT_SOAP_SEP_STRING, soapSepString); + PROGLOG("mck - soapSepString = %s", soapSepString.str()); StringBuffer tracing("maxActivityCores = "); if (maxActivityCores) diff --git a/thorlcr/thorutil/thormisc.hpp b/thorlcr/thorutil/thormisc.hpp index 260b58a5b55..b98ae50af47 100644 --- a/thorlcr/thorutil/thormisc.hpp +++ b/thorlcr/thorutil/thormisc.hpp @@ -118,6 +118,7 @@ #define THOROPT_MEMORY_SPILL_AT "memorySpillAt" // The threshold (%) that roxiemem will request memory to be reduced (default=80) #define THOROPT_FAIL_ON_LEAKS "failOnLeaks" // If any leaks are detected at the end of graph, fail the query (default=false) #define THOROPT_SOAP_TRACE_LEVEL "soapTraceLevel" // The trace SOAP level (default=1) +#define THOROPT_SOAP_SEP_STRING "soapSepString" // The SOAP request/response separator string for logging (default="") #define THOROPT_SORT_ALGORITHM "sortAlgorithm" // The algorithm used to sort records (quicksort/mergesort) #define THOROPT_COMPRESS_ALLFILES "v9_4_compressAllOutputs" // Compress all output files (default: bare-metal=off, cloud=on) #define THOROPT_AVOID_RENAME "avoidRename" // Avoid rename, write directly to target physical filenames (no temp file)