summaryrefslogtreecommitdiff
path: root/tools/top.cpp
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2011-09-14 17:08:06 +0200
committerAntonin Kral <a.kral@bobek.cz>2011-09-14 17:08:06 +0200
commit5d342a758c6095b4d30aba0750b54f13b8916f51 (patch)
tree762e9aa84781f5e3b96db2c02d356c29cf0217c0 /tools/top.cpp
parentcbe2d992e9cd1ea66af9fa91df006106775d3073 (diff)
downloadmongodb-5d342a758c6095b4d30aba0750b54f13b8916f51.tar.gz
Imported Upstream version 2.0.0
Diffstat (limited to 'tools/top.cpp')
-rw-r--r--tools/top.cpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/tools/top.cpp b/tools/top.cpp
new file mode 100644
index 0000000..42e4568
--- /dev/null
+++ b/tools/top.cpp
@@ -0,0 +1,196 @@
+// stat.cpp
+
+/**
+* Copyright (C) 2008 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 "pch.h"
+#include "client/dbclient.h"
+#include "db/json.h"
+#include "../util/text.h"
+#include "tool.h"
+#include <fstream>
+#include <iostream>
+#include <boost/program_options.hpp>
+
+namespace po = boost::program_options;
+
+namespace mongo {
+
+ class TopTool : public Tool {
+ public:
+
+ TopTool() : Tool( "top" , REMOTE_SERVER , "admin" ) {
+ _sleep = 1;
+
+ add_hidden_options()
+ ( "sleep" , po::value<int>() , "time to sleep between calls" )
+ ;
+ addPositionArg( "sleep" , 1 );
+
+ _autoreconnect = true;
+ }
+
+ BSONObj getData() {
+ BSONObj out;
+ if ( ! conn().simpleCommand( _db , &out , "top" ) ) {
+ cout << "error: " << out << endl;
+ return BSONObj();
+ }
+ return out.getOwned();
+ }
+
+ void printDiff( BSONObj prev , BSONObj now ) {
+ if ( ! prev["totals"].isABSONObj() ||
+ ! now["totals"].isABSONObj() ) {
+ cout << "." << endl;
+ return;
+ }
+
+ prev = prev["totals"].Obj();
+ now = now["totals"].Obj();
+
+ vector<NSInfo> data;
+
+ unsigned longest = 30;
+
+ BSONObjIterator i( now );
+ while ( i.more() ) {
+ BSONElement e = i.next();
+
+ // invalid, data fixed in 1.8.0
+ if ( e.fieldName()[0] == '?' )
+ continue;
+
+ if ( ! str::contains( e.fieldName() , '.' ) )
+ continue;
+
+ BSONElement old = prev[e.fieldName()];
+ if ( old.eoo() )
+ continue;
+
+ if ( strlen( e.fieldName() ) > longest )
+ longest = strlen(e.fieldName());
+
+ data.push_back( NSInfo( e.fieldName() , old.Obj() , e.Obj() ) );
+ }
+
+ std::sort( data.begin() , data.end() );
+
+ cout << "\n"
+ << setw(longest) << "ns"
+ << "\ttotal "
+ << "\tread "
+ << "\twrite "
+ << "\t\t" << terseCurrentTime()
+ << endl;
+ for ( int i=data.size()-1; i>=0 && data.size() - i < 10 ; i-- ) {
+ cout << setw(longest) << data[i].ns
+ << "\t" << setprecision(3) << data[i].diffTimeMS( "total" ) << "ms"
+ << "\t" << setprecision(3) << data[i].diffTimeMS( "readLock" ) << "ms"
+ << "\t" << setprecision(3) << data[i].diffTimeMS( "writeLock" ) << "ms"
+ << endl;
+ }
+ }
+
+ int run() {
+ _sleep = getParam( "sleep" , _sleep );
+
+ BSONObj prev = getData();
+
+ while ( true ) {
+ sleepsecs( _sleep );
+
+ BSONObj now;
+ try {
+ now = getData();
+ }
+ catch ( std::exception& e ) {
+ cout << "can't get data: " << e.what() << endl;
+ continue;
+ }
+
+ if ( now.isEmpty() )
+ return -2;
+
+ try {
+ printDiff( prev , now );
+ }
+ catch ( AssertionException& e ) {
+ cout << "\nerror: " << e.what() << "\n"
+ << now
+ << endl;
+ }
+
+
+ prev = now;
+ }
+
+ return 0;
+ }
+
+ struct NSInfo {
+ NSInfo( string thens , BSONObj a , BSONObj b ) {
+ ns = thens;
+ prev = a;
+ cur = b;
+
+ timeDiff = diffTime( "total" );
+ }
+
+
+ int diffTimeMS( const char * field ) const {
+ return (int)(diffTime( field ) / 1000);
+ }
+
+ double diffTime( const char * field ) const {
+ return diff( field , "time" );
+ }
+
+ double diffCount( const char * field ) const {
+ return diff( field , "count" );
+ }
+
+ /**
+ * @param field total,readLock, etc...
+ * @param type time or count
+ */
+ double diff( const char * field , const char * type ) const {
+ return cur[field].Obj()[type].number() - prev[field].Obj()[type].number();
+ }
+
+ bool operator<(const NSInfo& r) const {
+ return timeDiff < r.timeDiff;
+ }
+
+ string ns;
+
+ BSONObj prev;
+ BSONObj cur;
+
+ double timeDiff; // time diff between prev and cur
+ };
+
+ private:
+ int _sleep;
+ };
+
+}
+
+int main( int argc , char ** argv ) {
+ mongo::TopTool top;
+ return top.main( argc , argv );
+}
+