0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 09:06:21 +01:00
mongodb/db/stats/top.cpp
2010-02-26 14:38:51 -05:00

170 lines
5.3 KiB
C++

// top.cpp
/*
* Copyright (C) 2010 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
#include "top.h"
#include "../../util/message.h"
#include "../commands.h"
namespace mongo {
Top::UsageData::UsageData( UsageData& older , UsageData& newer )
: time(newer.time-older.time) ,
count(newer.count-older.count)
{
}
Top::CollectionData::CollectionData( CollectionData& older , CollectionData& newer )
: total( older.total , newer.total ) ,
readLock( older.readLock , newer.readLock ) ,
writeLock( older.writeLock , newer.writeLock ) ,
queries( older.queries , newer.queries ) ,
getmore( older.getmore , newer.getmore ) ,
insert( older.insert , newer.insert ) ,
update( older.update , newer.update ) ,
remove( older.remove , newer.remove ),
commands( older.commands , newer.commands )
{
}
void Top::record( const string& ns , int op , int lockType , long long micros , bool command ){
boostlock lk(_lock);
CollectionData& coll = _usage[ns];
_record( coll , op , lockType , micros , command );
_record( _global , op , lockType , micros , command );
}
void Top::_record( CollectionData& c , int op , int lockType , long long micros , bool command ){
c.total.inc( micros );
if ( lockType > 0 )
c.writeLock.inc( micros );
else if ( lockType < 0 )
c.readLock.inc( micros );
switch ( op ){
case 0:
// use 0 for unknown, non-specific
break;
case dbUpdate:
c.update.inc( micros );
break;
case dbInsert:
c.insert.inc( micros );
break;
case dbQuery:
if ( command )
c.commands.inc( micros );
else
c.queries.inc( micros );
break;
case dbGetMore:
c.getmore.inc( micros );
break;
case dbDelete:
c.remove.inc( micros );
break;
case opReply:
case dbMsg:
case dbKillCursors:
log() << "unexpected op in Top::record: " << op << endl;
break;
default:
log() << "unknown op in Top::record: " << op << endl;
}
}
Top::UsageMap Top::cloneMap(){
boostlock lk(_lock);
UsageMap x = _usage;
return x;
}
void Top::append( BSONObjBuilder& b ){
boostlock lk( _lock );
append( b , _usage );
}
void Top::append( BSONObjBuilder& b , const char * name , const UsageData& map ){
BSONObjBuilder bb( b.subobjStart( name ) );
bb.appendIntOrLL( "time" , map.time );
bb.appendIntOrLL( "count" , map.count );
bb.done();
}
void Top::append( BSONObjBuilder& b , const UsageMap& map ){
for ( UsageMap::const_iterator i=map.begin(); i!=map.end(); i++ ){
BSONObjBuilder bb( b.subobjStart( i->first.c_str() ) );
const CollectionData& coll = i->second;
append( b , "total" , coll.total );
append( b , "readLock" , coll.readLock );
append( b , "writeLock" , coll.writeLock );
append( b , "queries" , coll.queries );
append( b , "getmore" , coll.getmore );
append( b , "insert" , coll.insert );
append( b , "update" , coll.update );
append( b , "remove" , coll.remove );
append( b , "commands" , coll.commands );
bb.done();
}
}
class TopCmd : public Command {
public:
TopCmd() : Command( "top" ){}
virtual bool slaveOk(){ return true; }
virtual bool adminOnly(){ return true; }
virtual LockType locktype(){ return READ; }
virtual void help( stringstream& help ) const { help << "usage by collection"; }
virtual bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl){
{
BSONObjBuilder b( result.subobjStart( "totals" ) );
Top::global.append( b );
b.done();
}
return true;
}
} topCmd;
Top Top::global;
TopOld::T TopOld::_snapshotStart = TopOld::currentTime();
TopOld::D TopOld::_snapshotDuration;
TopOld::UsageMap TopOld::_totalUsage;
TopOld::UsageMap TopOld::_snapshotA;
TopOld::UsageMap TopOld::_snapshotB;
TopOld::UsageMap &TopOld::_snapshot = TopOld::_snapshotA;
TopOld::UsageMap &TopOld::_nextSnapshot = TopOld::_snapshotB;
boost::mutex TopOld::topMutex;
}