diff options
-rw-r--r-- | db/dbwebserver.cpp | 9 | ||||
-rw-r--r-- | db/repl/health.cpp | 70 | ||||
-rw-r--r-- | util/log.h | 7 | ||||
-rw-r--r-- | util/ramlog.h | 73 | ||||
-rw-r--r-- | util/util.cpp | 2 |
5 files changed, 91 insertions, 70 deletions
diff --git a/db/dbwebserver.cpp b/db/dbwebserver.cpp index 0b99553063a..b0e414a5065 100644 --- a/db/dbwebserver.cpp +++ b/db/dbwebserver.cpp @@ -32,6 +32,7 @@ #include "background.h" #include "commands.h" #include "../util/version.h" +#include "../util/ramlog.h" #include <pcrecpp.h> #include <boost/date_time/posix_time/posix_time.hpp> #undef assert @@ -87,7 +88,9 @@ namespace mongo { class DbWebServer : public MiniWebServer { public: - DbWebServer(const string& ip, int port) : MiniWebServer(ip, port) {} + DbWebServer(const string& ip, int port) : MiniWebServer(ip, port), ramlog(new RamLog()) { + Logstream::get().addGlobalTee( ramlog ); + } private: // caller locks @@ -147,6 +150,9 @@ namespace mongo { statsSnapshots.outputLockInfoHTML( ss ); BackgroundOperation::dump(ss); + + ss << "<h3>Log</h3>\n"; + ramlog->toHTML( ss ); } void display( stringstream& ss , double elapsed , const Top::UsageData& usage ){ @@ -791,6 +797,7 @@ namespace mongo { private: static DBDirectClient db; + RamLog * ramlog; }; DBDirectClient DbWebServer::db; diff --git a/db/repl/health.cpp b/db/repl/health.cpp index 8eb2de37838..0b74198a702 100644 --- a/db/repl/health.cpp +++ b/db/repl/health.cpp @@ -257,77 +257,9 @@ namespace mongo { s << _table(); } - static int repeats(const vector<const char *>& v, int i) { - for( int j = i-1; j >= 0 && j+8 > i; j-- ) { - if( strcmp(v[i]+20,v[j]+20) == 0 ) { - for( int x = 1; ; x++ ) { - if( j+x == i ) return j; - if( i+x>=(int) v.size() ) return -1; - if( strcmp(v[i+x]+20,v[j+x]+20) ) return -1; - } - return -1; - } - } - return -1; - } - - static string clean(const vector<const char *>& v, int i, string line="") { - if( line.empty() ) line = v[i]; - if( i > 0 && strncmp(v[i], v[i-1], 11) == 0 ) - return string(" ") + line.substr(11); - return v[i]; - } - - /*static bool isWarning(const char *line) { - const char *p = strstr(line, "replSet "); - if( p ) { - p += 8; - return startsWith(p, "warning") || startsWith(p, "error"); - } - return false; - }*/ - static string color(string line) { - string s = str::after(line, "replSet "); - if( str::startsWith(s, "warning") || startsWith(s, "error") ) - return red(line); - if( str::startsWith(s, "info") ) { - if( str::endsWith(s, " up\n") ) - return green(line); - if( str::endsWith(s, " down\n") ) - return yellow(line); - return blue(line); - } - - return line; - } void fillRsLog(stringstream& s) { - bool first = true; - s << "<pre>\n"; - vector<const char *> v = _rsLog.get(); - for( int i = 0; i < (int)v.size(); i++ ) { - assert( strlen(v[i]) > 20 ); - int r = repeats(v, i); - if( r < 0 ) { - s << color( clean(v,i) ); - } else { - stringstream x; - x << string(v[i], 0, 20); - int nr = (i-r); - int last = i+nr-1; - for( ; r < i ; r++ ) x << '.'; - if( 1 ) { - stringstream r; - if( nr == 1 ) r << "repeat last line"; - else r << "repeats last " << nr << " lines; ends " << string(v[last]+4,0,15); - first = false; s << a("", r.str(), clean(v,i,x.str())); - } - else s << x.str(); - s << '\n'; - i = last; - } - } - s << "</pre>\n"; + _rsLog.toHTML( s ); } Member* ReplSetImpl::findById(unsigned id) const { diff --git a/util/log.h b/util/log.h index 146dfe5647a..4c0b555bfa4 100644 --- a/util/log.h +++ b/util/log.h @@ -152,6 +152,7 @@ namespace mongo { LogLevel logLevel; static boost::scoped_ptr<ostream> stream; static FILE* logfile; + static vector<Tee*> globalTees; public: static void setLogFile(FILE* f){ @@ -185,6 +186,8 @@ namespace mongo { scoped_lock lk(mutex); if( t ) t->write(logLevel,s); + for ( unsigned i=0; i<globalTees.size(); i++ ) + globalTees[i]->write(logLevel,s); #ifndef _WIN32 //syslog( LOG_INFO , "%s" , cc ); @@ -248,6 +251,10 @@ namespace mongo { Logstream& prolog() { return *this; } + + void addGlobalTee( Tee * t ){ + globalTees.push_back( t ); + } private: static thread_specific_ptr<Logstream> tsp; diff --git a/util/ramlog.h b/util/ramlog.h index 6cdad975cb8..6d456c3b872 100644 --- a/util/ramlog.h +++ b/util/ramlog.h @@ -18,6 +18,7 @@ #pragma once #include "log.h" +#include "mongoutils/html.h" namespace mongo { @@ -35,6 +36,7 @@ namespace mongo { for( int i = 0; i < N; i++ ) lines[i][C-1] = 0; } + virtual void write(LogLevel ll, const string& str) { char *p = lines[(h+n)%N]; if( str.size() < C ) @@ -44,12 +46,83 @@ namespace mongo { if( n < N ) n++; else h = (h+1) % N; } + vector<const char *> get() const { vector<const char *> v; for( unsigned x=0, i=h; x++ < n; i=(i+1)%N ) v.push_back(lines[i]); return v; } + + static int repeats(const vector<const char *>& v, int i) { + for( int j = i-1; j >= 0 && j+8 > i; j-- ) { + if( strcmp(v[i]+20,v[j]+20) == 0 ) { + for( int x = 1; ; x++ ) { + if( j+x == i ) return j; + if( i+x>=(int) v.size() ) return -1; + if( strcmp(v[i+x]+20,v[j+x]+20) ) return -1; + } + return -1; + } + } + return -1; + } + + + static string clean(const vector<const char *>& v, int i, string line="") { + if( line.empty() ) line = v[i]; + if( i > 0 && strncmp(v[i], v[i-1], 11) == 0 ) + return string(" ") + line.substr(11); + return v[i]; + } + + static string color(string line) { + string s = str::after(line, "replSet "); + if( str::startsWith(s, "warning") || startsWith(s, "error") ) + return html::red(line); + if( str::startsWith(s, "info") ) { + if( str::endsWith(s, " up\n") ) + return html::green(line); + if( str::endsWith(s, " down\n") ) + return html::yellow(line); + return html::blue(line); + } + + return line; + } + + + void toHTML(stringstream& s) { + bool first = true; + s << "<pre>\n"; + vector<const char *> v = get(); + for( int i = 0; i < (int)v.size(); i++ ) { + assert( strlen(v[i]) > 20 ); + int r = repeats(v, i); + if( r < 0 ) { + s << color( clean(v,i) ); + } + else { + stringstream x; + x << string(v[i], 0, 20); + int nr = (i-r); + int last = i+nr-1; + for( ; r < i ; r++ ) x << '.'; + if( 1 ) { + stringstream r; + if( nr == 1 ) r << "repeat last line"; + else r << "repeats last " << nr << " lines; ends " << string(v[last]+4,0,15); + first = false; s << html::a("", r.str(), clean(v,i,x.str())); + } + else s << x.str(); + s << '\n'; + i = last; + } + } + s << "</pre>\n"; + } + + }; } diff --git a/util/util.cpp b/util/util.cpp index 4030e2d7d10..479c419d5b9 100644 --- a/util/util.cpp +++ b/util/util.cpp @@ -83,6 +83,8 @@ namespace mongo { bool UnitTest::running = false; Nullstream nullstream; + vector<Tee*> Logstream::globalTees; + thread_specific_ptr<Logstream> Logstream::tsp; |