summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/dbwebserver.cpp9
-rw-r--r--db/repl/health.cpp70
-rw-r--r--util/log.h7
-rw-r--r--util/ramlog.h73
-rw-r--r--util/util.cpp2
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;