diff options
Diffstat (limited to 'src/mongo/logger/ramlog.cpp')
-rw-r--r-- | src/mongo/logger/ramlog.cpp | 362 |
1 files changed, 184 insertions, 178 deletions
diff --git a/src/mongo/logger/ramlog.cpp b/src/mongo/logger/ramlog.cpp index dd2ea4ecc04..dc3c572521c 100644 --- a/src/mongo/logger/ramlog.cpp +++ b/src/mongo/logger/ramlog.cpp @@ -40,221 +40,227 @@ namespace mongo { - using std::string; +using std::string; namespace { - typedef std::map<string,RamLog*> RM; - stdx::mutex* _namedLock = NULL; - RM* _named = NULL; +typedef std::map<string, RamLog*> RM; +stdx::mutex* _namedLock = NULL; +RM* _named = NULL; } // namespace - RamLog::RamLog( const std::string& name ) : _name(name), _totalLinesWritten(0), _lastWrite(0) { - h = 0; - n = 0; - for( int i = 0; i < N; i++ ) - lines[i][C-1] = 0; +RamLog::RamLog(const std::string& name) : _name(name), _totalLinesWritten(0), _lastWrite(0) { + h = 0; + n = 0; + for (int i = 0; i < N; i++) + lines[i][C - 1] = 0; +} + +RamLog::~RamLog() {} + +void RamLog::write(const std::string& str) { + stdx::lock_guard<stdx::mutex> lk(_mutex); + _lastWrite = time(0); + _totalLinesWritten++; + + char* p = lines[(h + n) % N]; + + unsigned sz = str.size(); + if (0 == sz) + return; + if (sz < C) { + if (str.c_str()[sz - 1] == '\n') { + memcpy(p, str.c_str(), sz - 1); + p[sz - 1] = 0; + } else + strcpy(p, str.c_str()); + } else { + memcpy(p, str.c_str(), C - 1); } - RamLog::~RamLog() {} + if (n < N) + n++; + else + h = (h + 1) % N; +} + +time_t RamLog::LineIterator::lastWrite() { + return _ramlog->_lastWrite; +} - void RamLog::write(const std::string& str) { - stdx::lock_guard<stdx::mutex> lk(_mutex); - _lastWrite = time(0); - _totalLinesWritten++; +long long RamLog::LineIterator::getTotalLinesWritten() { + return _ramlog->_totalLinesWritten; +} - char *p = lines[(h+n)%N]; +const char* RamLog::getLine_inlock(unsigned lineNumber) const { + if (lineNumber >= n) + return ""; + return lines[(lineNumber + h) % N]; // h = 0 unless n == N, hence modulo N. +} - unsigned sz = str.size(); - if (0 == sz) return; - if( sz < C ) { - if (str.c_str()[sz-1] == '\n' ) { - memcpy(p, str.c_str(), sz-1); - p[sz-1] = 0; +int RamLog::repeats(const std::vector<const char*>& v, int i) { + for (int j = i - 1; j >= 0 && j + 8 > i; j--) { + if (strcmp(v[i] + 24, v[j] + 24) == 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] + 24, v[j + x] + 24)) + return -1; } - else - strcpy(p, str.c_str()); - } - else { - memcpy(p, str.c_str(), C-1); + return -1; } - - if( n < N ) n++; - else h = (h+1) % N; } + return -1; +} - time_t RamLog::LineIterator::lastWrite() { - return _ramlog->_lastWrite; - } - long long RamLog::LineIterator::getTotalLinesWritten() { - return _ramlog->_totalLinesWritten; - } - - const char* RamLog::getLine_inlock(unsigned lineNumber) const { - if (lineNumber >= n) - return ""; - return lines[(lineNumber + h) % N]; // h = 0 unless n == N, hence modulo N. - } +string RamLog::clean(const std::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]; +} - int RamLog::repeats(const std::vector<const char *>& v, int i) { - for( int j = i-1; j >= 0 && j+8 > i; j-- ) { - if( strcmp(v[i]+24,v[j]+24) == 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]+24,v[j+x]+24) ) return -1; - } - return -1; - } - } - return -1; +string RamLog::color(const std::string& line) { + std::string s = str::after(line, "replSet "); + if (str::startsWith(s, "warning") || str::startsWith(s, "error")) + return html::red(line); + if (str::startsWith(s, "info")) { + if (str::endsWith(s, " up\n")) + return html::green(line); + else if (str::contains(s, " down ") || str::endsWith(s, " down\n")) + return html::yellow(line); + return line; // html::blue(line); } + return line; +} - string RamLog::clean(const std::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]; - } +/* turn http:... into an anchor */ +string RamLog::linkify(const char* s) { + const char* p = s; + const char* h = strstr(p, "http://"); + if (h == 0) + return s; + + const char* sp = h + 7; + while (*sp && *sp != ' ') + sp++; + + string url(h, sp - h); + std::stringstream ss; + ss << string(s, h - s) << "<a href=\"" << url << "\">" << url << "</a>" << sp; + return ss.str(); +} - string RamLog::color(const std::string& line) { - std::string s = str::after(line, "replSet "); - if( str::startsWith(s, "warning") || str::startsWith(s, "error") ) - return html::red(line); - if( str::startsWith(s, "info") ) { - if( str::endsWith(s, " up\n") ) - return html::green(line); - else if( str::contains(s, " down ") || str::endsWith(s, " down\n") ) - return html::yellow(line); - return line; //html::blue(line); +void RamLog::toHTML(std::stringstream& s) { + LineIterator iter(this); + std::vector<const char*> v; + while (iter.more()) + v.push_back(iter.next()); + + s << "<pre>\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; } - - return line; } + s << "</pre>\n"; +} - /* turn http:... into an anchor */ - string RamLog::linkify(const char *s) { - const char *p = s; - const char *h = strstr(p, "http://"); - if( h == 0 ) return s; +RamLog::LineIterator::LineIterator(RamLog* ramlog) + : _ramlog(ramlog), _lock(ramlog->_mutex), _nextLineIndex(0) {} - const char *sp = h + 7; - while( *sp && *sp != ' ' ) sp++; +RamLogAppender::RamLogAppender(RamLog* ramlog) : _ramlog(ramlog) {} +RamLogAppender::~RamLogAppender() {} - string url(h, sp-h); - std::stringstream ss; - ss << string(s, h-s) << "<a href=\"" << url << "\">" << url << "</a>" << sp; - return ss.str(); - } +Status RamLogAppender::append(const logger::MessageEventEphemeral& event) { + std::ostringstream ss; + logger::MessageEventDetailsEncoder encoder; + encoder.encode(event, ss); + _ramlog->write(ss.str()); + return Status::OK(); +} - void RamLog::toHTML(std::stringstream& s) { - LineIterator iter(this); - std::vector<const char*> v; - while (iter.more()) - v.push_back(iter.next()); - - s << "<pre>\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 << "</pre>\n"; - } +// --------------- +// static things +// --------------- - RamLog::LineIterator::LineIterator(RamLog* ramlog) : - _ramlog(ramlog), - _lock(ramlog->_mutex), - _nextLineIndex(0) { +RamLog* RamLog::get(const std::string& name) { + if (!_namedLock) { + // Guaranteed to happen before multi-threaded operation. + _namedLock = new stdx::mutex(); } - 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(); + stdx::lock_guard<stdx::mutex> lk(*_namedLock); + if (!_named) { + // Guaranteed to happen before multi-threaded operation. + _named = new RM(); } - // --------------- - // static things - // --------------- - - RamLog* RamLog::get(const std::string& name) { - if (!_namedLock) { - // Guaranteed to happen before multi-threaded operation. - _namedLock = new stdx::mutex(); - } - - stdx::lock_guard<stdx::mutex> lk( *_namedLock ); - if (!_named) { - // Guaranteed to happen before multi-threaded operation. - _named = new RM(); - } - - RamLog* result = mapFindWithDefault(*_named, name, static_cast<RamLog*>(NULL)); - if (!result) { - result = new RamLog(name); - (*_named)[name] = result; - } - return result; + RamLog* result = mapFindWithDefault(*_named, name, static_cast<RamLog*>(NULL)); + if (!result) { + result = new RamLog(name); + (*_named)[name] = result; } + return result; +} - RamLog* RamLog::getIfExists(const std::string& name) { - if (!_named) - return NULL; - stdx::lock_guard<stdx::mutex> lk(*_namedLock); - return mapFindWithDefault(*_named, name, static_cast<RamLog*>(NULL)); - } +RamLog* RamLog::getIfExists(const std::string& name) { + if (!_named) + return NULL; + stdx::lock_guard<stdx::mutex> lk(*_namedLock); + return mapFindWithDefault(*_named, name, static_cast<RamLog*>(NULL)); +} - void RamLog::getNames( std::vector<string>& names ) { - if ( ! _named ) - return; +void RamLog::getNames(std::vector<string>& names) { + if (!_named) + return; - stdx::lock_guard<stdx::mutex> lk( *_namedLock ); - for ( RM::iterator i=_named->begin(); i!=_named->end(); ++i ) { - if ( i->second->n ) - names.push_back( i->first ); - } + stdx::lock_guard<stdx::mutex> 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 stdx::mutex(); - _named = new RM(); +/** + * 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."); } - - return Status::OK(); + _namedLock = new stdx::mutex(); + _named = new RM(); } + + return Status::OK(); +} } |