1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: Radisys Logging Framework
23 Desc: This file contains logging framework implementation.
26 *********************************************************************21*/
27 /**********************************************************************
28 @ description: This is source file which has implementaion of logging
30 ************************************************************************/
34 #include "rl_interface.h"
38 #include <sys/socket.h>
39 #include <sys/types.h>
41 #include <sys/resource.h>
47 #include <netinet/in.h>
53 #include "rl_platform.h"
69 #include "rl_interface.h"
71 char g_fileName[MAX_FILENAME_LEN];
72 char g_logDir[MAX_FILENAME_LEN];
73 char g_fileList[RLOG_MAX_FILES][MAX_FILENAME_LEN];
74 #ifdef RLOG_USE_CIRCULAR_BUFFER
75 static THREAD_DATA *g_pSingCirBuff = NULL;
76 static U16 g_prevLogOffset=0;
78 #ifndef RLOG_ENABLE_TEXT_LOGGING
79 static volatile U32 g_rlogPositionIndex=0;
80 U32 gIpType = CM_IPV4ADDR_TYPE;
83 ///////////////////////////////////////////////////////////////////////////////////////////////////
84 // Default variable initilization
85 ///////////////////////////////////////////////////////////////////////////////////////////////////
87 /* global file pointer */
91 #ifndef RLOG_ENABLE_TEXT_LOGGING
93 Data *g_l2rlogBuf = NULLP;
94 Data *g_l2LogBufStartPtr = NULLP;
95 Data *g_l2LogBufBasePtr = NULLP;
96 Data *g_logBufRcvdFromL2 = NULLP;
97 Data *g_l2LogBaseBuff = NULLP;
98 U32 g_logBufLenRcvdFromL2 = 0;
99 U32 g_l2LogBufLen = 0;
100 U32 startL2Logging = 0;
101 U32 g_l2logBuffPos = 0;
103 #endif /* Binary Logging */
105 /* number of times log function is called */
108 /* Socke descriptor if remote client is connected */
109 int g_nCliSocket = 0;
111 /* Default log level Error */
115 int g_logLevel = L_MAX_LOG_LEVEL;
117 /* MAX Log Files 1 */
118 U8 g_nMaxLogFiles = 1;
120 /* Max File Size limit for each log file */
121 U32 g_uiMaxFileSizeLimit = MAX_FILE_SIZE;
123 /* Default circular buffer size 100Kb*/
124 U32 g_cirMaxBufferSize = RLOG_MAX_CIRBUF_SIZE;
126 /* Default mask for each module is disabled */
129 /* Remote Logging port */
130 static U32 g_nLogPort = RLOG_REMOTE_LOGGING_PORT;
132 /* Current File Number index */
133 int g_nCurrFileIdx = 0;
135 /* Remote logging flag */
136 static U8 g_bRemoteLoggingDisabled=1;
138 /* Global file descriptor for L2 & L3 */
142 char g_l2Buf[RLOG_MAX_CIRBUF_SIZE];
144 #ifdef RLOG_USE_CIRCULAR_BUFFER
145 /* List of thread data pointers */
146 THREAD_DATA* g_pCirList[RLOG_MAX_THREADS];
148 /* Number of threads registered */
149 static int g_nThreadsRegistered;
151 /* Mutex to protect circular buffers */
152 pthread_mutex_t g_logmutex, g_condmutex;
153 pthread_cond_t g_cond;
155 U8 g_writeCirBuf = 0;
157 static int thread_signalled;
161 static U32 numTtiTicks;
162 /* Console input handling parameters */
163 static int g_kIdx, g_action, g_storeKeys;
164 static char g_keyBuf[32];
166 /* Standard C library, timezone */
167 extern char *tzname[2];
168 ///////////////////////////////////////////////////////////////////////////////
169 // FUNCTION DECLARATIONS //
170 ///////////////////////////////////////////////////////////////////////////////
171 #if defined(RLOG_ENABLE_TEXT_LOGGING)
172 static struct tm* getTime(int* microseconds);
173 static void getLogTimeStr(char* ts);
176 void initGlbDataAtL2(void);
177 void createNewLogFile(void);
178 void createL2LogFile(void);
179 void* rLogServer(void* arg);
180 void closeConnection(int sockfd);
181 void storeTimeDelimeter(FILE* fp);
182 void rlCatchSegViolation(int sig);
183 void flushData(int sig);
184 void* cirBufReaderThread(void* arg);
185 void readCircularBuffers(void);
186 void userAction(void);
187 void handleSigIO(int sig);
188 void rlPrintConfiguration(void);
189 THREAD_DATA* rlRegisterThread(const char* taskName);
190 extern void (*rlSigHandler)(int);
192 void rlInitL2Log(void);
193 U32 g_rlogWriteCount = 0;
194 U32 g_maxRlogCount = 50;
195 U32 g_logsDropCnt = 0;
196 RLLogCntLmt g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
198 #ifndef RLOG_ENABLE_TEXT_LOGGING
199 void readL2LogBuff(void);
200 S16 rlValidateL2LogBuf(void);
201 void rlSetL2LogBuf(U8 *l2LogBuf,U32 l2logLen);
202 void rlResetL2LogBuf(void);
206 #ifndef RLOG_ENABLE_TEXT_LOGGING
207 EndianType getCPU_Endian(Void);
208 void storeFileHeader(FILE* fp);
209 void saveLogDataFromCpul(const void* buf, U16 len);
210 void saveLogData(const void* buf, U16 len, U32 g_rlogWritePosIndex);
211 void sendToPostProcessor(const void* buf, U16 len);
212 void getLogTimeStr(char* ts);
214 ///////////////////////////////////////////////////////////////////////////////////////////////////
215 // @param[in] modMask - bit mask for any particular module.
216 // Sets or clears bit for the particular module. If mask value is zero all bits are cleared.
217 ///////////////////////////////////////////////////////////////////////////////////////////////////
218 void rlSetModuleMask(U32 modMask)
220 g_modMask = (modMask == 0 ) ? 0 : (g_modMask ^ modMask);
223 ///////////////////////////////////////////////////////////////////////////////////////////////////
224 // @param[in] - maxFileSize - Maximum file size in MB.
225 // @brief This function sets the limit to log file size.
226 ///////////////////////////////////////////////////////////////////////////////////////////////////
227 void rlSetLogFileSizeLimit(U32 maxFileSize)
229 g_uiMaxFileSizeLimit = (maxFileSize == 0) ? MAX_FILE_SIZE : maxFileSize*1048576;
232 ///////////////////////////////////////////////////////////////////////////////////////////////////
235 ///////////////////////////////////////////////////////////////////////////////////////////////////
236 void rlSetNumOfLogFiles(U8 nMaxFiles)
238 if( nMaxFiles > RLOG_MAX_FILES || nMaxFiles == 0 ) {
239 g_nMaxLogFiles = RLOG_MAX_FILES;
243 g_nMaxLogFiles = nMaxFiles;
246 ///////////////////////////////////////////////////////////////////////////////////////////////////
248 // @brief 1-> enable remote logging, 0-> disable remote logging
249 ///////////////////////////////////////////////////////////////////////////////////////////////////
250 void rlSetRemoteLoggingFlag(S32 flag)
252 g_bRemoteLoggingDisabled = !flag;
255 ///////////////////////////////////////////////////////////////////////////////////////////////////
256 // @param[in] port - Server port
257 // @brief Use this API to configure port for remote logging application.
258 ///////////////////////////////////////////////////////////////////////////////////////////////////
259 void rlSetLogPort(U32 port)
264 ///////////////////////////////////////////////////////////////////////////////////////////////////
265 // @param[in] enable_core - 1 Enables core file generation 0 - disable
266 // This enables or disables core file generation
267 ///////////////////////////////////////////////////////////////////////////////////////////////////
268 void rlEnableDisableCore(S32 enable_core)
270 struct rlimit core_limits;
271 core_limits.rlim_cur = core_limits.rlim_max = enable_core ? RLIM_INFINITY : 0;
272 setrlimit(RLIMIT_CORE, &core_limits);
275 ///////////////////////////////////////////////////////////////////////////////////////////////////
278 ///////////////////////////////////////////////////////////////////////////////////////////////////
279 void rlSetLogPath(const char* logDir)
281 strncpy(g_logDir, logDir, MAX_FILENAME_LEN);
284 ///////////////////////////////////////////////////////////////////////////////////////////////////
287 ///////////////////////////////////////////////////////////////////////////////////////////////////
288 void rlSetLogFile(const char* fileName)
290 strncpy(g_fileName, fileName, MAX_FILENAME_LEN);
293 ///////////////////////////////////////////////////////////////////////////////////////////////////
296 ///////////////////////////////////////////////////////////////////////////////////////////////////
297 void rlSetLogLevel(R_LOG_LEVEL logLevel)
299 g_logLevel = logLevel + 1;
302 ///////////////////////////////////////////////////////////////////////////////////////////////////
303 // @param[in] bufSize - Circulaer buffer size in multiples of 1Kb or 1024 bytes.
304 // This function is called to set circular buffer size for each thread.
305 ///////////////////////////////////////////////////////////////////////////////////////////////////
306 void rlSetCircularBufferSize(U32 bufSize)
308 g_cirMaxBufferSize = bufSize*1024;
309 g_cirMaxBufferSize = (g_cirMaxBufferSize/50) * 50;
312 ///////////////////////////////////////////////////////////////////////////////////////////////////
315 ///////////////////////////////////////////////////////////////////////////////////////////////////
316 void rlPrintConfiguration(void)
318 fprintf(stderr, "Log File:\t\t[%s]\n", g_fileName);
319 fprintf(stderr, "Log level:\t\t[%s]\n", g_logStr[g_logLevel-1]);
321 fprintf(stderr, "Module Mask:\t\t[%ld]\n", g_modMask);
322 fprintf(stderr, "File Size Limit:\t[%ld]\n", g_uiMaxFileSizeLimit);
324 fprintf(stderr, "Module Mask:\t\t[%d]\n", g_modMask);
325 fprintf(stderr, "File Size Limit:\t[%d]\n", g_uiMaxFileSizeLimit);
327 fprintf(stderr, "Maximum Log Files:\t[%d]\n", g_nMaxLogFiles);
328 fprintf(stderr, "Time Zone:\t\t[%s]\n", tzname[0]);
330 #ifdef RLOG_ENABLE_TEXT_LOGGING
331 fprintf(stderr, "Binary Logging:\t\t[Disabled]\n");
332 fprintf(stderr, "Remote Logging:\t\t[Disabled]\n");
333 fprintf(stderr, "Console Logging:\t[%s]\n", (g_fp==stderr) ? "Enabled" : "Disabled" );
335 fprintf(stderr, "Console Logging:\t[Disabled]\n");
336 fprintf(stderr, "Binary Logging:\t\t[Enabled]\n");
337 fprintf(stderr, "Remote Logging:\t\t[%s]\n", g_bRemoteLoggingDisabled ? "Disabled" : "Enabled");
339 fprintf(stderr, "Remote Logging Port:\t[%ld]\n", g_nLogPort);
341 fprintf(stderr, "Remote Logging Port:\t[%d]\n", g_nLogPort);
343 #ifdef RLOG_USE_CIRCULAR_BUFFER
344 fprintf(stderr, "Circular Buffer:\t[Enabled]\n");
346 fprintf(stderr, "Circular BufferSize:\t[Actual:%ld][Derived:%ld]\n",
347 g_cirMaxBufferSize/1024, g_cirMaxBufferSize);
349 fprintf(stderr, "Circular BufferSize:\t[Actual:%d][Derived:%d]\n",
350 g_cirMaxBufferSize/1024, g_cirMaxBufferSize);
353 fprintf(stderr, "Circular Buffer:\t[Disabled]\n");
354 #endif /* RLOG_USE_CIRCULAR_BUFFER */
355 #endif /* RLOG_ENABLE_TEXT_LOGGING */
359 #ifdef RLOG_USE_CIRCULAR_BUFFER
361 #ifdef RLOG_USE_TTI_LOGGING
362 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
365 logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));\
368 #define CHECK_FILE_SIZE
369 #endif /* RLOG_USE_TTI_LOGGING */
371 #else /* RLOG_USE_CIRCULAR_BUFFER */
373 #ifdef RLOG_USE_TTI_LOGGING
374 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
376 if( g_fp && ftell(g_fp) > g_uiMaxFileSizeLimit ) { \
377 createNewLogFile(); \
380 logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));\
383 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
385 if( g_fp && ( (U32)(ftell(g_fp)) > g_uiMaxFileSizeLimit) ) { \
386 createNewLogFile(); \
390 #endif /* RLOG_USE_TTI_LOGGING */
391 #endif /* RLOG_USE_CIRCULAR_BUFFER */
394 #ifdef RLOG_USE_CIRCULAR_BUFFER
396 #define CHECK_CIRFILE_SIZE if( g_fp && ftell(g_fp) > g_uiMaxFileSizeLimit ) \
399 ///////////////////////////////////////////////////////////////////////////////////////////////////
400 // @param[in] tasName - Name of registering thread / task
401 // This function registers the thread for writing logs. It creates thread specific buffers.
402 ///////////////////////////////////////////////////////////////////////////////////////////////////
403 THREAD_DATA* rlRegisterThread(const char* taskName)
405 THREAD_DATA* pThrData = (THREAD_DATA*) rlCalloc(sizeof(THREAD_DATA));
407 if( pThrData == NULL ) {
408 fprintf(stderr, "Failed to allocate memory for thread %s\n", taskName);
412 pthread_mutex_lock(&g_logmutex);
414 /* Allocate circular buffer */
415 pThrData->logBuff = (U8*) rlAlloc(g_cirMaxBufferSize);
417 if( pThrData->logBuff == NULL ) {
419 fprintf(stderr, "Failed to allocate memory [%ld] for thread %s\n",g_cirMaxBufferSize, taskName);
421 fprintf(stderr, "Failed to allocate memory [%d] for thread %s\n",g_cirMaxBufferSize, taskName);
426 /* store task name */
427 strcpy(pThrData->szTaskName, taskName);
429 //rlSetThreadSpecificData(pThrData);
431 pThrData->listIndex = g_nThreadsRegistered++;
433 /* Store this pointerin global list, to access it later */
434 g_pCirList[pThrData->listIndex] = pThrData;
436 pthread_mutex_unlock(&g_logmutex);
438 #ifdef RLOG_DEBUG_MODE
440 fprintf(stderr, "rlRegisterThread: allocated CIRCULAR BUFFER of size [%ld]\n", g_cirMaxBufferSize);
442 fprintf(stderr, "rlRegisterThread: allocated CIRCULAR BUFFER of size [%d]\n", g_cirMaxBufferSize);
444 fprintf(stderr, "rlRegisterThread: Total registered threads [%d]\n", g_nThreadsRegistered);
450 ///////////////////////////////////////////////////////////////////////////////////////////////////
451 // @param[in] arg - Thread argument
452 // This thread wakes up periodically and transfer logs from thread specific buffer into file system.
453 // If buffer is going to be full, this thread is signalled asynchrounously to read buffered logs.
454 ///////////////////////////////////////////////////////////////////////////////////////////////////
455 void* cirBufReaderThread(void* arg)
457 struct timespec timeout;
460 #ifdef RLOG_DEBUG_MODE
461 fprintf(stderr, "Circular Buffer Reader thread started\n");
466 /*this thread is not active and waiting to timeout */
467 thread_signalled = 0;
469 /* set the thread timeout */
470 timeout.tv_sec = time(NULL) + RLOG_CIRBUF_READ_INTERVAL;
473 /* wait for 120 seconds time interval to read buffer */
474 retCode = pthread_cond_timedwait(&g_cond, &g_condmutex, &timeout);
476 /* this means, this thread is already active, no need to give any other signal to wake up */
477 thread_signalled = 1;
479 #ifdef RLOG_DEBUG_MODE
480 //if(retCode == 0) fprintf(stderr, "cirBufReaderThread: I am signalled to read data\n");
483 /* If someone has given signal or there is timeout */
484 if( retCode == 0 || retCode == ETIMEDOUT ){
485 readCircularBuffers();
489 readCircularBuffers();
491 #ifdef RLOG_DEBUG_MODE
492 fprintf(stderr, "System is exiting ??");
493 perror("cirBufReaderThread");
501 ///////////////////////////////////////////////////////////////////////////////////////////////////
504 ///////////////////////////////////////////////////////////////////////////////////////////////////
505 void readCircularBuffers()
509 /* Check if process is L2. If L2 then return from here */
510 if (SFndProcId() == TENB_L2_PROC_ID)
516 /* Before reading circular buffers, store delimiter */
517 //storeTimeDelimeter(g_fp);
520 pthread_mutex_lock(&g_logmutex);
522 for(i=0; i < g_nThreadsRegistered; i++)
524 THREAD_DATA* pThrData = g_pCirList[i];
526 if( pThrData == NULL )
529 writerPos = pThrData->logBufLen;
531 #ifdef RLOG_DEBUG_MODE
532 //fprintf(stderr, "Thread [%ld] WritePos:[%ld] ReadPos:[%ld]\n", i+1, writerPos, pThrData->logReadPos);
535 if( pThrData->logReadPos < writerPos )
537 /* Calculate the delta data to be read from buffer */
538 int dataLen = writerPos - pThrData->logReadPos;
540 /* Write the data into file */
541 if( fwrite(pThrData->logBuff+pThrData->logReadPos,1, dataLen, g_fp) == -1 )
543 #ifdef RLOG_DEBUG_MODE
544 fprintf(stderr, "Failed to write data len %d\n", dataLen);
549 /* reset log read position to last known position */
550 pThrData->logReadPos = writerPos;
552 else if ( pThrData->logReadPos > writerPos )
554 /* Calculate the remaining data left in the buffer */
555 int dataLen = g_cirMaxBufferSize - pThrData->logReadPos;
557 /* Write from last know position till end */
558 if( fwrite(pThrData->logBuff+pThrData->logReadPos, 1, dataLen, g_fp) == -1 )
560 #ifdef RLOG_DEBUG_MODE
561 fprintf(stderr, "Failed to write data len %d\n", dataLen);
567 /* Write from 0 to len position */
568 if( fwrite(pThrData->logBuff, 1, writerPos, g_fp) == -1 )
570 #ifdef RLOG_DEBUG_MODE
571 fprintf(stderr, "Failed to write data len %d\n", dataLen);
577 /* reset log read position to last known position */
578 pThrData->logReadPos = writerPos;
582 /* unlock the mutex */
583 pthread_mutex_unlock(&g_logmutex);
585 /* after reading circular buffers also store delimiter */
586 //storeTimeDelimeter(g_fp);
595 #ifndef RLOG_ENABLE_TEXT_LOGGING
596 ///////////////////////////////////////////////////////////////////////////////////////////////////
599 ///////////////////////////////////////////////////////////////////////////////////////////////////
600 EndianType getCPU_Endian(Void)
606 c = *(unsigned char *)(&x);
608 return ( c == 0x01 ) ? little_endian : big_endian;
611 ///////////////////////////////////////////////////////////////////////////////////////////////////
614 ///////////////////////////////////////////////////////////////////////////////////////////////////
615 void storeFileHeader(FILE* fp)
619 memset(&fileHdr, 0, sizeof(FILE_HEADER));
621 fileHdr.endianType = getCPU_Endian();
622 fileHdr.dummy32 = 2818049;
623 fileHdr.END_MARKER = 0xFFFF;
624 strncpy(fileHdr.szTimeZone, tzname[0], RLOG_TIME_ZONE_LEN);
626 fileHdr.time_sec = time(NULL);
627 if( fwrite((const void*)&fileHdr, 1, sizeof(FILE_HEADER), fp) == -1 )
629 #ifdef RLOG_DEBUG_MODE
630 fprintf(stderr, "Failed to write file header\n");
637 ///////////////////////////////////////////////////////////////////////////////////////////////////
638 // @param[in] fileName - Log File Name
639 // @brief This function creates a log file. If log file name is stdout & text logging is enabled,
640 // file pointer is initialized to standard output. This function also creates thread on which
641 // remote application can connect & receive binary logs. If circular buffer is enabled, it creates
642 // thread key, which is used to store & retrieve thread specific buffers and data.
643 ///////////////////////////////////////////////////////////////////////////////////////////////////
644 void rlInitLog(U8 type)
647 /* Initilize the signal handler */
648 rlSigHandler = &rlCatchSegViolation;
650 signal(SIGSEGV, rlCatchSegViolation);
651 signal(SIGBUS, rlCatchSegViolation);
652 signal(SIGINT, flushData);
654 /* set rate limit count for L3 Logs */
655 g_maxRlogCount = RLOG_LIMIT_L3_COUNT;
657 #ifdef RLOG_DEBUG_MODE
658 rlPrintConfiguration();
659 #endif /* RLOG_DEBUG_MODE */
661 #if RLOG_ALLOW_CONSOLE_LOGS
662 if( !strcmp(g_fileName, "stdout")) {
668 #ifndef RLOG_ENABLE_TEXT_LOGGING
670 printf("\n IP Type before reader thread spawn [%d]\n",type);
671 /* Allocate circular buffer */
674 if( pthread_create(&tid, NULL, &rLogServer, NULL) != 0 ) {
675 fprintf(stderr, "Failed to initialize log server thread\n");
680 rlInitPlatformSpecific();
682 #ifdef RLOG_USE_CIRCULAR_BUFFER
685 pthread_mutex_init(&g_logmutex, NULL);
686 if( pthread_create(&tid, NULL, &cirBufReaderThread, NULL) != 0 ) {
687 fprintf(stderr, "Failed to initialize log server thread\n");
690 /* Initialize single circular buffer for all threads */
691 g_pSingCirBuff = rlRegisterThread("DUMMY");
701 //////////////////////////////////////////////////////////////////////////
702 // @Function : rlInitL2Log
703 // @Discription : This will be trigigered from cl init function to
704 // allocate buffer from shared memory and to intialize
708 //////////////////////////////////////////////////////////////////////////
709 void rlInitL2Log(void)
712 /* set rate limit count for L3 Logs */
713 g_maxRlogCount = RLOG_LIMIT_L2_COUNT;
715 #ifndef RLOG_ENABLE_TEXT_LOGGING
716 /* Initialise memory to write logs in L2. This is soc specific
717 function present in soc file. */
718 rlInitL2SocSpecific();
722 /* This is used to initialize global variable at L2 */
726 #endif /* Binary Logging */
730 #ifndef RLOG_ENABLE_TEXT_LOGGING
731 ///////////////////////////////////////////////////////////////////////////////////////////////////
732 // @param[in] arg - Input thread argument - IP Address type.
733 // @brief This is log server thread which listens on configred port. This allows user to connect to
734 // log server and view log data live.
735 ///////////////////////////////////////////////////////////////////////////////////////////////////
736 void* rLogServer(void* arg)
738 CmInetCmnSockAddr serv_addr;
739 CmInetCmnSockAddr cli_addr;
743 int domain = AF_INET;
744 memset((void*)&serv_addr, 0, sizeof(serv_addr));
747 if(gIpType == CM_IPV4ADDR_TYPE)
750 printf("Initializing RLOG for IPV4- %ld\n",gIpType);
752 printf("Initializing RLOG for IPV4- %d\n",gIpType);
754 clilen = serv_addr.len = sizeof(struct sockaddr_in);
756 serv_addr.type = CM_IPV4ADDR_TYPE;
757 serv_addr.u.addr.sin_family = AF_INET;
758 serv_addr.u.addr.sin_addr.s_addr = INADDR_ANY;
759 serv_addr.u.addr.sin_port = htons(g_nLogPort);
764 printf("Initializing RLOG for IPV6 - %ld\n",gIpType);
766 printf("Initializing RLOG for IPV6 - %d\n",gIpType);
768 #ifdef IPV6_SUPPORTED
769 if(gIpType == CM_IPV6ADDR_TYPE)
771 clilen = serv_addr.len = sizeof(struct sockaddr_in6);
773 serv_addr.type = CM_IPV6ADDR_TYPE;
774 serv_addr.u.addr6.sin6_family = AF_INET6;
775 serv_addr.u.addr6.sin6_addr = in6addr_any;
776 serv_addr.u.addr6.sin6_port = htons(g_nLogPort);
780 if( (sockfd = socket(domain, SOCK_STREAM, 0)) < 0 ) {
781 fprintf(stderr, "RLOG: Failed to create socket\n");
785 if( bind(sockfd, (struct sockaddr*)&(serv_addr.u),serv_addr.len) < 0 ) {
786 fprintf(stderr, "RLOG: Error in Binding\n");
795 newsockfd = accept(sockfd, (struct sockaddr*)&(cli_addr.u), (socklen_t *) &clilen);
796 if( newsockfd < 0 ) {
797 fprintf(stderr, "RLOG: Error on accept\n");
802 /* If remote logging is disabled or there is already 1 client connected */
803 if( g_bRemoteLoggingDisabled || g_nCliSocket ) {
804 /* close the new connection and proceed */
805 closeConnection(newsockfd);
809 g_nCliSocket = newsockfd;
815 ///////////////////////////////////////////////////////////////////////////////////////////////////
818 ///////////////////////////////////////////////////////////////////////////////////////////////////
819 void closeConnection(int sockfd)
821 shutdown(sockfd, SHUT_RDWR);
827 ///////////////////////////////////////////////////////////////////////////////////////////////////
830 ///////////////////////////////////////////////////////////////////////////////////////////////////
831 void handleSigIO(int sig)
835 if( read(0, &ch, 1) <= 0 )
838 rlHandleConInput(ch);
841 ///////////////////////////////////////////////////////////////////////////////////////////////////
844 ///////////////////////////////////////////////////////////////////////////////////////////////////
845 int rlHandleConInput(char ch)
847 if( ch == RLOG_CTRL_L ) {
849 g_action = RLOG_SET_LOGLEVEL;
850 fprintf(stderr, "\nEnter new log level:");
854 if( ch == RLOG_CTRL_Y ) {
856 g_action = RLOG_SET_MODMASK;
857 fprintf(stderr, "\nEnter module number:");
861 if( ch == RLOG_ENTER_KEY && g_action ) {
862 g_keyBuf[g_kIdx] = '\0';
868 g_keyBuf[g_kIdx] = ch;
875 ///////////////////////////////////////////////////////////////////////////////////////////////////
878 ///////////////////////////////////////////////////////////////////////////////////////////////////
881 unsigned int val = atol(g_keyBuf);
885 case RLOG_SET_LOGLEVEL:
887 if( val >= L_MAX_LOG_LEVEL )
888 fprintf(stderr, "Invalid log level\n");
893 rlSetLogLevel((R_LOG_LEVEL)val);
894 fprintf(stderr, "New Log level is %s\n", g_logStr[val]);
897 fprintf(stderr, "Log level below L_ERROR is not allowed\n");
902 case RLOG_SET_MODMASK:
904 rlSetModuleMask(val);
905 fprintf(stderr, "Toggled log mask %d\n", val);
915 ///////////////////////////////////////////////////////////////////////////////////////////////////
918 ///////////////////////////////////////////////////////////////////////////////////////////////////
919 void rlCatchSegViolation(int sig)
921 int i, nStrLen, nDepth;
923 void *stackTraceBuf[RLOG_MAX_STACK_DEPTH];
924 const char* sFileNames[RLOG_MAX_STACK_DEPTH];
925 const char* sFunctions[RLOG_MAX_STACK_DEPTH];
927 char **strings; char buf[RLOG_MAX_STACK_DEPTH*128]={0};
928 #ifdef T2K_MEM_LEAK_DBG
929 DumpT2kMemLeakInfoToFile();
931 #ifdef SSI_STATIC_MEM_LEAK_DETECTION
932 DumpStaticMemLeakFiles();
935 nDepth = backtrace(stackTraceBuf, RLOG_MAX_STACK_DEPTH);
938 strings = (char**) backtrace_symbols(stackTraceBuf, nDepth);
940 for(i = 0, nStrLen=0; i < nDepth; i++)
942 sFunctions[i] = (strings[i]);
943 sFileNames[i] = "unknown file";
945 #ifndef RLOG_ENABLE_TEXT_LOGGING
946 logLevS(L_SIGSEGV, L_FATAL, strings[i]);
948 printf("BT[%d] : len [%ld]: %s\n",i, (PTR)strlen(sFunctions[i]),strings[i]);
949 sprintf(buf+nStrLen, " in Function %s (from %s)\n", sFunctions[i], sFileNames[i]);
950 nStrLen += strlen(sFunctions[i]) + strlen(sFileNames[i]) + 15;
953 #ifdef RLOG_ENABLE_TEXT_LOGGING
954 logLevS(g_logStr[L_FATAL], "RLOG", "NULL", 0, FMTSTR RLOG_SEGFAULT_STR, buf);
957 logLevS(L_SIGSEGV, L_FATAL, buf);
963 ///////////////////////////////////////////////////////////////////////////////////////////////////
966 ///////////////////////////////////////////////////////////////////////////////////////////////////
967 void flushData(int sig)
969 #ifdef RLOG_USE_CIRCULAR_BUFFER
970 readCircularBuffers();
972 g_rlogWriteCount = 0;
978 signal(sig, SIG_DFL);
989 ///////////////////////////////////////////////////////////////////////////////////////////////////
992 ///////////////////////////////////////////////////////////////////////////////////////////////////
994 #ifdef RLOG_ENABLE_TEXT_LOGGING
996 #define TIME_PARAMS tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900,tm->tm_hour, tm->tm_min,tm->tm_sec,microseconds
998 ///////////////////////////////////////////////////////////////////////////////////////////////////
1001 ///////////////////////////////////////////////////////////////////////////////////////////////////
1002 void logLevS(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR str, ...)
1006 struct tm* tm = getTime(µseconds);
1007 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, str);
1012 ///////////////////////////////////////////////////////////////////////////////////////////////////
1015 ///////////////////////////////////////////////////////////////////////////////////////////////////
1016 void logLevH(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR hexdump, int hexlen, ...)
1019 char szHex[MAX_LOG_BUF_SIZE*3];
1021 struct tm* tm = getTime(µseconds);
1022 hextostr(szHex, hexdump, hexlen);
1023 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, szHex);
1028 ///////////////////////////////////////////////////////////////////////////////////////////////////
1031 ///////////////////////////////////////////////////////////////////////////////////////////////////
1032 void logLevE(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, R_SPL_ARG splType,
1033 U32 splVal, U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1037 struct tm* tm = getTime(µseconds);
1038 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, g_splStr[splType], splVal,
1039 arg1, arg2, arg3, arg4);
1043 ///////////////////////////////////////////////////////////////////////////////////////////////////
1046 ///////////////////////////////////////////////////////////////////////////////////////////////////
1047 void logLev0(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, ...)
1051 struct tm* tm = getTime(µseconds);
1052 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel);
1057 ///////////////////////////////////////////////////////////////////////////////////////////////////
1060 ///////////////////////////////////////////////////////////////////////////////////////////////////
1061 void logLev1(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32 arg1, ...)
1065 struct tm* tm = getTime(µseconds);
1066 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1);
1071 ///////////////////////////////////////////////////////////////////////////////////////////////////
1074 ///////////////////////////////////////////////////////////////////////////////////////////////////
1075 void logLev2(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32 arg1, U32 arg2, ...)
1079 struct tm* tm = getTime(µseconds);
1080 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2);
1085 ///////////////////////////////////////////////////////////////////////////////////////////////////
1088 ///////////////////////////////////////////////////////////////////////////////////////////////////
1089 void logLev3(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr,
1090 U32 arg1, U32 arg2, U32 arg3, ...)
1094 struct tm* tm = getTime(µseconds);
1095 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2, arg3);
1100 ///////////////////////////////////////////////////////////////////////////////////////////////////
1103 ///////////////////////////////////////////////////////////////////////////////////////////////////
1104 void logLev4(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr,
1105 U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1109 struct tm* tm = getTime(µseconds);
1110 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2, arg3, arg4);
1115 ///////////////////////////////////////////////////////////////////////////////////////////////////
1118 ///////////////////////////////////////////////////////////////////////////////////////////////////
1119 void logLevN(int logLevel, const char* modName, const char* file, int lineno, const char* fmtStr, ...)
1122 char szTime[RLOG_MAX_TIME_STAMP];
1123 char szLog1[MAX_LOG_LEN], szLog2[MAX_LOG_LEN];
1125 getLogTimeStr(szTime);
1126 snprintf(szLog1, MAX_LOG_LEN, "[%s][%s]%s:%d\n%s:", szTime, modName, file, lineno, g_logStr[logLevel]);
1128 va_start(argList,fmtStr);
1129 vsnprintf(szLog2, MAX_LOG_LEN, fmtStr, argList);
1132 fprintf(g_fp, "%s%s",szLog1, szLog2);
1136 #else /* BINARY LOGGING */
1138 #define RLOG_SAVE_TIME(_logTime) _logTime.ms_tti=numTtiTicks;
1140 void saveLogDataFromCpul(const void* buf, U16 len)
1142 #ifdef RLOG_USE_CIRCULAR_BUFFER
1143 THREAD_DATA* p = (THREAD_DATA*) g_pSingCirBuff;
1145 if( (p->logBufLen+len) > g_cirMaxBufferSize )
1147 S32 tempLen = g_cirMaxBufferSize - p->logBufLen;
1148 S32 remlen = len-tempLen;
1149 if ((tempLen < 0) || (remlen < 0))
1155 g_rlogPositionIndex = 0;
1156 g_prevLogOffset = 0;
1160 g_rlogPositionIndex = remlen/50;
1163 /* we are unlikely to hit this condition, but to prevent corruption of binary logs */
1164 /* we cannot write the data, if we write, data will be corrected forever */
1165 if( remlen > p->logReadPos )
1167 fprintf(stderr, "cannot write data.retune buffer parameters\n");
1170 if( (p->logReadPos - remlen) < RLOG_READ_POS_THRESHOLD && !thread_signalled )
1172 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1176 /* Copy data till end of the buffer */
1177 memcpy(p->logBuff+p->logBufLen, buf, tempLen);
1178 /* Copy remaining data from the start of buffer */
1179 memcpy(p->logBuff, ((const U8 *)buf)+tempLen, remlen);
1180 /* Store buffer length position */
1181 p->logBufLen = len-tempLen;
1185 /* if reader is far behind and writer is reaching reader position, diff < 5Kb */
1186 /* its time to wakeup thread if reader has not read much of data */
1187 if( p->logReadPos > p->logBufLen && (p->logReadPos - p->logBufLen) < RLOG_READ_POS_THRESHOLD && !thread_signalled )
1188 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1190 g_rlogPositionIndex += (len/50);
1191 memcpy(p->logBuff+p->logBufLen, buf, len);
1192 p->logBufLen += len;
1195 /* Directly write received buffer in cpuh log file */
1196 if( fwrite((const void*)buf, 1, len, g_fp) == -1 )
1198 #ifdef RLOG_DEBUG_MODE
1199 fprintf(stderr, "Failed to write log data in file\n");
1208 void saveLogData(const void* buf, U16 len, U32 g_rlogWritePosIndex)
1211 ++g_rlogWriteCount ;
1213 if((1 == g_writeCirBuf) ||
1214 ((g_rlLogCntLimit == RL_LOG_COUNT_LIMIT_START) &&
1215 (g_rlogWriteCount > g_maxRlogCount)) ||
1216 (len > RLOG_FIXED_LENGTH_BUFFER_SIZE))
1218 g_rlogPositionIndex --;
1223 /* check for if L2 is going to store logs */
1224 if (SFndProcId() == TENB_L2_PROC_ID)
1226 if((g_l2LogBufLen + RLOG_FIXED_LENGTH_BUFFER_SIZE) < L2LOG_BUFF_BLOCK_SIZE - sizeof(g_l2LogBufLen) )
1228 /* copying logs in shared buffer */
1229 memcpy(g_l2LogBufStartPtr, buf, len);
1231 g_l2LogBufStartPtr += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1232 /* increasing total log length with L2 log length */
1233 g_l2LogBufLen += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1237 #ifdef RLOG_USE_CIRCULAR_BUFFER
1238 U32 logWritePointerPosition;
1239 THREAD_DATA* p = (THREAD_DATA*) g_pSingCirBuff;
1241 /* if buffer is about to full, write till end and continue writing from begining */
1242 if( ((g_rlogWritePosIndex+1) * RLOG_FIXED_LENGTH_BUFFER_SIZE) > g_cirMaxBufferSize )
1244 /* setting this flag to 1 to avoid other threads
1245 to write in same circular buffer */
1247 /* Start globalPositionIndex again */
1248 g_rlogPositionIndex = 0;
1250 /* if reader has not read initial data, minmum buffer size should be 100Kb */
1251 if( p->logReadPos < RLOG_READ_POS_THRESHOLD && !thread_signalled ) {
1252 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1255 /* we are unlikely to hit this condition, but to prevent corruption of binary logs */
1256 /* we cannot write the data, if we write, data will be corrected forever */
1257 if( RLOG_FIXED_LENGTH_BUFFER_SIZE > p->logReadPos ) {
1258 fprintf(stderr, "cannot write data.retune buffer parameters\n");
1262 /* Copy data from the start of buffer */
1263 memcpy(p->logBuff, buf, len);
1264 /* Store buffer length position */
1265 p->logBufLen = RLOG_FIXED_LENGTH_BUFFER_SIZE;
1266 g_prevLogOffset = 0;
1267 /* setting this flag to 0 so that other threads
1268 will start writing in circular buffer */
1273 /* if reader is far behind and writer is reaching reader position, diff < 5Kb */
1274 /* its time to wakeup thread if reader has not read much of data */
1275 if( p->logReadPos > p->logBufLen && (p->logReadPos - p->logBufLen) < RLOG_READ_POS_THRESHOLD )
1276 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1278 logWritePointerPosition = (g_rlogWritePosIndex * RLOG_FIXED_LENGTH_BUFFER_SIZE) + g_prevLogOffset;
1280 memcpy(p->logBuff+logWritePointerPosition, buf, len);
1281 p->logBufLen += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1283 #else /* !RLOG_USE_CIRCULAR_BUFFER */
1284 if( fwrite((const void*)buf, 1, RLOG_FIXED_LENGTH_BUFFER_SIZE, g_fp) == -1 )
1286 #ifdef RLOG_DEBUG_MODE
1287 fprintf(stderr, "Failed to write log data in file\n");
1292 #endif /* RLOG_USE_CIRCULAR_BUFFER */
1296 /* If post processor connected send logs */
1297 if( g_nCliSocket && send(g_nCliSocket, buf, RLOG_FIXED_LENGTH_BUFFER_SIZE, 0 ) == -1 ) {
1298 closeConnection(g_nCliSocket);
1302 #ifdef RLOG_DEBUG_MODE_2
1304 static int maxlen = 0;
1307 fprintf(stderr, "MAX BUFFER SIZE is binary mode is [%d]\n", maxlen);
1315 void storeTimeDelimeter(FILE* fp)
1318 logData.logId = L_TIME_DELIMITER;
1319 logData.argType = 0;
1320 logData.logLevel = 0;
1321 logData.numOfArgs = 0;
1325 void sendToPostProcessor(const void* buf, U16 len)
1327 if( send(g_nCliSocket, buf, len, 0 ) == -1 ) {
1328 perror("ERROR Sending");
1329 closeConnection(g_nCliSocket);
1333 void logLevS( LOGID logId, R_LOG_LEVEL logLevel, const char* str, ...)
1335 ARGDATA arg; U16 bufsize;
1338 RLOG_SAVE_TIME(arg.logData.logTime);
1340 arg.logData.logId = logId;
1341 arg.logData.argType = LOG_ARG_STR;
1342 arg.logData.logLevel = logLevel;
1343 arg.logData.numOfArgs = 1;
1344 arg.logData.len = strlen(str);
1346 memcpy(arg.buf, (const void*)str, arg.logData.len);
1347 bufsize = sizeof(LOGDATA)+arg.logData.len;
1349 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1352 void logLevH( LOGID logId, R_LOG_LEVEL logLevel, PSTR hex, int hexlen, ...)
1357 RLOG_SAVE_TIME(arg.logData.logTime);
1359 arg.logData.logId = logId;
1360 arg.logData.argType = LOG_ARG_HEX;
1361 arg.logData.logLevel = logLevel;
1362 arg.logData.numOfArgs = 1;
1363 arg.logData.len = hexlen;
1365 memcpy(arg.buf, (const void*)hex, hexlen);
1366 bufsize = sizeof(LOGDATA)+arg.logData.len;
1368 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1370 void logLevE(LOGID logId, R_LOG_LEVEL logLevel, R_SPL_ARG splType, U32 splVal, U32 arg1, U32 arg2,
1371 U32 arg3, U32 arg4, ...)
1376 RLOG_SAVE_TIME(arg.logData.logTime);
1378 arg.logData.logId = logId;
1379 arg.logData.argType = LOG_ARG_SPL;
1380 arg.logData.logLevel = logLevel;
1382 arg.logData.numOfArgs = (arg2 == 0 ) ? 1 : (arg3==0 ? 2 : (arg4==0 ? 3 : 4));
1384 arg.logData.numOfArgs = 0;
1387 arg.logData.len = sizeof(u_int8_t) + sizeof(U32) + (sizeof(U32)*arg.logData.numOfArgs);
1389 arg.splEnum = splType;
1390 arg.splArg = splVal;
1396 bufsize = sizeof(LOGDATA)+arg.logData.len;
1398 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1401 void logLev0( LOGID logId, R_LOG_LEVEL logLevel, ...)
1406 RLOG_SAVE_TIME(arg.logData.logTime);
1408 arg.logData.logId = logId;
1409 arg.logData.argType = LOG_ARG_STR;
1410 arg.logData.logLevel = logLevel;
1411 arg.logData.numOfArgs = 0;
1412 arg.logData.len = 0;
1414 saveLogData((const void*)&arg, sizeof(LOGDATA),g_rlogPositionIndex++);
1417 void logLev1( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, ...)
1422 RLOG_SAVE_TIME(arg.logData.logTime);
1424 arg.logData.logId = logId;
1425 arg.logData.argType = LOG_ARG_INT;
1426 arg.logData.logLevel = logLevel;
1427 arg.logData.numOfArgs = 1;
1428 arg.logData.len = sizeof(U32);
1431 bufsize = sizeof(LOGDATA)+arg.logData.len;
1433 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1435 void logLev2( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, ...)
1440 RLOG_SAVE_TIME(arg.logData.logTime);
1442 arg.logData.logId = logId;
1443 arg.logData.argType = LOG_ARG_INT;
1444 arg.logData.logLevel = logLevel;
1445 arg.logData.numOfArgs = 2;
1446 arg.logData.len = 2 * sizeof(U32);
1451 bufsize = sizeof(LOGDATA)+arg.logData.len;
1453 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1455 void logLev3( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, ...)
1460 RLOG_SAVE_TIME(arg.logData.logTime);
1462 arg.logData.logId = logId;
1463 arg.logData.argType = LOG_ARG_INT;
1464 arg.logData.logLevel = logLevel;
1465 arg.logData.numOfArgs = 3;
1466 arg.logData.len = 3 * sizeof(U32);
1472 bufsize = sizeof(LOGDATA)+arg.logData.len;
1474 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1476 void logLev4( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1480 RLOG_SAVE_TIME(arg.logData.logTime);
1482 arg.logData.logId = logId;
1483 arg.logData.argType = LOG_ARG_INT;
1484 arg.logData.logLevel = logLevel;
1485 arg.logData.numOfArgs = 4;
1486 arg.logData.len = 4 * sizeof(U32);
1493 saveLogData((const void*)&arg, sizeof(ARG4DATA),g_rlogPositionIndex++);
1496 #endif /* BINARY LOGGING */
1498 #if defined(RLOG_ENABLE_TEXT_LOGGING)
1499 struct tm* getTime(int* microseconds)
1502 struct timespec ptime;
1504 struct timeval ptime;
1508 clock_gettime(CLOCK_REALTIME, &ptime);
1509 *microseconds = ptime.tv_nsec / 1000;
1511 gettimeofday(&ptime, NULL);
1512 *microseconds = ptime.tv_usec;
1515 /* Obtain the time of day, and convert it to a tm struct. --*/
1516 return localtime (&ptime.tv_sec);
1518 #elif !defined(RLOG_USE_TTI_LOGGING)
1519 static void getLogTime(LOGTIME* logTime)
1522 struct timespec ptime;
1524 struct timeval ptime;
1528 clock_gettime(CLOCK_REALTIME, &ptime);
1529 logTime->ms_tti = ptime.tv_nsec / 1000;
1531 gettimeofday(&ptime, NULL);
1532 logTime->ms_tti = ptime.tv_usec/1000;
1535 logTime->tv_sec = ptime.tv_sec;
1540 void getLogTimeStr(char* ts)
1543 struct timespec ptime;
1545 struct timeval ptime;
1551 clock_gettime(CLOCK_REALTIME, &ptime);
1552 microseconds = ptime.tv_nsec / 1000;
1554 gettimeofday(&ptime, NULL);
1555 microseconds = ptime.tv_usec/1000;
1558 /* Obtain the time of day, and convert it to a tm struct. --*/
1559 tm = localtime (&ptime.tv_sec);
1561 if (tm) sprintf(ts,"%d_%d_%d_%d_%d_%d.%03d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
1562 tm->tm_hour, tm->tm_min,tm->tm_sec,microseconds);
1564 ///////////////////////////////////////////////////////////////////////////////////////////////////
1567 ///////////////////////////////////////////////////////////////////////////////////////////////////
1569 void rlEnaBleBufferedIO(void)
1571 setvbuf (g_fp, NULL, _IOFBF, 1024 );
1574 void createNewLogFile()
1576 FILE *fp, *prev_fp = g_fp;
1577 char curTime[RLOG_MAX_TIME_STAMP]; int fd;
1579 /* Fix for CR ccpu00143040 */
1582 /* get current time, when file is created */
1583 getLogTimeStr(curTime);
1584 temptr = strchr(curTime, '.');
1585 if (temptr != NULLP)
1589 /* Fix for CR ccpu00143040 */
1590 dir = opendir(g_logDir);
1593 mkdir(g_logDir, O_RDWR);
1599 /* remove old file from system */
1600 if( g_fileList[g_nCurrFileIdx][0] != '\0' )
1601 unlink(g_fileList[g_nCurrFileIdx]);
1603 #ifdef RLOG_ENABLE_TEXT_LOGGING
1604 /* create file name, Example-> dbglog_2013_08_11_15_30_00 */
1605 snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.txt",g_logDir, g_fileName, curTime );
1606 fp = fopen(g_fileList[g_nCurrFileIdx], "w+");
1608 snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.bin",g_logDir, g_fileName, curTime );
1609 fp = fopen(g_fileList[g_nCurrFileIdx], "ab+");
1613 fprintf(stderr, "Failed to open log file %s\n", g_fileList[g_nCurrFileIdx]);
1622 if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1623 fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1626 #ifdef RLOG_ENABLE_TEXT_LOGGING
1627 setvbuf ( fp , NULL, _IOLBF, 1024 );
1629 setvbuf ( fp , NULL, _IONBF, 1024 );
1632 #ifndef RLOG_ENABLE_TEXT_LOGGING
1633 storeFileHeader(fp);
1636 if( prev_fp != NULL )
1639 if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1642 #ifndef RLOG_ENABLE_TEXT_LOGGING
1643 #ifdef RLOG_USE_TTI_LOGGING
1644 logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));
1649 void createL2LogFile()
1651 FILE *fp, *prev_fp = g_fp;
1653 char file[MAX_FILENAME_LEN];
1655 strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1656 strncpy(g_fileName, "dbglog_l2", MAX_FILENAME_LEN);
1657 snprintf(file, sizeof(file), "%s/%s.txt", g_logDir, g_fileName);
1659 fp = fopen(file, "w+");
1661 printf("Failed to open file %s", file);
1665 printf("Created L2 bin file FD=%s\n", g_fileName);
1667 setvbuf (fp , NULL, _IONBF, 1024 );
1674 if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1675 fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1678 setvbuf ( fp , NULL, _IOLBF, 1024 );
1680 if( prev_fp != NULL )
1683 if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1689 //////////////////////////////////////////////////////////////////////////
1690 // @Function : rlUdateRlogTti
1691 // @Discription : This function will be called every 10 ms whenever
1692 // application layer update the tti count
1695 //////////////////////////////////////////////////////////////////////////
1696 void rlUpdateRlogTti(Void)
1698 #ifndef RLOG_ENABLE_TEXT_LOGGING
1699 #ifdef RLOG_USE_TTI_LOGGING
1700 logLev1(L_TIME_TTI_UPDT, L_ALWAYS, (U32)time(NULL));
1705 /* This function processes log buffer received from L2
1706 mBuf is Received from L2 through SPstTsk. This function
1707 extracts buffer pointer and logLen and then these logs
1708 written to L3 log buffer/file.
1709 This function is called in application layer when EVTL2LOGBUF
1710 event is recieved from ssi
1714 PUBLIC Void rlProcessLogBufFromL2
1719 PUBLIC Void rlProcessLogBufFromL2(mBuf)
1723 #ifndef RLOG_ENABLE_TEXT_LOGGING
1729 printf("NULL MBUF received \n");
1732 /* Get Buffer pointer and length. This is SOC specific function which
1733 will extract Log-Buffer pointer and length from mBuf */
1734 rlGetL2LogBufPtr(mBuf, &logLength,&logPtr);
1735 rlSetL2LogBuf(logPtr,logLength);
1741 /* This function will get tick from RLC/CL and will process logs
1742 according to tick threshold. Tick threshold is SOC specific */
1743 PUBLIC Void rlProcessTicks(void)
1745 static U32 rlogTickCount;
1747 if(++rlogTickCount >= RLOGTICKSCNTTOPRCL2LOGS)
1750 rlResetLogRateLmt(); /* Resetting rlog write count to 0 */
1752 /* Tick count reached configured ticks to send L2 logs,
1753 Send existing log buffer to Application and create
1754 new log buffer to write logs */
1755 if (SFndProcId() == TENB_L2_PROC_ID)
1757 #ifndef RLOG_ENABLE_TEXT_LOGGING
1758 processL2LogBuff(); /* This processing of log buffer is done on L2 only
1759 This is SOC specific function and use to send
1760 log buffers to L3 and reset buffer pointer to
1763 /* Write functions specific to Text logging in cpul */
1768 /* L3 specific functions */
1774 #ifndef RLOG_ENABLE_TEXT_LOGGING
1775 //////////////////////////////////////////////////////////////////////////
1776 // @Function : readL2LogBuff
1777 // @Description : This function first validates received Log Buffer and
1778 // length from L2 and then writes L2 log buffer into L3
1779 // circular buffer. After reading it invalidates cache and
1780 // also resets global Log buffer pointer and lenth variable.
1783 //////////////////////////////////////////////////////////////////////////
1785 PUBLIC Void readL2LogBuff(void)
1787 /* Validate global buffer pointer and length */
1789 ret = rlValidateL2LogBuf();
1792 printf(" Validation failed for log buffer/len \n");
1796 saveLogDataFromCpul(g_logBufRcvdFromL2 , g_logBufLenRcvdFromL2 );
1797 /* TODO: Write SOC Specific function to invalidate cache */
1798 rlInvalidateL2LogsInCache(g_logBufRcvdFromL2 - sizeof(g_logBufLenRcvdFromL2) , (g_logBufLenRcvdFromL2 + sizeof(g_logBufLenRcvdFromL2)));
1804 //////////////////////////////////////////////////////////////////////////
1805 // @Function : rlStopLogCountLimit
1806 // @Description : This function validates L2 Log buffer,length, and start
1810 //////////////////////////////////////////////////////////////////////////
1813 PUBLIC S16 rlValidateL2LogBuf(void)
1815 PUBLIC S16 rlValidateL2LogBuf(void)
1819 if(g_logBufRcvdFromL2 == NULL)
1821 printf("Log-Buffer received from L2 is NULL \n");
1824 if(g_logBufLenRcvdFromL2 == 0)
1826 printf("Log-Buffer Length received from L2 is 0 \n");
1829 if(startL2Logging == 0)
1831 printf("startL2Logging flag is still inactive \n");
1838 //////////////////////////////////////////////////////////////////////////
1839 // @Function : rlStopLogCountLimit
1840 // @Description : This function set global log Buffer pointer & length
1841 // @in : l2LogBuf - Log Buffer to be set in global pointer
1842 // l2LogLen - Log length to be set in global lenth
1844 //////////////////////////////////////////////////////////////////////////
1847 PUBLIC void rlSetL2LogBuf
1853 PUBLIC void rlSetL2LogBuf(l2LogBuf,l2logLen)
1858 g_logBufRcvdFromL2 = l2LogBuf;
1859 g_logBufLenRcvdFromL2 = l2logLen;
1862 //////////////////////////////////////////////////////////////////////////
1863 // @Function : rlStopLogCountLimit
1864 // @Description : This function flushes global log Buffer pointer & length
1867 //////////////////////////////////////////////////////////////////////////
1870 PUBLIC void rlResetL2LogBuf
1875 PUBLIC void rlResetL2LogBuf(void)
1878 g_logBufRcvdFromL2 = NULL;
1879 g_logBufLenRcvdFromL2 = 0;
1884 //////////////////////////////////////////////////////////////////////////
1885 // @Function : rlStartLogCountLimit
1886 // @Discription : This function will be called by EnbApp after Cell is UP.
1887 // This function start the log cnt limit. i.e Number of logs
1888 // getting logged into curcular will be restricted to 100 logs.
1891 //////////////////////////////////////////////////////////////////////////
1893 void rlStartLogCountLimit(Void)
1895 g_rlogWriteCount = 0;
1896 g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_START;
1897 printf("Start Log Restriction\n");
1900 //////////////////////////////////////////////////////////////////////////
1901 // @Function : rlStopLogCountLimit
1902 // @Discription : This function will be called by EnbApp after Cell Shutdown
1903 // is triggered. This will enable to get all logs of shutdown.
1904 // This function stops the log cnt limit. i.e Restricition on
1905 // Number of logs getting logged into curcular will be removed
1908 //////////////////////////////////////////////////////////////////////////
1910 void rlStopLogCountLimit(Void)
1912 printf("Stop Log Restriction\n");
1913 g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
1916 //////////////////////////////////////////////////////////////////////////
1917 // @Function : rlResetLogRateLmt
1918 // @Discription : This function will be called every 10 ms whenever
1919 // application layer update the tti count. To reset the
1920 // log rate control. And Enable logging for next 10 ms
1923 //////////////////////////////////////////////////////////////////////////
1925 void rlResetLogRateLmt(void)
1927 g_rlogWriteCount = 0;
1931 void initGlbDataAtL2(void)
1933 strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1936 /**********************************************************************
1938 **********************************************************************/