0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
This commit is contained in:
Dwight 2010-05-07 16:42:55 -04:00
parent e8102565b5
commit 8717179475
12 changed files with 132 additions and 27 deletions

View File

@ -549,12 +549,16 @@
</ItemGroup>
<ItemGroup>
<None Include="..\SConstruct" />
<None Include="..\util\mongoutils\README" />
<None Include="repl\testing.js" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\targetver.h" />
<ClInclude Include="..\pcre-7.4\config.h" />
<ClInclude Include="..\pcre-7.4\pcre.h" />
<ClInclude Include="..\util\mongoutils\circularstringlist.h" />
<ClInclude Include="..\util\mongoutils\html.h" />
<ClInclude Include="..\util\ramlog.h" />
<ClInclude Include="helpers\dblogger.h" />
<ClInclude Include="repl.h" />
<ClInclude Include="replpair.h" />

View File

@ -21,7 +21,7 @@
#include "pch.h"
#include "../util/miniwebserver.h"
#include "../util/web/html.h"
#include "../util/mongoutils/html.h"
#include "../util/md5.hpp"
#include "db.h"
#include "repl.h"
@ -41,6 +41,7 @@ namespace mongo {
using namespace mongoutils::html;
using namespace bson;
extern void fillRsLog(stringstream&);
extern string bind_ip;
extern const char *replInfo;
@ -270,8 +271,9 @@ namespace mongo {
try {
theReplSet->summarizeAsHtml(s);
}
catch(...) { s << "error summarizing replset status"; }
catch(...) { s << "error summarizing replset status\n"; }
}
fillRsLog(s);
s << _end();
return s.str();
}

View File

