mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 09:06:21 +01:00
170 lines
5.3 KiB
C++
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;
|
|
|
|
|
|
}
|