v;
while (iter.more())
v.push_back(iter.next());
s << "\n";
for (int i = 0; i < (int)v.size(); i++) {
verify(strlen(v[i]) > 24);
int r = repeats(v, i);
if (r < 0) {
s << color(linkify(html::escape(clean(v, i)).c_str())) << '\n';
} else {
std::stringstream x;
x << string(v[i], 0, 24);
int nr = (i - r);
int last = i + nr - 1;
for (; r < i; r++)
x << '.';
if (1) {
std::stringstream r;
if (nr == 1)
r << "repeat last line";
else
r << "repeats last " << nr << " lines; ends " << string(v[last] + 4, 0, 15);
s << html::a("", r.str(), html::escape(clean(v, i, x.str())));
} else
s << x.str();
s << '\n';
i = last;
}
}
s << "
\n";
}
RamLog::LineIterator::LineIterator(RamLog* ramlog)
: _ramlog(ramlog), _lock(ramlog->_mutex), _nextLineIndex(0) {}
RamLogAppender::RamLogAppender(RamLog* ramlog) : _ramlog(ramlog) {}
RamLogAppender::~RamLogAppender() {}
Status RamLogAppender::append(const logger::MessageEventEphemeral& event) {
std::ostringstream ss;
logger::MessageEventDetailsEncoder encoder;
encoder.encode(event, ss);
_ramlog->write(ss.str());
return Status::OK();
}
// ---------------
// static things
// ---------------
RamLog* RamLog::get(const std::string& name) {
if (!_namedLock) {
// Guaranteed to happen before multi-threaded operation.
_namedLock = new mongo::mutex("RamLog::_namedLock");
}
scoped_lock lk(*_namedLock);
if (!_named) {
// Guaranteed to happen before multi-threaded operation.
_named = new RM();
}
RamLog* result = mapFindWithDefault(*_named, name, static_cast(NULL));
if (!result) {
result = new RamLog(name);
(*_named)[name] = result;
}
return result;
}
RamLog* RamLog::getIfExists(const std::string& name) {
if (!_named)
return NULL;
scoped_lock lk(*_namedLock);
return mapFindWithDefault(*_named, name, static_cast(NULL));
}
void RamLog::getNames(std::vector& names) {
if (!_named)
return;
scoped_lock lk(*_namedLock);
for (RM::iterator i = _named->begin(); i != _named->end(); ++i) {
if (i->second->n)
names.push_back(i->first);
}
}
/**
* Ensures that RamLog::get() is called at least once during single-threaded operation,
* ensuring that _namedLock and _named are initialized safely.
*/
MONGO_INITIALIZER(RamLogCatalog)(InitializerContext*) {
if (!_namedLock) {
if (_named) {
return Status(ErrorCodes::InternalError,
"Inconsistent intiailization of RamLogCatalog.");
}
_namedLock = new mongo::mutex("RamLog::_namedLock");
_named = new RM();
}
return Status::OK();
}
}