Equalizer  1.2.1
co/base/log.h
Go to the documentation of this file.
00001 
00002 /* Copyright (c) 2005-2011, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00027 #ifndef COBASE_LOG_H
00028 #define COBASE_LOG_H
00029 
00030 #include <co/base/api.h>
00031 
00032 #include <assert.h>
00033 #include <iomanip>
00034 #include <iostream>
00035 #include <sstream>
00036 #include <time.h>
00037 
00038 namespace co
00039 {
00040 namespace base
00041 {
00042     class Clock;
00043     class Lock;
00044 
00046     enum LogLevel
00047     {
00048         LOG_ERROR = 1, 
00049         LOG_WARN,      
00050         LOG_INFO,      
00051         LOG_VERB,      
00052         LOG_ALL
00053     };
00054 
00061     enum LogTopic
00062     {
00063         LOG_PLUGIN = 0x1,        
00064         LOG_CUSTOM = 0x10,       
00065         LOG_ANY    = 0xffffu     
00066     };
00067 
00069     class LogBuffer : public std::streambuf
00070     {
00071     public:
00072         LogBuffer( std::ostream& stream )
00073                 : _line(0), _indent(0), _blocked(0), _noHeader(0),
00074                   _newLine(true), _stream(stream)
00075             { _thread[0] = 0; }
00076         virtual ~LogBuffer() {}
00077 
00078         void indent() { ++_indent; }
00079         void exdent() { --_indent; }
00080 
00081         void disableFlush() { ++_blocked; } // use counted variable to allow
00082         void enableFlush()                  //   nested enable/disable calls
00083             { 
00084                 assert( _blocked );// Too many enableFlush on log stream
00085                 --_blocked;
00086             }
00087 
00088         void disableHeader() { ++_noHeader; } // use counted variable to allow
00089         void enableHeader()  { --_noHeader; } //   nested enable/disable calls
00090 
00091         COBASE_API void setThreadName( const std::string& name );
00092         const char* getThreadName() const { return _thread; }
00093 
00094         void setLogInfo( const char* file, const int line )
00095             { _file = file; _line = line; }
00096 
00097     protected:
00098         virtual int_type overflow( LogBuffer::int_type c );
00099         
00100         virtual int sync();
00101 
00102     private:
00103         LogBuffer( const LogBuffer& );
00104         LogBuffer& operator = ( const LogBuffer& );
00105 
00107         char _thread[12];
00108 
00110         std::string _file;
00111 
00113         int _line;
00114 
00116         int _indent;
00117 
00119         int _blocked;
00120 
00122         int _noHeader;
00123 
00125         bool _newLine;
00126 
00128         std::ostringstream _stringStream;
00129 
00131         std::ostream& _stream;
00132 
00134         static Lock _lock;
00135     };
00136 
00138     class Log : public std::ostream
00139     {
00140     public:
00141 
00142         Log() : std::ostream( &_logBuffer ), _logBuffer( getOutput( )){}
00143         virtual ~Log() { _logBuffer.pubsync(); }
00144 
00145         void indent() { _logBuffer.indent(); }
00146         void exdent() { _logBuffer.exdent(); }
00147         void disableFlush() { _logBuffer.disableFlush(); }
00148         void enableFlush()  { _logBuffer.enableFlush();  }
00149         void forceFlush()  { _logBuffer.pubsync();  }
00150         void disableHeader() { _logBuffer.disableHeader(); }
00151         void enableHeader()  { _logBuffer.enableHeader();  }
00152 
00154         static COBASE_API int level;
00155 
00157         static COBASE_API unsigned topics;
00158 
00160         static COBASE_API Log& instance();
00161 
00163         static COBASE_API Log& instance( const char* file, const int line );
00164 
00166         static COBASE_API void exit();
00167 
00169         static std::string& getLogLevelString();
00170 
00172         static COBASE_API void setOutput( std::ostream& stream );
00173 
00175         static COBASE_API std::ostream& getOutput ();
00176 
00185         static COBASE_API void setClock( Clock* clock );
00186 
00188         void setThreadName( const std::string& name )
00189             { _logBuffer.setThreadName( name ); }
00190 
00192         const char* getThreadName() const { return _logBuffer.getThreadName(); }
00193 
00194     private:
00195         LogBuffer _logBuffer; 
00196 
00197         Log( const Log& );
00198         Log& operator = ( const Log& );
00199 
00200         void setLogInfo( const char* file, const int line )
00201             { _logBuffer.setLogInfo( file, line ); }
00202     };
00203 
00209     COBASE_API std::ostream& indent( std::ostream& os );
00211     COBASE_API std::ostream& exdent( std::ostream& os );
00212 
00214     COBASE_API std::ostream& disableFlush( std::ostream& os );
00216     COBASE_API std::ostream& enableFlush( std::ostream& os );
00218     COBASE_API std::ostream& forceFlush( std::ostream& os );
00219 
00221     COBASE_API std::ostream& disableHeader( std::ostream& os );
00223     COBASE_API std::ostream& enableHeader( std::ostream& os );
00224 }
00225 }
00226 
00228 #define EQERROR (co::base::Log::level >= co::base::LOG_ERROR) &&    \
00229     co::base::Log::instance( __FILE__, __LINE__ )
00230 
00231 #define EQWARN  (co::base::Log::level >= co::base::LOG_WARN)  &&    \
00232     co::base::Log::instance( __FILE__, __LINE__ )
00233 
00234 #define EQINFO  (co::base::Log::level >= co::base::LOG_INFO)  &&    \
00235     co::base::Log::instance( __FILE__, __LINE__ )
00236 
00237 #ifdef NDEBUG
00238 #  define EQVERB if( false )                                    \
00239         co::base::Log::instance( __FILE__, __LINE__ )
00240 #else
00241 
00242 #  define EQVERB (co::base::Log::level >= co::base::LOG_VERB)  &&    \
00243     co::base::Log::instance( __FILE__, __LINE__ )
00244 #endif
00245 
00250 #define EQLOG(topic)  (co::base::Log::topics & (topic))  &&  \
00251     co::base::Log::instance( __FILE__, __LINE__ )
00252 
00253 #endif //COBASE_LOG_H
Generated on Fri Jun 8 2012 15:44:31 for Equalizer 1.2.1 by  doxygen 1.8.0