0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
This commit is contained in:
Aaron 2009-02-09 15:57:30 -05:00
parent 8356bec070
commit 166716bb25
7 changed files with 131 additions and 4 deletions

View File

@ -18,6 +18,7 @@
#include "../stdafx.h"
#include "../util/message.h"
#include "../util/top.h"
namespace mongo {
@ -76,6 +77,7 @@ namespace mongo {
~dblock() {
/* todo: this should be inlined */
dbunlocking();
Top::clientStop();
}
};
@ -129,7 +131,8 @@ namespace mongo {
variables.
*/
assert( dbMutexInfo.isLocked() );
Top::clientStart( ns );
curNs = ns;
string key = getKey( ns, path );
map<string,Database*>::iterator it = databases.find(key);
@ -191,6 +194,7 @@ namespace mongo {
#else
boost::detail::thread::lock_ops<boost::mutex>::unlock(dbMutex);
#endif
Top::clientStop();
}
~dbtemprelease() {
#if BOOST_VERSION >= 103500

View File

@ -67,6 +67,7 @@ namespace mongo {
{
Timer lktm;
dblock lk;
Top::completeSnapshot();
q = (q+1)%NStats;
Timing timing;
dbMutexInfo.timingInfo(timing.start, timing.timeLocked);
@ -127,6 +128,14 @@ namespace mongo {
if ( !seemCaughtUp ) ss << "</b>";
ss << '\n';
ss << "\n<b>DBTOP</b>\n";
ss << "<table border=1><tr align='left'><th>Namespace</th><th>%</th><th>Time</th>";
vector< Top::Usage > usage;
Top::usage( usage );
for( vector< Top::Usage >::iterator i = usage.begin(); i != usage.end(); ++i )
ss << setprecision( 2 ) << fixed << "<tr><td>" << i->ns << "</td><td>" << i->pct << "</td><td>" << i->time << "</td></tr>\n";
ss << "</table>";
ss << "\n<b>dt\ttlocked</b>\n";
unsigned i = q;
while ( 1 ) {

View File

@ -650,5 +650,4 @@ namespace mongo {
::exit(rc);
}
} // namespace mongo

View File

@ -127,5 +127,5 @@ namespace mongo {
boost::thread_specific_ptr< AuthenticationInfo > backup_;
};
};
} // namespace mongo

View File

@ -312,6 +312,7 @@ namespace mongo {
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/program_options.hpp>

103
util/top.h Normal file
View File

@ -0,0 +1,103 @@
// top.h : DB usage monitor.
//
/**
* Copyright (C) 2009 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/>.
*/
namespace mongo {
// No two functions of this class may be called concurrently.
class Top {
public:
typedef boost::posix_time::ptime T;
typedef boost::posix_time::time_duration D;
static void clientStart( const char *client ) {
clientStop();
currentStart_ = currentTime();
current_ = client;
}
static void clientStop() {
if ( currentStart_ == T() )
return;
D d = currentTime() - currentStart_;
size_t dot = current_.rfind( "." );
if ( dot == string::npos || dot != current_.length() - 1 )
recordUsage( current_, d );
while( dot != string::npos ) {
current_ = current_.substr( 0, dot );
recordUsage( current_, d );
dot = current_.rfind( "." );
}
currentStart_ = T();
}
struct Usage { string ns; D time; double pct; };
static void usage( vector< Usage > &res ) {
multimap< D, string, more > sorted;
for( map< string, D >::iterator i = snapshot_.begin(); i != snapshot_.end(); ++i )
sorted.insert( make_pair( i->second, i->first ) );
set< string > already;
for( multimap< D, string >::iterator i = sorted.begin(); i != sorted.end(); ++i ) {
Usage u;
already.insert( i->second );
u.ns = i->second;
u.time = totalUsage_[ u.ns ];
u.pct = snapshotDuration_ != D() ? 100.0 * i->first.ticks() / snapshotDuration_.ticks() : 0;
res.push_back( u );
}
for( map< string, D >::iterator i = totalUsage_.begin(); i != totalUsage_.end(); ++i ) {
if ( already.count( i->first ) != 0 )
continue;
Usage u;
u.ns = i->first;
u.time = i->second;
u.pct = 0;
res.push_back( u );
}
}
static void completeSnapshot() {
if ( &snapshot_ == &snapshotA_ ) {
snapshot_ = snapshotB_;
nextSnapshot_ = snapshotA_;
} else {
snapshot_ = snapshotA_;
nextSnapshot_ = snapshotB_;
}
snapshotDuration_ = currentTime() - snapshotStart_;
snapshotStart_ = currentTime();
nextSnapshot_.clear();
}
private:
typedef map< string, D > UsageMap;
static T currentTime() {
return boost::posix_time::microsec_clock::universal_time();
}
static void recordUsage( const string &client, D duration ) {
totalUsage_[ client ] += duration;
nextSnapshot_[ client ] += duration;
}
struct more { bool operator()( const D &a, const D &b ) { return a > b; } };
static string current_;
static T currentStart_;
static T snapshotStart_;
static D snapshotDuration_;
static UsageMap totalUsage_;
static UsageMap snapshotA_;
static UsageMap snapshotB_;
static UsageMap &snapshot_;
static UsageMap &nextSnapshot_;
};
} // namespace mongo

View File

@ -19,6 +19,7 @@
#include "stdafx.h"
#include "goodies.h"
#include "unittest.h"
#include "top.h"
namespace mongo {
@ -81,5 +82,15 @@ namespace mongo {
}
} utilTest;
string Top::current_;
Top::T Top::currentStart_;
Top::T Top::snapshotStart_ = Top::currentTime();
Top::D Top::snapshotDuration_;
Top::UsageMap Top::totalUsage_;
Top::UsageMap Top::snapshotA_;
Top::UsageMap Top::snapshotB_;
Top::UsageMap &Top::snapshot_ = Top::snapshotA_;
Top::UsageMap &Top::nextSnapshot_ = Top::snapshotB_;
} // namespace mongo