Subject: |
[Merge] lp:~mshankar/epics-base/softioclogging into lp:epics-base |
From: |
Andrew Johnson <[email protected]> |
To: |
[email protected] |
Date: |
Thu, 25 Aug 2011 00:35:13 -0000 |
Andrew Johnson has proposed merging lp:~mshankar/epics-base/softioclogging into lp:epics-base.
Requested reviews:
EPICS Core Developers (epics-core)
For more details, see:
https://code.launchpad.net/~mshankar/epics-base/softioclogging/+merge/72816
Codeathon: Add logClientPrefix command and functionality.
This branch includes code, tests and release notes.
AppDevGuide entry also supplied separately.
--
https://code.launchpad.net/~mshankar/epics-base/softioclogging/+merge/72816
Your team EPICS Core Developers is requested to review the proposed merge of lp:~mshankar/epics-base/softioclogging into lp:epics-base.
=== modified file 'documentation/RELEASE_NOTES.html'
--- documentation/RELEASE_NOTES.html 2011-08-23 23:19:55 +0000
+++ documentation/RELEASE_NOTES.html 2011-08-25 00:35:04 +0000
@@ -280,5 +280,15 @@
Removed the 3.13 <top>/config directory and build compatibility rules and
variables, and various conversion documents.</p>
+<h3>
+Added support for iocLogPrefix</h3>
+
+<p>
+Added a <code>iocLogPrefix</code> command to <code>ioCsh</code>. This establishes a prefix that will be
+common to all log messages as they are sent to the iocLogServer. This lets us use the
+"fac=<<i>facility</i>>" syntax for displaying the facility, process name etc. in log viewers like the
+<code>cmlogviewer<code>.
+</p>
+
</body>
</html>
=== modified file 'src/libCom/iocsh/libComRegister.c'
--- src/libCom/iocsh/libComRegister.c 2010-05-03 22:26:41 +0000
+++ src/libCom/iocsh/libComRegister.c 2011-08-25 00:35:04 +0000
@@ -191,6 +191,15 @@
errlogPrintfNoConsole("%s\n", args[0].sval);
}
+/* iocLogPrefix */
+static const iocshArg iocLogPrefixArg0 = { "prefix",iocshArgString};
+static const iocshArg * const iocLogPrefixArgs[1] = {&iocLogPrefixArg0};
+static const iocshFuncDef iocLogPrefixFuncDef = {"iocLogPrefix",1,iocLogPrefixArgs};
+static void iocLogPrefixCallFunc(const iocshArgBuf *args)
+{
+ iocLogPrefix(args[0].sval);
+}
+
/* epicsThreadShowAll */
static const iocshArg epicsThreadShowAllArg0 = { "level",iocshArgInt};
static const iocshArg * const epicsThreadShowAllArgs[1] = {&epicsThreadShowAllArg0};
@@ -355,6 +364,7 @@
iocshRegister(&errlogInitFuncDef,errlogInitCallFunc);
iocshRegister(&errlogInit2FuncDef,errlogInit2CallFunc);
iocshRegister(&errlogFuncDef, errlogCallFunc);
+ iocshRegister(&iocLogPrefixFuncDef, iocLogPrefixCallFunc);
iocshRegister(&epicsThreadShowAllFuncDef,epicsThreadShowAllCallFunc);
iocshRegister(&threadFuncDef, threadCallFunc);
=== modified file 'src/libCom/log/logClient.c'
--- src/libCom/log/logClient.c 2009-07-09 16:37:24 +0000
+++ src/libCom/log/logClient.c 2011-08-25 00:35:04 +0000
@@ -58,6 +58,11 @@
static const double LOG_SERVER_SHUTDOWN_TIMEOUT = 30.0; /* sec */
/*
+ * The logClientPrefix stores a prefix that is sent as a prefix for all log messages.
+ */
+static char* logClientPrefix = NULL;
+
+/*
* logClientClose ()
*/
static void logClientClose ( logClient *pClient )
@@ -160,21 +165,13 @@
}
/*
- * logClientSend ()
+ * private method with code refactored out of logClientSend.
+ * This method relies on the mutex being obtained on pClient->mutex (which happens in logClientSend prior to this method being called)
*/
-void epicsShareAPI logClientSend ( logClientId id, const char * message )
-{
- logClient * pClient = ( logClient * ) id;
+static void sendLogMessageinChunks(logClient * pClient, const char * message) {
unsigned strSize;
- if ( ! pClient || ! message ) {
- return;
- }
-
strSize = strlen ( message );
-
- epicsMutexMustLock ( pClient->mutex );
-
while ( strSize ) {
unsigned msgBufBytesLeft =
sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex;
@@ -231,10 +228,31 @@
break;
}
}
-
+}
+
+
+/*
+ * logClientSend ()
+ */
+void epicsShareAPI logClientSend ( logClientId id, const char * message )
+{
+ logClient * pClient = ( logClient * ) id;
+
+ if ( ! pClient || ! message ) {
+ return;
+ }
+
+ epicsMutexMustLock ( pClient->mutex );
+
+ if(logClientPrefix) {
+ sendLogMessageinChunks(pClient, logClientPrefix);
+ }
+ sendLogMessageinChunks(pClient, message);
+
epicsMutexUnlock (pClient->mutex);
}
+
void epicsShareAPI logClientFlush ( logClientId id )
{
logClient * pClient = ( logClient * ) id;
@@ -553,5 +571,33 @@
pClient->sock==INVALID_SOCKET?"INVALID":"OK",
pClient->connectCount);
}
-}
+
+ if(logClientPrefix) {
+ printf ("log client: a log prefix has been set \"%s\"\n", logClientPrefix);
+ }
+}
+
+/*
+ * iocLogPrefix()
+ **/
+void epicsShareAPI iocLogPrefix(const char* prefix)
+{
+ // If we have already established a log prefix, do not let the user change it
+ // Note iocLogPrefix is expected to be set in the cmd file during initialization.
+ // We do not anticipate changing this after it has been set
+ if(logClientPrefix) {
+ printf ("log client: a log prefix has already been established \"%s\". Ignoring this call \n", logClientPrefix);
+ return;
+ }
+
+ if(prefix) {
+ unsigned prefixLen = strlen(prefix);
+ if(prefixLen > 0) {
+ char* localCopy = malloc(prefixLen+1);
+ strcpy(localCopy, prefix);
+ logClientPrefix = localCopy;
+ }
+ }
+}
+
=== modified file 'src/libCom/log/logClient.h'
--- src/libCom/log/logClient.h 2005-11-22 00:28:17 +0000
+++ src/libCom/log/logClient.h 2011-08-25 00:35:04 +0000
@@ -33,6 +33,7 @@
epicsShareFunc void epicsShareAPI logClientSend (logClientId id, const char *message);
epicsShareFunc void epicsShareAPI logClientShow (logClientId id, unsigned level);
epicsShareFunc void epicsShareAPI logClientFlush (logClientId id);
+epicsShareFunc void epicsShareAPI iocLogPrefix(const char* prefix);
/* deprecated interface; retained for backward compatibility */
/* note: implementations are in iocLog.c, not logClient.c */
=== modified file 'src/libCom/test/epicsErrlogTest.c'
--- src/libCom/test/epicsErrlogTest.c 2011-03-01 21:03:33 +0000
+++ src/libCom/test/epicsErrlogTest.c 2011-08-25 00:35:04 +0000
@@ -22,6 +22,11 @@
#include "errlog.h"
#include "epicsUnitTest.h"
#include "testMain.h"
+#include "iocLog.h"
+#include "logClient.h"
+#include "envDefs.h"
+#include "osiSock.h"
+#include "fdmgr.h"
#define LOGBUFSIZE 2048
@@ -75,6 +80,27 @@
int jam;
} clientPvt;
+static void testLogPrefix(void);
+static void acceptNewClient( void *pParam );
+static void readFromClient( void *pParam );
+static void testPrefixLogandCompare( const char* logmessage);
+
+static void *pfdctx;
+static SOCKET sock;
+static SOCKET insock;
+
+static const char* prefixactualmsg[]= {
+ "A message without prefix",
+ "A message with prefix",
+ "DONE"
+ };
+static const char prefixexpectedmsg[] = "A message without prefix"
+ "fac=LI21 A message with prefix"
+ "fac=LI21 DONE"
+ ;
+static char prefixmsgbuffer[1024];
+
+
static
void logClient(void* raw, const char* msg)
{
@@ -115,7 +141,7 @@
char msg[256];
clientPvt pvt, pvt2;
- testPlan(25);
+ testPlan(35);
strcpy(msg, truncmsg);
@@ -289,5 +315,143 @@
/* Clean up */
errlogRemoveListener(&logClient);
+ testLogPrefix();
+
return testDone();
}
+/*
+ * Tests the log prefix code
+ * Since the log prefix is only applied to log messages as they are going out on the socket,
+ * we need to create a server listening on a port, accept connections etc.
+ * This code is a reduced version of the code in iocLogServer.
+ */
+static void testLogPrefix(void) {
+ struct sockaddr_in serverAddr;
+ int status;
+ struct timeval timeout;
+ struct sockaddr_in actualServerAddr;
+ osiSocklen_t actualServerAddrSize;
+
+
+ testDiag("Testing iocLogPrefix");
+
+ timeout.tv_sec = 5; /* in seconds */
+ timeout.tv_usec = 0;
+
+ memset((void*)prefixmsgbuffer, 0, sizeof prefixmsgbuffer);
+
+ /* Clear "errlog: <n> messages were discarded" status */
+ errlogPrintfNoConsole(".");
+ errlogFlush();
+
+ sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0);
+ testOk1(sock != INVALID_SOCKET);
+
+ // We listen on a an available port.
+ memset((void *)&serverAddr, 0, sizeof serverAddr);
+ serverAddr.sin_family = AF_INET;
+ serverAddr.sin_port = htons(0);
+
+ status = bind (sock,
+ (struct sockaddr *)&serverAddr,
+ sizeof (serverAddr) );
+ testOk1(status >= 0);
+
+ status = listen(sock, 10);
+ testOk1(status >= 0);
+
+ // Determine the port that the OS chose
+ actualServerAddrSize = sizeof actualServerAddr;
+ memset((void *)&actualServerAddr, 0, sizeof serverAddr);
+ status = getsockname(sock, (struct sockaddr *) &actualServerAddr, &actualServerAddrSize);
+ testOk1(status >= 0);
+
+ char portstring[16];
+ sprintf(portstring, "%d", ntohs(actualServerAddr.sin_port));
+ testDiag("Listening on port %s", portstring);
+
+ // Set the EPICS environment variables for logging.
+ epicsEnvSet ( "EPICS_IOC_LOG_INET", "localhost" );
+ epicsEnvSet ( "EPICS_IOC_LOG_PORT", portstring );
+
+ pfdctx = (void *) fdmgr_init();
+ testOk1(pfdctx != NULL);
+
+ status = fdmgr_add_callback(
+ pfdctx,
+ sock,
+ fdi_read,
+ acceptNewClient,
+ &serverAddr);
+ testOk1(status >= 0);
+
+ status = iocLogInit ();
+ testOk1(status >= 0);
+ fdmgr_pend_event(pfdctx, &timeout);
+
+ testPrefixLogandCompare(prefixactualmsg[0]);
+
+ iocLogPrefix("fac=LI21 ");
+ testPrefixLogandCompare(prefixactualmsg[1]);
+ testPrefixLogandCompare(prefixactualmsg[2]);
+
+ close(sock);
+}
+
+static void testPrefixLogandCompare( const char* logmessage ) {
+ struct timeval timeout;
+ timeout.tv_sec = 5; /* in seconds */
+ timeout.tv_usec = 0;
+
+ errlogPrintfNoConsole(logmessage);
+ errlogFlush();
+ iocLogFlush();
+ fdmgr_pend_event(pfdctx, &timeout);
+}
+
+static void acceptNewClient ( void *pParam )
+{
+ osiSocklen_t addrSize;
+ struct sockaddr_in addr;
+ int status;
+
+ addrSize = sizeof ( addr );
+ insock = epicsSocketAccept ( sock, (struct sockaddr *)&addr, &addrSize );
+ testOk1(insock!=INVALID_SOCKET && addrSize >= sizeof (addr) );
+
+ status = fdmgr_add_callback(
+ pfdctx,
+ insock,
+ fdi_read,
+ readFromClient,
+ NULL);
+ testOk1(status >= 0);
+}
+
+static void readFromClient(void *pParam)
+{
+ char recvbuf[1024];
+ int recvLength;
+
+ memset(&recvbuf, 0, 1024);
+ recvLength = recv(insock,
+ &recvbuf,
+ 1024,
+ 0);
+ if (recvLength > 0) {
+ strcat(prefixmsgbuffer, recvbuf);
+
+ // If we have received all of the messages.
+ if(strstr(prefixmsgbuffer, "DONE") != NULL) {
+ int prefixcmp = strncmp(prefixexpectedmsg, prefixmsgbuffer, strlen(prefixexpectedmsg));
+ if(prefixcmp != 0) {
+ printf("Expected %s\n", prefixexpectedmsg);
+ printf("Obtained %s\n", prefixmsgbuffer);
+ }
+
+ testOk1(prefixcmp == 0);
+ }
+ }
+}
+
+
- Replies:
- Re: [Merge] lp:~mshankar/epics-base/softioclogging into lp:epics-base Andrew Johnson
- [Merge] lp:~mshankar/epics-base/softioclogging into lp:epics-base noreply
- Navigate by Date:
- Prev:
Re: [Merge] lp:~mdavidsaver/epics-base/reorg-src into lp:epics-base Andrew Johnson
- Next:
Re: [Merge] lp:~mshankar/epics-base/softioclogging into lp:epics-base Andrew Johnson
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
<2011>
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
[Merge] lp:~epics-core/epics-base/3.15-buildCompilerSpecific into lp:epics-base noreply
- Next:
Re: [Merge] lp:~mshankar/epics-base/softioclogging into lp:epics-base Andrew Johnson
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
<2011>
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|