Equalizer 1.0
|
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