p;
if ( numBack < numDeltas() )
p.reset( new SnapshotDelta( getPrev(numBack+1) , getPrev(numBack) ) );
return p;
}
const SnapshotData& Snapshots::getPrev( int numBack ) {
int x = _loc - numBack;
if ( x < 0 )
x += _n;
return _snapshots[x];
}
void Snapshots::outputLockInfoHTML( stringstream& ss ) {
scoped_lock lk(_lock);
ss << "\n";
for ( int i=0; i 4100 )
ss << '(' << e / 1000.0 << "s)";
ss << ' ';
}
ss << "
\n";
}
void SnapshotThread::run() {
Client::initThread("snapshotthread");
Client& client = cc();
long long numLoops = 0;
const SnapshotData* prev = 0;
while ( ! inShutdown() ) {
try {
const SnapshotData* s = statsSnapshots.takeSnapshot();
if ( prev && cmdLine.cpu ) {
unsigned long long elapsed = s->_created - prev->_created;
SnapshotDelta d( *prev , *s );
log() << "cpu: elapsed:" << (elapsed/1000) <<" writelock: " << (int)(100*d.percentWriteLocked()) << "%" << endl;
}
prev = s;
}
catch ( std::exception& e ) {
log() << "ERROR in SnapshotThread: " << e.what() << endl;
}
numLoops++;
sleepsecs(4);
}
client.shutdown();
}
using namespace mongoutils::html;
class WriteLockStatus : public WebStatusPlugin {
public:
WriteLockStatus() : WebStatusPlugin( "write lock" , 51 , "% time in write lock, by 4 sec periods" ) {}
virtual void init() {}
virtual void run( stringstream& ss ) {
statsSnapshots.outputLockInfoHTML( ss );
ss << "";
ss << "write locked now: " << (dbMutex.info().isLocked() ? "true" : "false") << "\n";
}
} writeLockStatus;
class DBTopStatus : public WebStatusPlugin {
public:
DBTopStatus() : WebStatusPlugin( "dbtop" , 50 , "(occurences|percent of elapsed)" ) {}
void display( stringstream& ss , double elapsed , const Top::UsageData& usage ) {
ss << "";
ss << usage.count;
ss << " | ";
double per = 100 * ((double)usage.time)/elapsed;
if( per == (int) per )
ss << (int) per;
else
ss << setprecision(1) << fixed << per;
ss << '%';
ss << " | ";
}
void display( stringstream& ss , double elapsed , const string& ns , const Top::CollectionData& data ) {
if ( ns != "TOTAL" && data.total.count == 0 )
return;
ss << "" << ns << " | ";
display( ss , elapsed , data.total );
display( ss , elapsed , data.readLock );
display( ss , elapsed , data.writeLock );
display( ss , elapsed , data.queries );
display( ss , elapsed , data.getmore );
display( ss , elapsed , data.insert );
display( ss , elapsed , data.update );
display( ss , elapsed , data.remove );
ss << "
\n";
}
void run( stringstream& ss ) {
auto_ptr delta = statsSnapshots.computeDelta();
if ( ! delta.get() )
return;
ss << "";
ss << "";
ss << a("http://www.mongodb.org/display/DOCS/Developer+FAQ#DeveloperFAQ-What%27sa%22namespace%22%3F", "namespace") <<
"NS | "
"total | "
"Reads | "
"Writes | "
"Queries | "
"GetMores | "
"Inserts | "
"Updates | "
"Removes | ";
ss << "
\n";
display( ss , (double) delta->elapsed() , "TOTAL" , delta->globalUsageDiff() );
Top::UsageMap usage = delta->collectionUsageDiff();
for ( Top::UsageMap::iterator i=usage.begin(); i != usage.end(); i++ ) {
display( ss , (double) delta->elapsed() , i->first , i->second );
}
ss << "
";
}
virtual void init() {}
} dbtopStatus;
Snapshots statsSnapshots;
SnapshotThread snapshotThread;
}