& 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;
}
void fillRsLog(stringstream& s) {
bool first = true;
s << "\n";
vector 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 << red( clean(v,i), isWarning(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 << "\n";
}
void ReplSet::summarizeStatus(BSONObjBuilder& b) const {
Member *m =_members.head();
vector v;
// add self
{
HostAndPort h(getHostName(), cmdLine.port);
v.push_back(
BSON( "name" << h.toString() << "self" << true <<
"errmsg" << _self->_lastHeartbeatErrMsg.get() ) );
}
while( m ) {
BSONObjBuilder bb;
bb.append("name", m->fullName());
bb.append("health", m->health());
bb.append("uptime", (unsigned) (m->upSince() ? (time(0)-m->upSince()) : 0));
bb.appendDate("lastHeartbeat", m->lastHeartbeat());
bb.append("errmsg", m->_lastHeartbeatErrMsg.get());
v.push_back(bb.obj());
m = m->next();
}
b.append("set", name());
b.appendDate("date", time(0));
b.append("myState", _myState);
b.append("members", v);
}
void ReplSet::startHealthThreads() {
Member* m = _members.head();
while( m ) {
FeedbackThread *f = new FeedbackThread();
f->m = m;
f->go();
m = m->next();
}
}
}
/* todo:
stop bg job and delete on removefromset
*/