-
Notifications
You must be signed in to change notification settings - Fork 304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HPCC-31755 Soapcall LOG multi-line separator #19145
Conversation
c8dc2fc
to
608dee7
Compare
Jira Issue: https://hpccsystems.atlassian.net//browse/HPCC-31755 Jirabot Action Result: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mckellyln - please see comments.
common/thorhelper/thorsoapcall.cpp
Outdated
@@ -1951,10 +1952,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(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial/style: ("") not needed.
ecl/hthor/hthor.cpp
Outdated
StringBufferAdaptor soapSepAdaptor(soapSepStr); | ||
agent.queryWorkUnit()->getDebugValue("soapLogSepString", soapSepAdaptor); | ||
if (!soapSepStr.isEmpty()) | ||
soapSepString.clear().append(soapSepStr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not populate soapSepStr directly? :
StringBufferAdaptor soapSepAdaptor(soapSepString);
agent.queryWorkUnit()->getDebugValue("soapLogSepString", soapSepAdaptor);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
calling here (in activity init code) means it this will be called multiple times per job (if there are act based on this base per job). [ that's true of existing soapTraceLevel line too ]
Maybe nothing to worry about
common/thorhelper/thorsoapcall.cpp
Outdated
@@ -50,6 +50,7 @@ using roxiemem::OwnedRoxieString; | |||
#define CONNECTION "Connection" | |||
|
|||
unsigned soapTraceLevel = 1; | |||
StringBuffer soapSepString(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial/style: ("") not needed.
common/thorhelper/thorsoapcall.cpp
Outdated
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()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: the start of contentStr could be commoned up to include the "%s: request":
VStringBuffer contentStr("%s: request", master->wscCallTypeText());
common/thorhelper/thorsoapcall.hpp
Outdated
@@ -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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is going to cause the object to be copied where included I think.
Should either be a reference or a method
To be reference would mean the cpp would have to have code something like this:
static StringBuffer _soapSepString;
StringBuffer &soapSepString = _soapSepString;
A method is probably cleanest.
common/thorhelper/thorsoapcall.cpp
Outdated
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()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mCTXLOG (multiline CTXLOG) is parsing newline/carriage returns specifically to call multiple CTXLOG calls).
I think you should be calling logctx.CTXLOG after removing the newlines.
roxie/ccd/ccdstate.cpp
Outdated
else if (stricmp(queryName, "control:soapLogSepString")==0) | ||
{ | ||
if (control->hasProp("@string")) | ||
control->getProp("@string", soapSepString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this theoretically thread unsafe in combination with the placement of the code in HThorWSCBaseActivity::init() ?
e.g. if an activity is initializing when this thread is also initializing.
Also, if called multiple times soapSepString will grow (should be soapSepString.clear())
common/thorhelper/thorsoapcall.cpp
Outdated
response2.append(response); | ||
response2.replaceString("\r\n", soapSepString.str()); | ||
response2.replaceString("\r", soapSepString.str()); | ||
response2.replaceString("\n", soapSepString.str()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite expensive (to build up new StringBuffer with dbgheader+response), then call multiple replaceString's which will walk the whole response for each call.
It may be worth adding a function to append to a StringBuffer replacing the sequences with the new separator (or removing them) as it goes.
An efficient implementation could be quite simple if it only removed (meaning the target was guaranteed to be smaller than source).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE this PR to optimize replaceString: #19187
@jakesmith thx, please re-review changes in commit 2 |
} | ||
|
||
static void multiLineAppendReplace(StringBuffer &origStr, StringBuffer &newStr) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an opt, we could index for '\r' and then append chunks between newlines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, if it was very time critical, might be worth two pass, so can allocate correct size once, reserve and use regular ptr's instead of calls to StringBuffer, but doubt worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mckellyln - looks good, a few minor/trivial comments
common/thorhelper/thorsoapcall.cpp
Outdated
StringBuffer soapSepString; | ||
static CriticalSection soapCrit; | ||
|
||
void setSoapSepString(StringBuffer &_soapSepString) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial/style: if no benefit to passing a StringBuffer as param vs simlp[e const char *, then we normally do later, it's more portable/usable (doesn't enforce having to need a StringBuffer when not needed).
common/thorhelper/thorsoapcall.cpp
Outdated
void setSoapSepString(StringBuffer &_soapSepString) | ||
{ | ||
CriticalBlock b(soapCrit); | ||
soapSepString.clear().append(_soapSepString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial: StringBuffer::set is equivalent
ecl/hthor/hthor.cpp
Outdated
@@ -7741,8 +7741,7 @@ void CHThorWSCBaseActivity::init() | |||
StringBuffer soapSepStr; | |||
StringBufferAdaptor soapSepAdaptor(soapSepStr); | |||
agent.queryWorkUnit()->getDebugValue("soapLogSepString", soapSepAdaptor); | |||
if (!soapSepStr.isEmpty()) | |||
soapSepString.clear().append(soapSepStr); | |||
setSoapSepString(soapSepStr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this means the default (and in thorsoapcall.cpp) is an empty string.
i.e. by default soap responses will be stripped of linefeeds and lines concatenated together. Is that what we want?
Shouldn't " " be set to default in thorsoapcall, and not changed here / elsewhere, unless option provided?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If soapSepString is empty (the default unless its set in config) then no translation is done.
I didn't think we should also allow only removal of the newlines.
thorlcr/graph/thgraph.cpp
Outdated
getOpt(THOROPT_SOAP_LOG_SEP_STRING, soapSepString); | ||
StringBuffer tmpSepString; | ||
getOpt(THOROPT_SOAP_LOG_SEP_STRING, tmpSepString); | ||
setSoapSepString(tmpSepString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see other comment in hthor.cpp - shouldn't it default to something like " " in thorsoapcall.cpp - and only set/change here if property present? Otherwise default is to strip and join lines together.
common/thorhelper/thorsoapcall.cpp
Outdated
@@ -50,6 +50,41 @@ using roxiemem::OwnedRoxieString; | |||
#define CONNECTION "Connection" | |||
|
|||
unsigned soapTraceLevel = 1; | |||
StringBuffer soapSepString; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like this should now be a static
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, yes
} | ||
|
||
static void multiLineAppendReplace(StringBuffer &origStr, StringBuffer &newStr) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, if it was very time critical, might be worth two pass, so can allocate correct size once, reserve and use regular ptr's instead of calls to StringBuffer, but doubt worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mckellyln - looks good. Please squash.
Thanks, squashed. |
common/thorhelper/thorsoapcall.cpp
Outdated
if (origStr.isEmpty()) | ||
return; | ||
const char *cursor = origStr; | ||
while (cursor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be while (*cursor) (or could be while (true) which it effectively is)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
static void multiLineAppendReplace(StringBuffer &origStr, StringBuffer &newStr) | ||
{ | ||
if (origStr.isEmpty()) | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we newStr.ensureCapacity(origStr.length()) before starting loop so we dont have to expand it more than once ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if replacement separator was >1 char and existing separator was \n, it would still have to expand more than once.
an initial guess ensureCapacity wouldn't harm, but not sure worth it, unless this is going to intensively used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree preallocate to the original size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
I don't understand failing test - exec sudo snap install microk8s --channel=1.27/stable --classic { silent: false }
I think this is unrelated to code changes ? |
ok, a rerun of the tests shows all ok |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, a few minor comments
StringBuffer contentStr; | ||
if (contentEncoded) | ||
contentStr.append(", content encoded."); | ||
if ( (master->logXML) && (soapSepString.length() > 0) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check: I think the master->logXML test can be deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left it and added comment - so we only do translation if LOG set in SOAPCALL args
static void multiLineAppendReplace(StringBuffer &origStr, StringBuffer &newStr) | ||
{ | ||
if (origStr.isEmpty()) | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree preallocate to the original size.
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) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
common/thorhelper/thorsoapcall.cpp
Outdated
|
||
void setSoapSepString(const char *_soapSepString) | ||
{ | ||
CriticalBlock b(soapCrit); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the critical and the control: command to change it, and require that this is only called when no soapcalls are running, OR all access to this static needs to be in a critical block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it enough that we remove the control: dynamic setting of this ? As then its only set at job start or Roxie start.
@ghalliday updated PR, thank you. Will squash when ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mckellyln please squash
@@ -7738,6 +7738,10 @@ void CHThorWSCBaseActivity::init() | |||
JBASE64_Encode(uidpair.str(), uidpair.length(), authToken, false); | |||
} | |||
soapTraceLevel = agent.queryWorkUnit()->getDebugValueInt("soapTraceLevel", 1); | |||
StringBuffer soapSepStr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
future: Can use SCMStringBuffer to avoid the need for the adaptor.
Signed-off-by: M Kelly <[email protected]>
Squashed |
Type of change:
Checklist:
Smoketest:
Testing: