2008-07-11 18:27:23 +02:00
|
|
|
// log.h
|
|
|
|
|
2009-10-27 20:58:27 +01:00
|
|
|
/* Copyright 2009 10gen Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2008-07-20 23:37:33 +02:00
|
|
|
|
2008-07-11 18:27:23 +02:00
|
|
|
#pragma once
|
|
|
|
|
2009-12-21 16:06:14 +01:00
|
|
|
#include <string.h>
|
2010-01-28 20:58:23 +01:00
|
|
|
#include <errno.h>
|
2009-12-21 16:06:14 +01:00
|
|
|
|
2009-01-14 23:09:51 +01:00
|
|
|
namespace mongo {
|
2009-02-19 18:03:15 +01:00
|
|
|
|
2009-10-18 02:35:03 +02:00
|
|
|
using boost::shared_ptr;
|
|
|
|
|
2009-05-28 21:22:24 +02:00
|
|
|
// Utility interface for stringifying object only when val() called.
|
2009-02-19 18:03:15 +01:00
|
|
|
class LazyString {
|
|
|
|
public:
|
2009-02-23 17:11:00 +01:00
|
|
|
virtual ~LazyString() {}
|
|
|
|
virtual string val() const = 0;
|
|
|
|
};
|
2009-05-28 21:22:24 +02:00
|
|
|
|
|
|
|
// Utility class for stringifying object only when val() called.
|
2009-02-23 17:11:00 +01:00
|
|
|
template< class T >
|
|
|
|
class LazyStringImpl : public LazyString {
|
|
|
|
public:
|
|
|
|
LazyStringImpl( const T &t ) : t_( t ) {}
|
|
|
|
virtual string val() const { return (string)t_; }
|
2009-02-19 18:03:15 +01:00
|
|
|
private:
|
2009-02-23 17:11:00 +01:00
|
|
|
const T& t_;
|
2009-02-19 18:03:15 +01:00
|
|
|
};
|
2009-09-03 20:58:05 +02:00
|
|
|
|
2009-01-15 16:17:11 +01:00
|
|
|
class Nullstream {
|
|
|
|
public:
|
2009-02-18 19:42:32 +01:00
|
|
|
virtual ~Nullstream() {}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(const char *) {
|
|
|
|
return *this;
|
|
|
|
}
|
2009-02-23 17:11:00 +01:00
|
|
|
virtual Nullstream& operator<<(char *) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
virtual Nullstream& operator<<(char) {
|
2009-01-20 23:21:47 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(int) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-08-05 22:00:27 +02:00
|
|
|
virtual Nullstream& operator<<(ExitCode) {
|
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(unsigned long) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-29 22:06:22 +01:00
|
|
|
virtual Nullstream& operator<<(long) {
|
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(unsigned) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(double) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(void *) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-02-23 17:16:33 +01:00
|
|
|
virtual Nullstream& operator<<(const void *) {
|
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(long long) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<<(unsigned long long) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-02-23 17:11:00 +01:00
|
|
|
virtual Nullstream& operator<<(bool) {
|
|
|
|
return *this;
|
|
|
|
}
|
2009-02-19 18:03:15 +01:00
|
|
|
virtual Nullstream& operator<<(const LazyString&) {
|
|
|
|
return *this;
|
|
|
|
}
|
2009-02-23 17:11:00 +01:00
|
|
|
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 >
|
2009-08-17 16:46:19 +02:00
|
|
|
Nullstream& operator<<(const shared_ptr<T> p ){
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
template< class T >
|
2009-02-23 17:11:00 +01:00
|
|
|
Nullstream& operator<<(const T &t) {
|
|
|
|
return operator<<( static_cast<const LazyString&>( LazyStringImpl< T >( t ) ) );
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<< (ostream& ( *endl )(ostream&)) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual Nullstream& operator<< (ios_base& (*hex)(ios_base&)) {
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-20 20:30:59 +01:00
|
|
|
virtual void flush(){}
|
2009-01-15 16:17:11 +01:00
|
|
|
};
|
|
|
|
extern Nullstream nullstream;
|
2009-01-20 20:30:59 +01:00
|
|
|
|
2009-09-03 19:37:20 +02:00
|
|
|
|
2009-01-20 20:30:59 +01:00
|
|
|
class Logstream : public Nullstream {
|
2010-03-15 17:42:01 +01:00
|
|
|
static mongo::mutex mutex;
|
2009-10-21 22:40:31 +02:00
|
|
|
static int doneSetup;
|
2009-09-03 21:16:04 +02:00
|
|
|
stringstream ss;
|
2009-01-15 16:17:11 +01:00
|
|
|
public:
|
2009-10-21 22:40:31 +02:00
|
|
|
static int magicNumber(){
|
|
|
|
return 1717;
|
|
|
|
}
|
2009-01-15 16:17:11 +01:00
|
|
|
void flush() {
|
2009-10-21 22:40:31 +02:00
|
|
|
// this ensures things are sane
|
|
|
|
if ( doneSetup == 1717 ){
|
2010-03-15 17:42:01 +01:00
|
|
|
scoped_lock lk(mutex);
|
2009-09-03 21:16:04 +02:00
|
|
|
cout << ss.str();
|
|
|
|
cout.flush();
|
|
|
|
}
|
|
|
|
ss.str("");
|
2009-01-15 16:17:11 +01:00
|
|
|
}
|
2010-04-24 20:03:14 +02:00
|
|
|
|
|
|
|
/** note these are virtual */
|
|
|
|
Logstream& operator<<(const char *x) { ss << x; 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; }
|
|
|
|
Logstream& operator<<(ExitCode x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(long x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(unsigned long x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(unsigned x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(double x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(void *x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(const void *x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(long long x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(unsigned long long x) { ss << x; return *this; }
|
|
|
|
Logstream& operator<<(bool x) { ss << x; return *this; }
|
|
|
|
|
2009-02-19 18:03:15 +01:00
|
|
|
Logstream& operator<<(const LazyString& x) {
|
2009-09-03 21:16:04 +02:00
|
|
|
ss << x.val();
|
2009-02-19 18:03:15 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-01-15 16:17:11 +01:00
|
|
|
Logstream& operator<< (ostream& ( *_endl )(ostream&)) {
|
2009-09-03 21:16:04 +02:00
|
|
|
ss << '\n';
|
|
|
|
flush();
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
Logstream& operator<< (ios_base& (*_hex)(ios_base&)) {
|
2009-09-03 21:16:04 +02:00
|
|
|
ss << _hex;
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-09-03 19:37:20 +02:00
|
|
|
|
|
|
|
template< class T >
|
|
|
|
Nullstream& operator<<(const shared_ptr<T> p ){
|
|
|
|
T * t = p.get();
|
|
|
|
if ( ! t )
|
|
|
|
*this << "null";
|
|
|
|
else
|
|
|
|
*this << t;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-10-13 22:01:02 +02:00
|
|
|
Logstream& prolog() {
|
2009-01-15 16:17:11 +01:00
|
|
|
char now[64];
|
|
|
|
time_t_to_String(time(0), now);
|
|
|
|
now[20] = 0;
|
2009-09-03 21:16:04 +02:00
|
|
|
ss << now;
|
2009-01-15 16:17:11 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2009-09-03 19:37:20 +02:00
|
|
|
|
2009-09-03 20:58:05 +02:00
|
|
|
private:
|
|
|
|
static thread_specific_ptr<Logstream> tsp;
|
|
|
|
public:
|
|
|
|
static Logstream& get() {
|
|
|
|
Logstream *p = tsp.get();
|
|
|
|
if( p == 0 )
|
|
|
|
tsp.reset( p = new Logstream() );
|
|
|
|
return *p;
|
|
|
|
}
|
2009-01-15 16:17:11 +01:00
|
|
|
};
|
|
|
|
|
2009-02-11 19:17:52 +01:00
|
|
|
extern int logLevel;
|
2009-01-20 20:30:59 +01:00
|
|
|
|
2009-02-11 19:17:52 +01:00
|
|
|
inline Nullstream& out( int level = 0 ) {
|
|
|
|
if ( level > logLevel )
|
|
|
|
return nullstream;
|
2009-09-03 20:58:05 +02:00
|
|
|
return Logstream::get();
|
2009-01-15 17:26:38 +01:00
|
|
|
}
|
|
|
|
|
2009-02-18 15:45:49 +01:00
|
|
|
/* flush the log stream if the log level is
|
|
|
|
at the specified level or higher. */
|
|
|
|
inline void logflush(int level = 0) {
|
|
|
|
if( level > logLevel )
|
2009-09-03 20:58:05 +02:00
|
|
|
Logstream::get().flush();
|
2009-02-18 15:45:49 +01:00
|
|
|
}
|
|
|
|
|
2009-09-21 22:31:00 +02:00
|
|
|
/* without prolog */
|
|
|
|
inline Nullstream& _log( int level = 0 ){
|
|
|
|
if ( level > logLevel )
|
|
|
|
return nullstream;
|
|
|
|
return Logstream::get();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Nullstream& log( int level = 0 ) {
|
2009-01-20 20:30:59 +01:00
|
|
|
if ( level > logLevel )
|
|
|
|
return nullstream;
|
2009-09-03 20:58:05 +02:00
|
|
|
return Logstream::get().prolog();
|
2009-02-11 19:17:52 +01:00
|
|
|
}
|
|
|
|
|
2009-09-03 20:58:05 +02:00
|
|
|
/* TODOCONCURRENCY */
|
2009-02-11 19:17:52 +01:00
|
|
|
inline ostream& stdcout() {
|
|
|
|
return cout;
|
2009-01-20 20:30:59 +01:00
|
|
|
}
|
|
|
|
|
2009-10-13 22:01:02 +02:00
|
|
|
/* default impl returns "" -- mongod overrides */
|
|
|
|
extern const char * (*getcurns)();
|
|
|
|
|
|
|
|
inline Nullstream& problem( int level = 0 ) {
|
|
|
|
if ( level > logLevel )
|
|
|
|
return nullstream;
|
|
|
|
Logstream& l = Logstream::get().prolog();
|
|
|
|
l << ' ' << getcurns() << ' ';
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
2009-10-16 16:56:15 +02:00
|
|
|
/**
|
|
|
|
log to a file rather than stdout
|
|
|
|
defined in assert_util.cpp
|
|
|
|
*/
|
|
|
|
void initLogging( const string& logpath , bool append );
|
2009-10-16 18:46:06 +02:00
|
|
|
void rotateLogs( int signal = 0 );
|
2009-10-16 16:56:15 +02:00
|
|
|
|
2010-04-24 20:03:14 +02:00
|
|
|
inline string errnoWithDescription(int x = errno) {
|
|
|
|
stringstream s;
|
|
|
|
s << "errno:" << x << ' ' << strerror(x);
|
|
|
|
return s.str();
|
|
|
|
}
|
2009-12-21 16:06:14 +01:00
|
|
|
|
2010-04-24 20:03:14 +02:00
|
|
|
/** output the error # and error message with prefix.
|
|
|
|
handy for use as parm in uassert/massert.
|
|
|
|
*/
|
|
|
|
string errnoWithPrefix( const char * prefix = 0 );
|
2010-02-04 16:59:13 +01:00
|
|
|
|
2009-01-14 23:09:51 +01:00
|
|
|
} // namespace mongo
|