Equalizer 1.0

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 
00045     enum LogLevel
00046     {
00047         LOG_ERROR = 1, 
00048         LOG_WARN,      
00049         LOG_INFO,      
00050         LOG_VERB,      
00051         LOG_ALL
00052     };
00053 
00060     enum LogTopic
00061     {
00062         LOG_PLUGIN = 0x1,        
00063         LOG_CUSTOM = 0x10,       
00064         LOG_ANY    = 0xffffu     
00065     };
00066 
00068     class LogBuffer : public std::streambuf
00069     {
00070     public:
00071         LogBuffer( std::ostream& stream )
00072                 : _line(0), _indent(0), _blocked(0), _noHeader(0),
00073                   _newLine(true), _stream(stream)
00074             { _thread[0] = 0; }
00075         virtual ~LogBuffer() {}
00076 
00077         void indent() { ++_indent; }
00078         void exdent() { --_indent; }
00079 
00080         void disableFlush() { ++_blocked; } // use counted variable to allow
00081         void enableFlush()                  //   nested enable/disable calls
00082             { 
00083                 assert( _blocked );// Too many enableFlush on log stream
00084                 --_blocked;
00085             }
00086 
00087         void disableHeader() { ++_noHeader; } // use counted variable to allow
00088         void enableHeader()  { --_noHeader; } //   nested enable/disable calls
00089 
00090         COBASE_API void setThreadName( const std::string& name );
00091         const char* getThreadName() const { return _thread; }
00092 
00093         void setLogInfo( const char* file, const int line )
00094             { _file = file; _line = line; }
00095 
00096     protected:
00097         virtual int_type overflow( LogBuffer::int_type c );
00098         
00099         virtual int sync() 
00100             {
00101                 if( !_blocked )
00102                 {
00103                     const std::string& string = _stringStream.str();
00104                     _stream.write( string.c_str(), string.length( ));
00105                     _stream.rdbuf()->pubsync();
00106                     _stringStream.str( "" );
00107                 }
00108                 _newLine = true;
00109                 return 0;
00110             }
00111 
00112     private:
00113         LogBuffer( const LogBuffer& );
00114         LogBuffer& operator = ( const LogBuffer& );
00115 
00117         char _thread[12];
00118 
00120         std::string _file;
00121 
00123         int _line;
00124 
00126         int _indent;
00127 
00129         int _blocked;
00130 
00132         int _noHeader;
00133 
00135         bool _newLine;
00136 
00138         std::ostringstream _stringStream;
00139 
00141         std::ostream& _stream;
00142     };
00143 
00145     class Log : public std::ostream
00146     {
00147     public:
00148 
00149         Log() : std::ostream( &_logBuffer ), _logBuffer( getOutput( )){}
00150         virtual ~Log() { _logBuffer.pubsync(); }
00151 
00152         void indent() { _logBuffer.indent(); }
00153         void exdent() { _logBuffer.exdent(); }
00154         void disableFlush() { _logBuffer.disableFlush(); }
00155         void enableFlush()  { _logBuffer.enableFlush();  }
00156         void forceFlush()  { _logBuffer.pubsync();  }
00157         void disableHeader() { _logBuffer.disableHeader(); }
00158         void enableHeader()  { _logBuffer.enableHeader();  }
00159 
00161         static COBASE_API int level;
00162 
00164         static COBASE_API unsigned topics;
00165 
00167         static COBASE_API Log& instance();
00168 
00170         static COBASE_API Log& instance( const char* file, const int line );
00171 
00173         static COBASE_API void exit();
00174 
00176         static std::string& getLogLevelString();
00177 
00179         static COBASE_API void setOutput( std::ostream& stream );
00180 
00182         static COBASE_API std::ostream& getOutput ();
00183 
00192         static COBASE_API void setClock( Clock* clock );
00193 
00195         void setThreadName( const std::string& name )
00196             { _logBuffer.setThreadName( name ); }
00197 
00199         const char* getThreadName() const { return _logBuffer.getThreadName(); }
00200 
00201     private:
00202         LogBuffer _logBuffer; 
00203 
00204         Log( const Log& );
00205         Log& operator = ( const Log& );
00206 
00207         void setLogInfo( const char* file, const int line )
00208             { _logBuffer.setLogInfo( file, line ); }
00209     };
00210 
00216     COBASE_API std::ostream& indent( std::ostream& os );
00218     COBASE_API std::ostream& exdent( std::ostream& os );
00219 
00221     COBASE_API std::ostream& disableFlush( std::ostream& os );
00223     COBASE_API std::ostream& enableFlush( std::ostream& os );
00225     COBASE_API std::ostream& forceFlush( std::ostream& os );
00226 
00228     COBASE_API std::ostream& disableHeader( std::ostream& os );
00230     COBASE_API std::ostream& enableHeader( std::ostream& os );
00231 }
00232 }
00233 
00235 #define EQERROR (co::base::Log::level >= co::base::LOG_ERROR) &&    \
00236     co::base::Log::instance( __FILE__, __LINE__ )
00237 
00238 #define EQWARN  (co::base::Log::level >= co::base::LOG_WARN)  &&    \
00239     co::base::Log::instance( __FILE__, __LINE__ )
00240 
00241 #define EQINFO  (co::base::Log::level >= co::base::LOG_INFO)  &&    \
00242     co::base::Log::instance( __FILE__, __LINE__ )
00243 
00244 #ifdef NDEBUG
00245 #  define EQVERB if( false )                                    \
00246         co::base::Log::instance( __FILE__, __LINE__ )
00247 #else
00248 
00249 #  define EQVERB (co::base::Log::level >= co::base::LOG_VERB)  &&    \
00250     co::base::Log::instance( __FILE__, __LINE__ )
00251 #endif
00252 
00257 #define EQLOG(topic)  (co::base::Log::topics & (topic))  &&  \
00258     co::base::Log::instance( __FILE__, __LINE__ )
00259 
00260 #endif //COBASE_LOG_H
Generated on Sun May 8 2011 19:11:07 for Equalizer 1.0 by  doxygen 1.7.3