summaryrefslogtreecommitdiff
path: root/util/log.h
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2011-03-17 00:05:43 +0100
committerAntonin Kral <a.kral@bobek.cz>2011-03-17 00:05:43 +0100
commit582fc32574a3b158c81e49cb00e6ae59205e66ba (patch)
treeac64a3243e0d2121709f685695247052858115c8 /util/log.h
parent2761bffa96595ac1698d86bbc2e95ebb0d4d6e93 (diff)
downloadmongodb-582fc32574a3b158c81e49cb00e6ae59205e66ba.tar.gz
Imported Upstream version 1.8.0
Diffstat (limited to 'util/log.h')
-rw-r--r--util/log.h166
1 files changed, 104 insertions, 62 deletions
diff --git a/util/log.h b/util/log.h
index 87b7b7e..86aae1c 100644
--- a/util/log.h
+++ b/util/log.h
@@ -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