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);
1314 void sendToPostProcessor(const void* buf, U16 len)
1316 if( send(g_nCliSocket, buf, len, 0 ) == -1 ) {
1317 perror("ERROR Sending");
1318 closeConnection(g_nCliSocket);
1322 void logLevS( LOGID logId, R_LOG_LEVEL logLevel, const char* str, ...)
1324 ARGDATA arg; U16 bufsize;
1327 RLOG_SAVE_TIME(arg.logData.logTime);
1329 arg.logData.logId = logId;
1330 arg.logData.argType = LOG_ARG_STR;
1331 arg.logData.logLevel = logLevel;
1332 arg.logData.numOfArgs = 1;
1333 arg.logData.len = strlen(str);
1335 memcpy(arg.buf, (const void*)str, arg.logData.len);
1336 bufsize = sizeof(LOGDATA)+arg.logData.len;
1338 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1341 void logLevH( LOGID logId, R_LOG_LEVEL logLevel, PSTR hex, int hexlen, ...)
1346 RLOG_SAVE_TIME(arg.logData.logTime);
1348 arg.logData.logId = logId;
1349 arg.logData.argType = LOG_ARG_HEX;
1350 arg.logData.logLevel = logLevel;
1351 arg.logData.numOfArgs = 1;
1352 arg.logData.len = hexlen;
1354 memcpy(arg.buf, (const void*)hex, hexlen);
1355 bufsize = sizeof(LOGDATA)+arg.logData.len;
1357 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1359 void logLevE(LOGID logId, R_LOG_LEVEL logLevel, R_SPL_ARG splType, U32 splVal, U32 arg1, U32 arg2,
1360 U32 arg3, U32 arg4, ...)
1365 RLOG_SAVE_TIME(arg.logData.logTime);
1367 arg.logData.logId = logId;
1368 arg.logData.argType = LOG_ARG_SPL;
1369 arg.logData.logLevel = logLevel;
1371 arg.logData.numOfArgs = (arg2 == 0 ) ? 1 : (arg3==0 ? 2 : (arg4==0 ? 3 : 4));
1373 arg.logData.numOfArgs = 0;
1376 arg.logData.len = sizeof(u_int8_t) + sizeof(U32) + (sizeof(U32)*arg.logData.numOfArgs);
1378 arg.splEnum = splType;
1379 arg.splArg = splVal;
1385 bufsize = sizeof(LOGDATA)+arg.logData.len;
1387 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1390 void logLev0( LOGID logId, R_LOG_LEVEL logLevel, ...)
1395 RLOG_SAVE_TIME(arg.logData.logTime);
1397 arg.logData.logId = logId;
1398 arg.logData.argType = LOG_ARG_STR;
1399 arg.logData.logLevel = logLevel;
1400 arg.logData.numOfArgs = 0;
1401 arg.logData.len = 0;
1403 saveLogData((const void*)&arg, sizeof(LOGDATA),g_rlogPositionIndex++);
1406 void logLev1( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, ...)
1411 RLOG_SAVE_TIME(arg.logData.logTime);
1413 arg.logData.logId = logId;
1414 arg.logData.argType = LOG_ARG_INT;
1415 arg.logData.logLevel = logLevel;
1416 arg.logData.numOfArgs = 1;
1417 arg.logData.len = sizeof(U32);
1420 bufsize = sizeof(LOGDATA)+arg.logData.len;
1422 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1424 void logLev2( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, ...)
1429 RLOG_SAVE_TIME(arg.logData.logTime);
1431 arg.logData.logId = logId;
1432 arg.logData.argType = LOG_ARG_INT;
1433 arg.logData.logLevel = logLevel;
1434 arg.logData.numOfArgs = 2;
1435 arg.logData.len = 2 * sizeof(U32);
1440 bufsize = sizeof(LOGDATA)+arg.logData.len;
1442 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1444 void logLev3( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, ...)
1449 RLOG_SAVE_TIME(arg.logData.logTime);
1451 arg.logData.logId = logId;
1452 arg.logData.argType = LOG_ARG_INT;
1453 arg.logData.logLevel = logLevel;
1454 arg.logData.numOfArgs = 3;
1455 arg.logData.len = 3 * sizeof(U32);
1461 bufsize = sizeof(LOGDATA)+arg.logData.len;
1463 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1465 void logLev4( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1469 RLOG_SAVE_TIME(arg.logData.logTime);
1471 arg.logData.logId = logId;
1472 arg.logData.argType = LOG_ARG_INT;
1473 arg.logData.logLevel = logLevel;
1474 arg.logData.numOfArgs = 4;
1475 arg.logData.len = 4 * sizeof(U32);
1482 saveLogData((const void*)&arg, sizeof(ARG4DATA),g_rlogPositionIndex++);
1485 #endif /* BINARY LOGGING */
1487 #if defined(RLOG_ENABLE_TEXT_LOGGING)
1488 struct tm* getTime(int* microseconds)
1491 struct timespec ptime;
1493 struct timeval ptime;
1497 clock_gettime(CLOCK_REALTIME, &ptime);
1498 *microseconds = ptime.tv_nsec / 1000;
1500 gettimeofday(&ptime, NULL);
1501 *microseconds = ptime.tv_usec;
1504 /* Obtain the time of day, and convert it to a tm struct. --*/
1505 return localtime (&ptime.tv_sec);
1507 #elif !defined(RLOG_USE_TTI_LOGGING)
1508 static void getLogTime(LOGTIME* logTime)
1511 struct timespec ptime;
1513 struct timeval ptime;
1517 clock_gettime(CLOCK_REALTIME, &ptime);
1518 logTime->ms_tti = ptime.tv_nsec / 1000;
1520 gettimeofday(&ptime, NULL);
1521 logTime->ms_tti = ptime.tv_usec/1000;
1524 logTime->tv_sec = ptime.tv_sec;
1529 void getLogTimeStr(char* ts)
1532 struct timespec ptime;
1534 struct timeval ptime;
1540 clock_gettime(CLOCK_REALTIME, &ptime);
1541 microseconds = ptime.tv_nsec / 1000;
1543 gettimeofday(&ptime, NULL);
1544 microseconds = ptime.tv_usec/1000;
1547 /* Obtain the time of day, and convert it to a tm struct. --*/
1548 tm = localtime (&ptime.tv_sec);
1550 if (tm) sprintf(ts,"%d_%d_%d_%d_%d_%d.%03d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
1551 tm->tm_hour, tm->tm_min,tm->tm_sec,microseconds);
1553 ///////////////////////////////////////////////////////////////////////////////////////////////////
1556 ///////////////////////////////////////////////////////////////////////////////////////////////////
1558 void rlEnaBleBufferedIO(void)
1560 setvbuf (g_fp, NULL, _IOFBF, 1024 );
1563 void createNewLogFile()
1565 FILE *fp, *prev_fp = g_fp;
1566 char curTime[RLOG_MAX_TIME_STAMP]; int fd;
1568 /* Fix for CR ccpu00143040 */
1571 /* get current time, when file is created */
1572 getLogTimeStr(curTime);
1573 temptr = strchr(curTime, '.');
1574 if (temptr != NULLP)
1578 /* Fix for CR ccpu00143040 */
1579 dir = opendir(g_logDir);
1582 mkdir(g_logDir, O_RDWR);
1588 /* remove old file from system */
1589 if( g_fileList[g_nCurrFileIdx][0] != '\0' )
1590 unlink(g_fileList[g_nCurrFileIdx]);
1592 #ifdef RLOG_ENABLE_TEXT_LOGGING
1593 /* create file name, Example-> dbglog_2013_08_11_15_30_00 */
1594 snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.txt",g_logDir, g_fileName, curTime );
1595 fp = fopen(g_fileList[g_nCurrFileIdx], "w+");
1597 snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.bin",g_logDir, g_fileName, curTime );
1598 fp = fopen(g_fileList[g_nCurrFileIdx], "ab+");
1602 fprintf(stderr, "Failed to open log file %s\n", g_fileList[g_nCurrFileIdx]);
1611 if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1612 fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1615 #ifdef RLOG_ENABLE_TEXT_LOGGING
1616 setvbuf ( fp , NULL, _IOLBF, 1024 );
1618 setvbuf ( fp , NULL, _IONBF, 1024 );
1621 #ifndef RLOG_ENABLE_TEXT_LOGGING
1622 storeFileHeader(fp);
1625 if( prev_fp != NULL )
1628 if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1631 #ifndef RLOG_ENABLE_TEXT_LOGGING
1632 #ifdef RLOG_USE_TTI_LOGGING
1633 logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));
1638 void createL2LogFile()
1640 FILE *fp, *prev_fp = g_fp;
1642 char file[MAX_FILENAME_LEN];
1644 strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1645 strncpy(g_fileName, "dbglog_l2", MAX_FILENAME_LEN);
1646 snprintf(file, sizeof(file), "%s/%s.txt", g_logDir, g_fileName);
1648 fp = fopen(file, "w+");
1650 printf("Failed to open file %s", file);
1654 printf("Created L2 bin file FD=%s\n", g_fileName);
1656 setvbuf (fp , NULL, _IONBF, 1024 );
1663 if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1664 fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1667 setvbuf ( fp , NULL, _IOLBF, 1024 );
1669 if( prev_fp != NULL )
1672 if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1678 //////////////////////////////////////////////////////////////////////////
1679 // @Function : rlUdateRlogTti
1680 // @Discription : This function will be called every 10 ms whenever
1681 // application layer update the tti count
1684 //////////////////////////////////////////////////////////////////////////
1685 void rlUpdateRlogTti(Void)
1687 #ifndef RLOG_ENABLE_TEXT_LOGGING
1688 #ifdef RLOG_USE_TTI_LOGGING
1689 logLev1(L_TIME_TTI_UPDT, L_ALWAYS, (U32)time(NULL));
1694 /* This function processes log buffer received from L2
1695 mBuf is Received from L2 through SPstTsk. This function
1696 extracts buffer pointer and logLen and then these logs
1697 written to L3 log buffer/file.
1698 This function is called in application layer when EVTL2LOGBUF
1699 event is recieved from ssi
1703 PUBLIC Void rlProcessLogBufFromL2
1708 PUBLIC Void rlProcessLogBufFromL2(mBuf)
1712 #ifndef RLOG_ENABLE_TEXT_LOGGING
1718 printf("NULL MBUF received \n");
1721 /* Get Buffer pointer and length. This is SOC specific function which
1722 will extract Log-Buffer pointer and length from mBuf */
1723 rlGetL2LogBufPtr(mBuf, &logLength,&logPtr);
1724 rlSetL2LogBuf(logPtr,logLength);
1730 /* This function will get tick from RLC/CL and will process logs
1731 according to tick threshold. Tick threshold is SOC specific */
1732 PUBLIC Void rlProcessTicks(void)
1734 static U32 rlogTickCount;
1736 if(++rlogTickCount >= RLOGTICKSCNTTOPRCL2LOGS)
1739 rlResetLogRateLmt(); /* Resetting rlog write count to 0 */
1741 /* Tick count reached configured ticks to send L2 logs,
1742 Send existing log buffer to Application and create
1743 new log buffer to write logs */
1744 if (SFndProcId() == TENB_L2_PROC_ID)
1746 #ifndef RLOG_ENABLE_TEXT_LOGGING
1747 processL2LogBuff(); /* This processing of log buffer is done on L2 only
1748 This is SOC specific function and use to send
1749 log buffers to L3 and reset buffer pointer to
1752 /* Write functions specific to Text logging in cpul */
1757 /* L3 specific functions */
1763 #ifndef RLOG_ENABLE_TEXT_LOGGING
1764 //////////////////////////////////////////////////////////////////////////
1765 // @Function : readL2LogBuff
1766 // @Description : This function first validates received Log Buffer and
1767 // length from L2 and then writes L2 log buffer into L3
1768 // circular buffer. After reading it invalidates cache and
1769 // also resets global Log buffer pointer and lenth variable.
1772 //////////////////////////////////////////////////////////////////////////
1774 PUBLIC Void readL2LogBuff(void)
1776 /* Validate global buffer pointer and length */
1778 ret = rlValidateL2LogBuf();
1781 printf(" Validation failed for log buffer/len \n");
1785 saveLogDataFromCpul(g_logBufRcvdFromL2 , g_logBufLenRcvdFromL2 );
1786 /* TODO: Write SOC Specific function to invalidate cache */
1787 rlInvalidateL2LogsInCache(g_logBufRcvdFromL2 - sizeof(g_logBufLenRcvdFromL2) , (g_logBufLenRcvdFromL2 + sizeof(g_logBufLenRcvdFromL2)));
1793 //////////////////////////////////////////////////////////////////////////
1794 // @Function : rlStopLogCountLimit
1795 // @Description : This function validates L2 Log buffer,length, and start
1799 //////////////////////////////////////////////////////////////////////////
1802 PUBLIC S16 rlValidateL2LogBuf(void)
1804 PUBLIC S16 rlValidateL2LogBuf(void)
1808 if(g_logBufRcvdFromL2 == NULL)
1810 printf("Log-Buffer received from L2 is NULL \n");
1813 if(g_logBufLenRcvdFromL2 == 0)
1815 printf("Log-Buffer Length received from L2 is 0 \n");
1818 if(startL2Logging == 0)
1820 printf("startL2Logging flag is still inactive \n");
1827 //////////////////////////////////////////////////////////////////////////
1828 // @Function : rlStopLogCountLimit
1829 // @Description : This function set global log Buffer pointer & length
1830 // @in : l2LogBuf - Log Buffer to be set in global pointer
1831 // l2LogLen - Log length to be set in global lenth
1833 //////////////////////////////////////////////////////////////////////////
1836 PUBLIC void rlSetL2LogBuf
1842 PUBLIC void rlSetL2LogBuf(l2LogBuf,l2logLen)
1847 g_logBufRcvdFromL2 = l2LogBuf;
1848 g_logBufLenRcvdFromL2 = l2logLen;
1851 //////////////////////////////////////////////////////////////////////////
1852 // @Function : rlStopLogCountLimit
1853 // @Description : This function flushes global log Buffer pointer & length
1856 //////////////////////////////////////////////////////////////////////////
1859 PUBLIC void rlResetL2LogBuf
1864 PUBLIC void rlResetL2LogBuf(void)
1867 g_logBufRcvdFromL2 = NULL;
1868 g_logBufLenRcvdFromL2 = 0;
1873 //////////////////////////////////////////////////////////////////////////
1874 // @Function : rlStartLogCountLimit
1875 // @Discription : This function will be called by EnbApp after Cell is UP.
1876 // This function start the log cnt limit. i.e Number of logs
1877 // getting logged into curcular will be restricted to 100 logs.
1880 //////////////////////////////////////////////////////////////////////////
1882 void rlStartLogCountLimit(Void)
1884 g_rlogWriteCount = 0;
1885 g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_START;
1886 printf("Start Log Restriction\n");
1889 //////////////////////////////////////////////////////////////////////////
1890 // @Function : rlStopLogCountLimit
1891 // @Discription : This function will be called by EnbApp after Cell Shutdown
1892 // is triggered. This will enable to get all logs of shutdown.
1893 // This function stops the log cnt limit. i.e Restricition on
1894 // Number of logs getting logged into curcular will be removed
1897 //////////////////////////////////////////////////////////////////////////
1899 void rlStopLogCountLimit(Void)
1901 printf("Stop Log Restriction\n");
1902 g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
1905 //////////////////////////////////////////////////////////////////////////
1906 // @Function : rlResetLogRateLmt
1907 // @Discription : This function will be called every 10 ms whenever
1908 // application layer update the tti count. To reset the
1909 // log rate control. And Enable logging for next 10 ms
1912 //////////////////////////////////////////////////////////////////////////
1914 void rlResetLogRateLmt(void)
1916 g_rlogWriteCount = 0;
1920 void initGlbDataAtL2(void)
1922 strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1925 /**********************************************************************
1927 **********************************************************************/