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 <<
"(): "
Stream buffer class that will use the YUILog's logger function.
std::streamsize writeBuffer(const char *sequence, std::streamsize seqLen)
Write (no more than maxLength characters of) a sequence of characters and return the number of charac...
virtual ~YUILogBuffer()
Destructor.
virtual std::streamsize xsputn(const char *sequence, std::streamsize maxLength)
Write (no more than maxLength characters of) a sequence of characters and return the number of charac...
void flush()
Flush the output buffer: Write any data unwritten so far.
virtual int overflow(int ch=EOF)
Write one character in case of buffer overflow.
YUILogBuffer()
Constructor.
static std::ostream & debug(const char *logComponent, const char *sourceFileName, int lineNo, const char *functionName)
Logging functions for each log level.
static bool debugLoggingEnabled()
Return 'true' if debug logging is enabled, 'false' if not.
static YUIEnableDebugLoggingFunction enableDebugLoggingHook()
Return the hook function that enables or disables debug logging or 0 if no such hook function is set.
static std::string basename(const std::string &fileNameWithPath)
Return the base name without path from a file name with path.
std::ostream & log(YUILogLevel_t logLevel, const char *logComponent, const char *sourceFileName, int lineNo, const char *functionName)
Generic log function.
static void setLoggerFunction(YUILoggerFunction loggerFunction)
Set the UI logger function.
static YUIDebugLoggingEnabledFunction debugLoggingEnabledHook()
Return the hook function that checks if debug logging is enabled or 0 if no such hook function is set...
static void setEnableDebugLoggingHooks(YUIEnableDebugLoggingFunction enableFunction, YUIDebugLoggingEnabledFunction isEnabledFunction)
Set the hook functions to enable/disable debug logging and to query if debug logging is enabled:
static void enableDebugLogging(bool debugLogging=true)
Enable or disable debug logging.
static std::string logFileName()
Return the current log file name or an empty string if stderr is used.
static YUILoggerFunction loggerFunction(bool returnStdLogger=false)
Return the UI logger function.
static bool setLogFileName(const std::string &logFileName)
Set the log file name to be used with the standard logger function.
static YUILog * instance()
Return the singleton object for this class.
Helper class: Per-thread logging information.
YPerThreadLogInfo()
Constructor.
~YPerThreadLogInfo()
Destructor.
bool isThread(pthread_t otherThreadHandle)
Check if this per-thread logging information belongs to the specified thread.
YPerThreadLogInfo * findCurrentThread()
Find the per-thread logging information for the current thread.
~YUILogPrivate()
Destructor.
YUILogPrivate()
Constructor.