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();
331 static YUILog * instance = 0;
336 YUI_CHECK_NEW( instance );
346 instance()->priv->logFileName = logFileName;
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;
412 instance()->priv->loggerFunction = loggerFunction;
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 <<
"(): " 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.
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.
std::ostream & log(YUILogLevel_t logLevel, const char *logComponent, const char *sourceFileName, int lineNo, const char *functionName)
Generic log function.
virtual ~YUILogBuffer()
Destructor.
bool isThread(pthread_t otherThreadHandle)
Check if this per-thread logging information belongs to the specified thread.
static std::ostream & debug(const char *logComponent, const char *sourceFileName, int lineNo, const char *functionName)
Logging functions for each log level.
YUILogPrivate()
Constructor.
static std::string basename(const std::string &fileNameWithPath)
Return the base name without path from a file name with path.
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.
YPerThreadLogInfo()
Constructor.
static std::string logFileName()
Return the current log file name or an empty string if stderr is used.
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.
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...