Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019 
<== Date ==> <== Thread ==>

Subject: [Merge] lp:~mshankar/epics-base/softioclogging into lp:epics-base
From: Andrew Johnson <anj@aps.anl.gov>
To: mp+72816@code.launchpad.net
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 &lt;top&gt;/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=&lt;<i>facility</i>&gt;" 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  <20112012  2013  2014  2015  2016  2017  2018  2019 
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  <20112012  2013  2014  2015  2016  2017  2018  2019 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·