33 #define YUILogComponent "ui"
36 #include "YUIException.h"
39 static void stdLogger( YUILogLevel_t logLevel,
40 const char * logComponent,
41 const char * sourceFileName,
43 const char * sourceFunctionName,
44 const char * message );
46 static std::ostream * stdLogStream = &std::cerr;
83 virtual std::streamsize
xsputn(
const char * sequence, std::streamsize maxLength );
90 virtual int overflow(
int ch = EOF );
99 std::streamsize
writeBuffer(
const char * sequence, std::streamsize seqLen );
109 YUILogLevel_t logLevel;
110 const char * logComponent;
111 const char * sourceFileName;
113 const char * functionName;
126 buffer += std::string( sequence, seqLen );
132 std::size_t start = 0;
133 std::size_t newline_pos = 0;
135 while ( start < buffer.length() &&
136 ( newline_pos = buffer.find_first_of(
'\n', start ) ) != std::string::npos )
140 std::string line = buffer.substr( start, newline_pos - start );
146 start = newline_pos + 1;
149 if ( start < buffer.length() )
150 buffer = buffer.substr( start, std::string::npos );
214 : threadHandle( pthread_self() )
216 , logStream( &logBuffer )
234 return pthread_equal( otherThreadHandle, this->threadHandle );
242 pthread_t threadHandle;
244 std::ostream logStream;
256 : loggerFunction( stdLogger )
257 , enableDebugLoggingHook( 0 )
258 , debugLoggingEnabledHook( 0 )
259 , enableDebugLogging( false )
267 for (
unsigned i=0; i < threadLogInfo.size(); i++ )
268 delete threadLogInfo[i];
277 pthread_t thisThread = pthread_self();
283 for ( std::vector<YPerThreadLogInfo *>::reverse_iterator it = threadLogInfo.rbegin();
284 it != threadLogInfo.rend();
287 if ( (*it)->isThread( thisThread ) )
292 threadLogInfo.push_back( newThreadLogInfo );
294 return newThreadLogInfo;
301 std::string logFileName;
302 std::ofstream stdLogStream;
303 YUILoggerFunction loggerFunction;
304 YUIEnableDebugLoggingFunction enableDebugLoggingHook;
305 YUIDebugLoggingEnabledFunction debugLoggingEnabledHook;
306 bool enableDebugLogging;
308 std::vector<YPerThreadLogInfo *> threadLogInfo;
317 YUI_CHECK_NEW( priv );
323 if ( priv->stdLogStream.is_open() )
324 priv->stdLogStream.close();
336 YUI_CHECK_NEW( instance );
348 std::ofstream & logStream =
instance()->priv->stdLogStream;
350 if ( logStream.is_open() )
355 if ( logFileName.empty() )
357 stdLogStream = &std::cerr;
361 logStream.open( logFileName.c_str(), std::ios_base::app );
362 success = logStream.good();
366 stdLogStream = &(
instance()->priv->stdLogStream );
370 std::cerr <<
"ERROR: Can't open log file " << logFileName << std::endl;
371 stdLogStream = &std::cerr;
382 return instance()->priv->logFileName;
389 instance()->priv->enableDebugLogging = debugLogging;
391 if (
instance()->priv->enableDebugLoggingHook )
392 instance()->priv->enableDebugLoggingHook( debugLogging );
399 if (
instance()->priv->debugLoggingEnabledHook )
400 return instance()->priv->debugLoggingEnabledHook();
402 return instance()->priv->enableDebugLogging;
409 if ( ! loggerFunction )
410 loggerFunction = stdLogger;
419 YUILoggerFunction logger =
instance()->priv->loggerFunction;
421 if ( logger == stdLogger && ! returnStdLogger )
430 YUIDebugLoggingEnabledFunction isEnabledFunction )
432 instance()->priv->enableDebugLoggingHook = enableFunction;
433 instance()->priv->debugLoggingEnabledHook = isEnabledFunction;
437 YUIEnableDebugLoggingFunction
440 return instance()->priv->enableDebugLoggingHook;
444 YUIDebugLoggingEnabledFunction
447 return instance()->priv->debugLoggingEnabledHook;
453 const char * logComponent,
454 const char * sourceFileName,
456 const char * functionName )
460 if ( ! threadLogInfo->logBuffer.buffer.empty() )
462 if ( threadLogInfo->logBuffer.logLevel != logLevel ||
463 threadLogInfo->logBuffer.lineNo != lineNo ||
464 strcmp( threadLogInfo->logBuffer.logComponent, logComponent ) != 0 ||
465 strcmp( threadLogInfo->logBuffer.sourceFileName, sourceFileName ) != 0 ||
466 strcmp( threadLogInfo->logBuffer.functionName, functionName ) != 0 )
468 threadLogInfo->logBuffer.
flush();
472 threadLogInfo->logBuffer.logLevel = logLevel;
473 threadLogInfo->logBuffer.logComponent = logComponent;
474 threadLogInfo->logBuffer.sourceFileName = sourceFileName;
475 threadLogInfo->logBuffer.lineNo = lineNo;
476 threadLogInfo->logBuffer.functionName = functionName;
478 return threadLogInfo->logStream;
483 YUILog::debug(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
485 return instance()->
log( YUI_LOG_DEBUG, logComponent, sourceFileName, lineNo, functionName );
490 YUILog::milestone(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
492 return instance()->
log( YUI_LOG_MILESTONE, logComponent, sourceFileName, lineNo, functionName );
497 YUILog::warning(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
499 return instance()->
log( YUI_LOG_WARNING, logComponent, sourceFileName, lineNo, functionName );
504 YUILog::error(
const char * logComponent,
const char * sourceFileName,
int lineNo,
const char * functionName )
506 return instance()->
log( YUI_LOG_ERROR, logComponent, sourceFileName, lineNo, functionName );
514 std::size_t lastSlashPos = fileNameWithPath.find_last_of(
'/' );
516 std::string fileName =
517 ( lastSlashPos == std::string::npos ) ?
519 fileNameWithPath.substr( lastSlashPos+1 );
527 stdLogger( YUILogLevel_t logLevel,
528 const char * logComponent,
529 const char * sourceFileName,
531 const char * sourceFunctionName,
532 const char * message )
534 const char * logLevelStr =
"";
545 case YUI_LOG_MILESTONE: logLevelStr =
"_M_";
break;
546 case YUI_LOG_WARNING: logLevelStr =
"WRN";
break;
547 case YUI_LOG_ERROR: logLevelStr =
"ERR";
break;
550 if ( ! logComponent )
553 if ( ! sourceFileName )
554 sourceFileName =
"??";
556 if ( ! sourceFunctionName )
557 sourceFunctionName =
"??";
562 (*stdLogStream) <<
"<" << logLevelStr <<
"> "
563 <<
"[" << logComponent <<
"] "
564 << sourceFileName <<
":" << sourceLineNo <<
" "
565 << sourceFunctionName <<
"(): "