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