@ -44,7 +44,7 @@ namespace mongo {
class E : public BackgroundJob {
void run() {
ok = 0;
log() << "not done" << endl;
log() << "not done" << rsLog;
try {
ScopedConn c(m->fullName());
if( c->runCommand("admin", electCmd, result) )

View File

@ -21,8 +21,9 @@
#include "../../client/dbclient.h"
#include "../commands.h"
#include "../../util/concurrency/value.h"
#include "../../util/web/html.h"
#include "../../util/mongoutils/html.h"
#include "../../util/goodies.h"
#include "../../util/ramlog.h"
#include "../helpers/dblogger.h"
#include "connections.h"
@ -36,6 +37,9 @@ namespace mongo {
using namespace mongoutils::html;
static RamLog _rsLog;
Tee *rsLog = &_rsLog;
/* { replSetHeartbeat : <setname> } */
class CmdReplSetHeartbeat : public Command {
public:
@ -74,7 +78,7 @@ namespace mongo {
m->_health = 0.0;
if( m->_upSince ) {
m->_upSince = 0;
log() << "replSet " << m->fullName() << " is now down" << endl;
log() << "replSet " << m->fullName() << " is now down" << rsLog;
}
}
@ -94,7 +98,7 @@ namespace mongo {
m->_lastHeartbeat = time(0);
if( ok ) {
if( m->_upSince == 0 ) {
log() << "replSet " << m->fullName() << " is now up" << endl;
log() << "replSet " << m->fullName() << " is now up" << rsLog;
m->_upSince = m->_lastHeartbeat;
}
m->_health = 1.0;
@ -184,6 +188,14 @@ namespace mongo {
s << _table();
}
void fillRsLog(stringstream& s) {
s << "<br><pre>\n";
vector<const char *> v = _rsLog.get();
for( unsigned i = 0; i < v.size(); i++ )
s << v[i];
s << "</pre>\n";
}
void ReplSet::summarizeStatus(BSONObjBuilder& b) const {
Member *m =_members.head();
vector<BSONObj> v;

View File

@ -25,6 +25,7 @@ namespace mongo {
ReplSet *theReplSet = 0;
void ReplSet::fillIsMaster(BSONObjBuilder& b) {
log() << "hellO" << rsLog;
b.append("ismaster", 0);
b.append("ok", false);
b.append("msg", "not yet implemented");
@ -44,7 +45,7 @@ namespace mongo {
const char *slash = strchr(p, '/');
uassert(13093, "bad --replSet config string format is: <setname>/<seedhost1>,<seedhost2>[,...]", slash != 0 && p != slash);
_name = string(p, slash-p);
log() << "replSet " << cfgString << endl;
log() << "replSet " << cfgString << rsLog;
set<HostAndPort> temp;
vector<HostAndPort> *seeds = new vector<HostAndPort>;
@ -65,7 +66,7 @@ namespace mongo {
temp.insert(m);
uassert(13101, "can't use localhost in replset host list", !m.isLocalHost());
if( m.isSelf() )
log() << "replSet ignoring seed " << m.toString() << " (=self)" << endl;
log() << "replSet ignoring seed " << m.toString() << " (=self)" << rsLog;
else
seeds->push_back(m);
if( *comma == 0 )
@ -146,13 +147,13 @@ namespace mongo {
startupStatusMsg = "can't get admin.system.replset config from self or any seed (uninitialized?)";
log() << "replSet can't get admin.system.replset config from self or any seed (EMPTYCONFIG)\n";
log() << "replSet have you ran replSetInitiate yet?\n";
log() << "replSet sleeping 1 minute and will try again." << endl;
log() << "replSet sleeping 1 minute and will try again." << rsLog;
}
else {
startupStatus = EMPTYUNREACHABLE;
startupStatusMsg = "can't currently get admin.system.replset config from self or any seed (EMPTYUNREACHABLE)";
log() << "replSet can't get admin.system.replset config from self or any seed.\n";
log() << "replSet sleeping 1 minute and will try again." << endl;
log() << "replSet sleeping 1 minute and will try again." << rsLog;
}
sleepsecs(60);
@ -164,7 +165,7 @@ namespace mongo {
startupStatus = BADCONFIG;
startupStatusMsg = "replSet error loading set config (BADCONFIG)";
log() << "replSet error loading configurations\n";
log() << "replSet replication will not start" << endl;
log() << "replSet replication will not start" << rsLog;
fatal();
throw;
}
@ -186,7 +187,7 @@ namespace mongo {
(theReplSet = new ReplSet(cmdLine.replSet))->go();
}
catch(std::exception& e) {
log() << "replSet Caught exception in management thread: " << e.what() << endl;
log() << "replSet Caught exception in management thread: " << e.what() << rsLog;
if( theReplSet )
theReplSet->fatal();
}

View File

@ -28,6 +28,8 @@ namespace mongo {
extern bool replSet; // true if using repl sets
extern class ReplSet *theReplSet; // null until initialized
extern Tee *rsLog;
/* information about the entire repl set, such as the various servers in the set, and their state */
/* note: We currently do not free mem when the set goes away - it is assumed the replset is a
singleton and long lived.
@ -142,7 +144,7 @@ namespace mongo {
friend class FeedbackThread;
public:
void fatal() { _myState = FATAL; log() << "replSet fatal error, stopping replication" << endl; }
void fatal() { _myState = FATAL; log() << "replSet fatal error, stopping replication" << rsLog; }
};

View File

@ -63,7 +63,7 @@ namespace mongo {
ReplSetConfig newConfig(cmdObj["replSetInitiate"].Obj());
log() << newConfig.toString() << endl;
log() << newConfig.toString() << rsLog;
newConfig.save();

View File

@ -138,13 +138,13 @@ namespace mongo {
m.check();
}
catch( const char * p ) {
log() << "replSet cfg parsing exception for members[" << i << "] " << p << endl;
log() << "replSet cfg parsing exception for members[" << i << "] " << p << rsLog;
stringstream ss;
ss << "replSet members[" << i << "] " << p;
uassert(13107, ss.str(), false);
}
catch(DBException& e) {
log() << "replSet cfg parsing exception for members[" << i << "] " << e.what() << endl;
log() << "replSet cfg parsing exception for members[" << i << "] " << e.what() << rsLog;
stringstream ss;
ss << "replSet members[" << i << "] bad config object";
uassert(13135, ss.str(), false);
@ -173,7 +173,7 @@ namespace mongo {
clear();
int level = 2;
DEV level = 0;
log(0) << "replSet load config from: " << h.toString() << endl;
log(0) << "replSet load config from: " << h.toString() << rsLog;
auto_ptr<DBClientCursor> c;
try {
@ -207,7 +207,7 @@ namespace mongo {
version = -1;
}
catch( UserException& e) {
log(level) << "replSet couldn't load config " << h.toString() << ' ' << e.what() << endl;
log(level) << "replSet couldn't load config " << h.toString() << ' ' << e.what() << rsLog;
return;
}
@ -215,7 +215,7 @@ namespace mongo {
uassert(13109, "multiple rows in local.system.replset not supported", !c->more());
from(o);
_ok = true;
log(level) << "replSet load ok" << endl;
log(level) << "replSet load ok" << rsLog;
}
}

View File

@ -41,8 +41,16 @@ namespace mongo {
const T& t_;
};
class Tee {
public:
virtual void write(const string& str) = 0;
};
class Nullstream {
public:
virtual Nullstream& operator<< (Tee* tee) {
return *this;
}
virtual ~Nullstream() {}
virtual Nullstream& operator<<(const char *) {
return *this;
@ -111,15 +119,10 @@ namespace mongo {
virtual Nullstream& operator<< (ios_base& (*hex)(ios_base&)) {
return *this;
}
virtual void flush(){}
virtual void flush(Tee *t = 0) {}
};
extern Nullstream nullstream;
class Tee {
public:
virtual void write(const string& str) = 0;
};
class Logstream : public Nullstream {
static mongo::mutex mutex;
static int doneSetup;
@ -160,9 +163,9 @@ namespace mongo {
ss << x.val();
return *this;
}
Logstream& operator<< (Tee& tee) {
Nullstream& operator<< (Tee* tee) {
ss << '\n';
flush(&tee);
flush(tee);
return *this;
}
Logstream& operator<< (ostream& ( *_endl )(ostream&)) {

7
util/mongoutils/README Executable file
View File

@ -0,0 +1,7 @@
mongoutils namespace requirements:
(1) code is not database specific, rather, true utilities
(2) are cross platform
(3) may require boost headers, but not libs
(4) are clean and easy to use in any c++ project without pulling in lots of other stuff
(5) apache license

View File

@ -9,6 +9,21 @@
(4) are clean and easy to use in any c++ project without pulling in lots of other stuff
*/
/* Copyright 2010 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.
*/
#include <sstream>
namespace mongoutils {

59
util/ramlog.h Normal file
View File

@ -0,0 +1,59 @@
// log.h
/* 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.
*/
#pragma once
#include "log.h"
namespace mongo {
class RamLog : public Tee {
enum {
N = 128,
C = 256
};
char lines[N][C];
unsigned h, t;
public:
RamLog() {
h = 0; t = 1;
for( int i = 0; i < N; i++ )
lines[i][C-1] = 0;
}
virtual void write(const string& str) {
char *p = lines[t];
if( str.size() < C )
strcpy(p, str.c_str());
else
memcpy(p, str.c_str(), C-1);
t = (t+1) % N;
if( h == t )
h = (h+1) % N;
}
vector<const char *> get() const {
vector<const char *> v;
unsigned x = h;
while( x != t ) {
v.push_back(lines[x]);
x = (x+1) % N;
}
return v;
}
};
}