diff options
author | Antonin Kral <a.kral@bobek.cz> | 2011-03-17 00:05:43 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2011-03-17 00:05:43 +0100 |
commit | 582fc32574a3b158c81e49cb00e6ae59205e66ba (patch) | |
tree | ac64a3243e0d2121709f685695247052858115c8 /util/log.h | |
parent | 2761bffa96595ac1698d86bbc2e95ebb0d4d6e93 (diff) | |
download | mongodb-582fc32574a3b158c81e49cb00e6ae59205e66ba.tar.gz |
Imported Upstream version 1.8.0
Diffstat (limited to 'util/log.h')
-rw-r--r-- | util/log.h | 166 |
1 files changed, 104 insertions, 62 deletions
@@ -28,24 +28,24 @@ namespace mongo { enum LogLevel { LL_DEBUG , LL_INFO , LL_NOTICE , LL_WARNING , LL_ERROR , LL_SEVERE }; - - inline const char * logLevelToString( LogLevel l ){ - switch ( l ){ + + inline const char * logLevelToString( LogLevel l ) { + switch ( l ) { case LL_DEBUG: - case LL_INFO: + case LL_INFO: case LL_NOTICE: return ""; - case LL_WARNING: - return "warning" ; - case LL_ERROR: + case LL_WARNING: + return "warning" ; + case LL_ERROR: return "ERROR"; - case LL_SEVERE: + case LL_SEVERE: return "SEVERE"; default: return "UNKNOWN"; } } - + class LazyString { public: virtual ~LazyString() {} @@ -62,15 +62,15 @@ namespace mongo { const T& t_; }; - class Tee { + class Tee { public: - virtual ~Tee(){} + virtual ~Tee() {} virtual void write(LogLevel level , const string& str) = 0; }; class Nullstream { public: - virtual Nullstream& operator<< (Tee* tee) { + virtual Nullstream& operator<< (Tee* tee) { return *this; } virtual ~Nullstream() {} @@ -80,6 +80,9 @@ namespace mongo { virtual Nullstream& operator<<(const string& ) { return *this; } + virtual Nullstream& operator<<(const StringData& ) { + return *this; + } virtual Nullstream& operator<<(char *) { return *this; } @@ -125,53 +128,72 @@ namespace mongo { template< class T > Nullstream& operator<<(T *t) { return operator<<( static_cast<void*>( t ) ); - } + } template< class T > Nullstream& operator<<(const T *t) { return operator<<( static_cast<const void*>( t ) ); - } + } template< class T > - Nullstream& operator<<(const shared_ptr<T> p ){ + Nullstream& operator<<(const shared_ptr<T> p ) { + T * t = p.get(); + if ( ! t ) + *this << "null"; + else + *this << *t; return *this; } template< class T > Nullstream& operator<<(const T &t) { return operator<<( static_cast<const LazyString&>( LazyStringImpl< T >( t ) ) ); } + virtual Nullstream& operator<< (ostream& ( *endl )(ostream&)) { return *this; } virtual Nullstream& operator<< (ios_base& (*hex)(ios_base&)) { return *this; } + virtual void flush(Tee *t = 0) {} }; extern Nullstream nullstream; - + class Logstream : public Nullstream { static mongo::mutex mutex; static int doneSetup; stringstream ss; + int indent; LogLevel logLevel; static FILE* logfile; static boost::scoped_ptr<ostream> stream; static vector<Tee*> * globalTees; public: - inline static void logLockless( const StringData& s ); - - static void setLogFile(FILE* f){ + + static void setLogFile(FILE* f) { scoped_lock lk(mutex); logfile = f; } - static int magicNumber(){ + static int magicNumber() { return 1717; } + static int getLogDesc() { + int fd = -1; + if (logfile != NULL) +#if defined(_WIN32) + // the ISO C++ conformant name is _fileno + fd = _fileno( logfile ); +#else + fd = fileno( logfile ); +#endif + return fd; + } + inline void flush(Tee *t = 0); - - inline Nullstream& setLogLevel(LogLevel l){ + + inline Nullstream& setLogLevel(LogLevel l) { logLevel = l; return *this; } @@ -179,6 +201,7 @@ namespace mongo { /** note these are virtual */ Logstream& operator<<(const char *x) { ss << x; return *this; } Logstream& operator<<(const string& x) { ss << x; return *this; } + Logstream& operator<<(const StringData& x) { ss << x.data(); return *this; } Logstream& operator<<(char *x) { ss << x; return *this; } Logstream& operator<<(char x) { ss << x; return *this; } Logstream& operator<<(int x) { ss << x; return *this; } @@ -197,7 +220,7 @@ namespace mongo { ss << x.val(); return *this; } - Nullstream& operator<< (Tee* tee) { + Nullstream& operator<< (Tee* tee) { ss << '\n'; flush(tee); return *this; @@ -212,32 +235,27 @@ namespace mongo { return *this; } - template< class T > - Nullstream& operator<<(const shared_ptr<T> p ){ - T * t = p.get(); - if ( ! t ) - *this << "null"; - else - *this << *t; - return *this; - } - Logstream& prolog() { return *this; } - - void addGlobalTee( Tee * t ){ + + void addGlobalTee( Tee * t ) { if ( ! globalTees ) globalTees = new vector<Tee*>(); globalTees->push_back( t ); } + + void indentInc(){ indent++; } + void indentDec(){ indent--; } + int getIndent() const { return indent; } private: static thread_specific_ptr<Logstream> tsp; - Logstream(){ + Logstream() { + indent = 0; _init(); } - void _init(){ + void _init() { ss.str(""); logLevel = LL_INFO; } @@ -258,16 +276,16 @@ namespace mongo { return nullstream; return Logstream::get(); } - - /* flush the log stream if the log level is + + /* flush the log stream if the log level is at the specified level or higher. */ - inline void logflush(int level = 0) { + inline void logflush(int level = 0) { if( level > logLevel ) Logstream::get().flush(0); } /* without prolog */ - inline Nullstream& _log( int level = 0 ){ + inline Nullstream& _log( int level = 0 ) { if ( level > logLevel ) return nullstream; return Logstream::get(); @@ -287,6 +305,9 @@ namespace mongo { return Logstream::get().prolog(); } +#define MONGO_LOG(level) if ( logLevel >= (level) ) log( level ) +#define LOG MONGO_LOG + inline Nullstream& log( LogLevel l ) { return Logstream::get().prolog().setLogLevel( l ); } @@ -295,7 +316,7 @@ namespace mongo { inline Nullstream& log() { return Logstream::get().prolog(); } - + inline Nullstream& error() { return log( LL_ERROR ); } @@ -317,7 +338,7 @@ namespace mongo { /** log to a file rather than stdout - defined in assert_util.cpp + defined in assert_util.cpp */ void initLogging( const string& logpath , bool append ); void rotateLogs( int signal = 0 ); @@ -333,7 +354,7 @@ namespace mongo { FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ALLOCATE_BUFFER - |FORMAT_MESSAGE_IGNORE_INSERTS, + |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, x, 0, (LPTSTR) &errorText, // output @@ -342,7 +363,7 @@ namespace mongo { if( errorText ) { string x = toUtf8String(errorText); for( string::iterator i = x.begin(); i != x.end(); i++ ) { - if( *i == '\n' || *i == '\r' ) + if( *i == '\n' || *i == '\r' ) break; s << *i; } @@ -351,11 +372,11 @@ namespace mongo { else s << strerror(x); /* - DWORD n = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | + DWORD n = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, x, + NULL, x, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); */ @@ -365,22 +386,28 @@ namespace mongo { return s.str(); } - /** output the error # and error message with prefix. + /** output the error # and error message with prefix. handy for use as parm in uassert/massert. */ string errnoWithPrefix( const char * prefix ); - void Logstream::logLockless( const StringData& s ){ - if ( doneSetup == 1717 ){ - if(fwrite(s.data(), s.size(), 1, logfile)){ + void Logstream::logLockless( const StringData& s ) { + + if ( s.size() == 0 ) + return; + + if ( doneSetup == 1717 ) { + if (fwrite(s.data(), s.size(), 1, logfile)) { fflush(logfile); - }else{ + } + else { int x = errno; - cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl; + cout << "Failed to write to logfile: " << errnoWithDescription(x) << endl; } } else { - cout << s.data() << endl; + cout << s.data(); + cout.flush(); } } @@ -391,23 +418,28 @@ namespace mongo { string threadName = getThreadName(); const char * type = logLevelToString(logLevel); - int spaceNeeded = msg.size() + 64 + threadName.size(); + int spaceNeeded = (int)(msg.size() + 64 + threadName.size()); int bufSize = 128; while ( bufSize < spaceNeeded ) bufSize += 128; BufBuilder b(bufSize); time_t_to_String( time(0) , b.grow(20) ); - if (!threadName.empty()){ + if (!threadName.empty()) { b.appendChar( '[' ); b.appendStr( threadName , false ); b.appendChar( ']' ); b.appendChar( ' ' ); } - if ( type[0] ){ + + for ( int i=0; i<indent; i++ ) + b.appendChar( '\t' ); + + if ( type[0] ) { b.appendStr( type , false ); b.appendStr( ": " , false ); } + b.appendStr( msg ); string out( b.buf() , b.len() - 1); @@ -415,7 +447,7 @@ namespace mongo { scoped_lock lk(mutex); if( t ) t->write(logLevel,out); - if ( globalTees ){ + if ( globalTees ) { for ( unsigned i=0; i<globalTees->size(); i++ ) (*globalTees)[i]->write(logLevel,out); } @@ -423,9 +455,10 @@ namespace mongo { #ifndef _WIN32 //syslog( LOG_INFO , "%s" , cc ); #endif - if(fwrite(out.data(), out.size(), 1, logfile)){ + if(fwrite(out.data(), out.size(), 1, logfile)) { fflush(logfile); - }else{ + } + else { int x = errno; cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl; } @@ -433,4 +466,13 @@ namespace mongo { _init(); } + struct LogIndentLevel { + LogIndentLevel(){ + Logstream::get().indentInc(); + } + ~LogIndentLevel(){ + Logstream::get().indentDec(); + } + }; + } // namespace mongo |