33 #define YUILogComponent "ui"
36 #include "YUIException.h"
43 static void stdLogger( YUILogLevel_t logLevel,
44 const char * logComponent,
45 const char * sourceFileName,
47 const char * sourceFunctionName,
48 const char * message );
50 static ostream * stdLogStream = &cerr;
87 virtual std::streamsize
xsputn(
const char * sequence, std::streamsize maxLength );
94 virtual int overflow(
int ch = EOF );
103 std::streamsize
writeBuffer(
const char * sequence, std::streamsize seqLen );
113 YUILogLevel_t logLevel;
114 const char * logComponent;
115 const char * sourceFileName;
117 const char * functionName;
130 buffer += string( sequence, seqLen );
137 size_t newline_pos = 0;
139 while ( start < buffer.length() &&
140 ( newline_pos = buffer.find_first_of(
'\n', start ) ) != string::npos )
144 string line = buffer.substr( start, newline_pos - start );
150 start = newline_pos + 1;
153 if ( start < buffer.length() )
154 buffer = buffer.substr( start, string::npos );
218 : threadHandle( pthread_self() )
220 , logStream( &logBuffer )
238 return pthread_equal( otherThreadHandle, this->threadHandle );
246 pthread_t threadHandle;
260 : loggerFunction( stdLogger )
261 , enableDebugLoggingHook( 0 )
262 , debugLoggingEnabledHook( 0 )
263 , enableDebugLogging( false )
271 for (
unsigned i=0; i < threadLogInfo.size(); i++ )
272 delete threadLogInfo[i];
281 pthread_t thisThread = pthread_self();
287 for ( std::vector<YPerThreadLogInfo *>::reverse_iterator it = threadLogInfo.rbegin();
288 it != threadLogInfo.rend();
291 if ( (*it)->isThread( thisThread ) )
296 threadLogInfo.push_back( newThreadLogInfo );
298 return newThreadLogInfo;
306 std::ofstream stdLogStream;
307 YUILoggerFunction loggerFunction;
308 YUIEnableDebugLoggingFunction enableDebugLoggingHook;
309 YUIDebugLoggingEnabledFunction debugLoggingEnabledHook;
310 bool enableDebugLogging;
312 std::vector<YPerThreadLogInfo *> threadLogInfo;
321 YUI_CHECK_NEW( priv );
327 if ( priv->stdLogStream.is_open() )
328 priv->stdLogStream.close();
352 std::ofstream & logStream =
instance()->priv->stdLogStream;
354 if ( logStream.is_open() )
361 stdLogStream = &cerr;
365 logStream.open(
logFileName.c_str(), std::ios_base::app );
366 success = logStream.good();
370 stdLogStream = &(
instance()->priv->stdLogStream );
374 cerr <<
"ERROR: Can't open log file " <<
logFileName << endl;
375 stdLogStream = &cerr;
386 return instance()->priv->logFileName;
393 instance()->priv->enableDebugLogging = debugLogging;
395 if (
instance()->priv->enableDebugLoggingHook )
396 instance()->priv->enableDebugLoggingHook( debugLogging );
403 if (
instance()->priv->debugLoggingEnabledHook )
404 return instance()->priv->debugLoggingEnabledHook();
406 return instance()->priv->enableDebugLogging;
423 YUILoggerFunction logger =
instance()->priv->loggerFunction;
425 if ( logger == stdLogger && ! returnStdLogger )
434 YUIDebugLoggingEnabledFunction isEnabledFunction )
436 instance()->priv->enableDebugLoggingHook = enableFunction;
437 instance()->priv->debugLoggingEnabledHook = isEnabledFunction;
441 YUIEnableDebugLoggingFunction
444 return instance()->priv->enableDebugLoggingHook;
448 YUIDebugLoggingEnabledFunction
451 return instance()->priv->debugLoggingEnabledHook;
457 const char * logComponent,
458 const char * sourceFileName,
460 const char * functionName )
464 if ( ! threadLogInfo->logBuffer.buffer.empty() )
466 if ( threadLogInfo->logBuffer.logLevel != logLevel ||
467 threadLogInfo->logBuffer.lineNo != lineNo ||
468 strcmp( threadLogInfo->logBuffer.logComponent, logComponent ) != 0 ||
469 strcmp( threadLogInfo->logBuffer.sourceFileName, sourceFileName ) != 0 ||
470 strcmp( threadLogInfo->logBuffer.functionName, functionName ) != 0 )
472 threadLogInfo->logBuffer.
flush();
476 threadLogInfo->logBuffer.logLevel = logLevel;
477 threadLogInfo->logBuffer.logComponent = logComponent;
478 threadLogInfo->logBuffer.sourceFileName = sourceFileName;
479 threadLogInfo->logBuffer.lineNo = lineNo;
480 threadLogInfo->logBuffer.functionName = functionName;
482 return threadLogInfo->logStream;
487 YUILog::debug(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
489 return instance()->
log( YUI_LOG_DEBUG, logComponent, sourceFileName, lineNo, functionName );
494 YUILog::milestone(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
496 return instance()->
log( YUI_LOG_MILESTONE, logComponent, sourceFileName, lineNo, functionName );
501 YUILog::warning(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
503 return instance()->
log( YUI_LOG_WARNING, logComponent, sourceFileName, lineNo, functionName );
508 YUILog::error(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
510 return instance()->
log( YUI_LOG_ERROR, logComponent, sourceFileName, lineNo, functionName );
518 size_t lastSlashPos = fileNameWithPath.find_last_of(
'/' );
521 ( lastSlashPos == string::npos ) ?
523 fileNameWithPath.substr( lastSlashPos+1 );
531 stdLogger( YUILogLevel_t logLevel,
532 const char * logComponent,
533 const char * sourceFileName,
535 const char * sourceFunctionName,
536 const char * message )
538 const char * logLevelStr =
"";
549 case YUI_LOG_MILESTONE: logLevelStr =
"_M_";
break;
550 case YUI_LOG_WARNING: logLevelStr =
"WRN";
break;
551 case YUI_LOG_ERROR: logLevelStr =
"ERR";
break;
554 if ( ! logComponent )
557 if ( ! sourceFileName )
558 sourceFileName =
"??";
560 if ( ! sourceFunctionName )
561 sourceFunctionName =
"??";
566 (*stdLogStream) <<
"<" << logLevelStr <<
"> "
567 <<
"[" << logComponent <<
"] "
568 << sourceFileName <<
":" << sourceLineNo <<
" "
569 << sourceFunctionName <<
"(): "