diff --git a/documentation/new-notes/PR-679.md b/documentation/new-notes/PR-679.md new file mode 100644 index 000000000..055f623e7 --- /dev/null +++ b/documentation/new-notes/PR-679.md @@ -0,0 +1,8 @@ +### Apply log prefix to each line + +If multi-line ioc log messages are sent with `errlogPrintf()`, apply +`logClientPrefix` (e.g. set by `iocLogPrefix`) to each line in order to help +browsing the log files. +Also strip off any leading newlines which some calls have. + +Extend `errlog` iocsh command to interpret escape chars (just like `echo`). diff --git a/modules/libcom/src/iocsh/libComRegister.c b/modules/libcom/src/iocsh/libComRegister.c index fd7c232de..e7c72cd12 100644 --- a/modules/libcom/src/iocsh/libComRegister.c +++ b/modules/libcom/src/iocsh/libComRegister.c @@ -291,8 +291,12 @@ static void errlogInit2CallFunc(const iocshArgBuf *args) } /* errlog */ -IOCSH_STATIC_FUNC void errlog(const char *message) +IOCSH_STATIC_FUNC void errlog(char *message) { + if (message) + dbTranslateEscape(message, message); /* in-place is safe */ + else + message = ""; errlogPrintfNoConsole("%s\n", message); } diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 7840211fd..1260cc543 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -168,12 +168,9 @@ static void logClientDestroy (logClientId id) /* * This method requires the pClient->mutex be owned already. */ -static void sendMessageChunk(logClient * pClient, const char * message) { - unsigned strSize; - - strSize = strlen ( message ); +static void sendMessageChunk(logClient * pClient, const char * message, size_t strSize) { while ( strSize ) { - unsigned msgBufBytesLeft = + size_t msgBufBytesLeft = sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex; if ( msgBufBytesLeft < strSize && pClient->nextMsgIndex != 0u && pClient->connected) @@ -202,17 +199,44 @@ static void sendMessageChunk(logClient * pClient, const char * message) { void epicsStdCall logClientSend ( logClientId id, const char * message ) { logClient * pClient = ( logClient * ) id; + size_t prefixLength; if ( ! pClient || ! message ) { return; } + while (*message == '\n') { + message++; /* skip initial newlines */ + } + if (!*message) { + return; + } epicsMutexMustLock ( pClient->mutex ); if (logClientPrefix) { - sendMessageChunk(pClient, logClientPrefix); + prefixLength = strlen(logClientPrefix); + } else { + prefixLength = 0; } - sendMessageChunk(pClient, message); + do { + /* apply logClientPrefix to each line */ + size_t lineLength; + char* lineEnd = strchr(message, '\n'); + if (lineEnd) { + lineLength = lineEnd + 1 - message; + } else { + lineLength = strlen(message); + } + if (prefixLength) { + sendMessageChunk(pClient, logClientPrefix, prefixLength); + } + sendMessageChunk(pClient, message, lineLength); + if (!lineEnd) { + /* terminate last line if necessary */ + sendMessageChunk(pClient, "\n", 1); + } + message += lineLength; + } while (*message); epicsMutexUnlock (pClient->mutex); }