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