From 723a1490f7893771e3f056a2da036a5a9adcb78d Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Tue, 23 Feb 2010 15:21:09 -0500 Subject: [PATCH 1/2] print warning if have full debug enabled --- db/db.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/db.cpp b/db/db.cpp index 978a21bc0ef..4e54dadb94a 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -465,7 +465,7 @@ namespace mongo { log() << "Mongo DB : starting : pid = " << pid << " port = " << cmdLine.port << " dbpath = " << dbpath << " master = " << replSettings.master << " slave = " << (int) replSettings.slave << " " << ( is32bit ? "32" : "64" ) << "-bit " << endl; - + DEV log() << " FULL DEBUG ENABLED " << endl; show_32_warning(); { From 8d572b8fb8997b3071abb461780ed111cec30c6a Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Tue, 23 Feb 2010 15:37:30 -0500 Subject: [PATCH 2/2] mongostat tool --- .gitignore | 1 + SConstruct | 2 +- tools/stat.cpp | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 tools/stat.cpp diff --git a/.gitignore b/.gitignore index 5bd51776e65..0d83f60613d 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ mongoexport mongoimport mongosniff mongobridge +mongostat *.tgz *.zip diff --git a/SConstruct b/SConstruct index 1c07431d822..0fd2abd898c 100644 --- a/SConstruct +++ b/SConstruct @@ -1081,7 +1081,7 @@ Default( mongod ) # tools allToolFiles = commonFiles + coreDbFiles + serverOnlyFiles + [ "client/gridfs.cpp", "tools/tool.cpp" ] -normalTools = [ "dump" , "restore" , "export" , "import" , "files" ] +normalTools = [ "dump" , "restore" , "export" , "import" , "files" , "stat" ] env.Alias( "tools" , [ "mongo" + x for x in normalTools ] ) for x in normalTools: env.Program( "mongo" + x , allToolFiles + [ "tools/" + x + ".cpp" ] ) diff --git a/tools/stat.cpp b/tools/stat.cpp new file mode 100644 index 00000000000..cc4c5e3d456 --- /dev/null +++ b/tools/stat.cpp @@ -0,0 +1,144 @@ +// 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 . +*/ + +#include "stdafx.h" +#include "client/dbclient.h" +#include "db/json.h" + +#include "tool.h" + +#include +#include + +#include + +namespace po = boost::program_options; + +namespace mongo { + + class Stat : public Tool { + public: + + Stat() : Tool( "stat" , false , "admin" ){ + _sleep = 1; + _rowNum = 0; + } + + BSONObj stats(){ + BSONObj out; + if ( ! conn().simpleCommand( _db , &out , "serverStatus" ) ){ + cout << "error: " << out << endl; + return BSONObj(); + } + return out.getOwned(); + } + + double diff( const string& name , const BSONObj& a , const BSONObj& b ){ + BSONElement x = a.getFieldDotted( name.c_str() ); + BSONElement y = b.getFieldDotted( name.c_str() ); + if ( ! x.isNumber() || ! y.isNumber() ) + return -1; + return ( y.number() - x.number() ) / _sleep; + } + + double percent( const char * outof , const char * val , const BSONObj& a , const BSONObj& b ){ + double x = ( b.getFieldDotted( val ).number() - a.getFieldDotted( val ).number() ); + double y = ( b.getFieldDotted( outof ).number() - a.getFieldDotted( outof ).number() ); + if ( y == 0 ) + return 0; + return x / y; + } + + void cellstart( stringstream& ss , string name , unsigned& width ){ + if ( name.size() > width ) + width = name.size(); + if ( _rowNum % 20 == 0 ) + cout << setw(width) << name << " "; + } + + void cell( stringstream& ss , string name , unsigned width , double val ){ + cellstart( ss , name , width ); + ss << setw(width) << val << " "; + } + + void cell( stringstream& ss , string name , unsigned width , int val ){ + cellstart( ss , name , width ); + ss << setw(width) << val << " "; + } + + string doRow( const BSONObj& a , const BSONObj& b ){ + stringstream ss; + + if ( b["opcounters"].type() == Object ){ + BSONObj ax = a["opcounters"].embeddedObject(); + BSONObj bx = b["opcounters"].embeddedObject(); + BSONObjIterator i( bx ); + while ( i.more() ){ + BSONElement e = i.next(); + cell( ss , (string)(e.fieldName()) + "/s" , 6 , (int)diff( e.fieldName() , ax , bx ) ); + } + } + + if ( b.getFieldDotted("mem.supported").trueValue() ){ + BSONObj bx = b["mem"].embeddedObject(); + BSONObjIterator i( bx ); + cell( ss , "mapped" , 6 , bx["mapped"].numberInt() ); + cell( ss , "vsize" , 6 , bx["virtual"].numberInt() ); + cell( ss , "res" , 6 , bx["resident"].numberInt() ); + } + + cell( ss , "% locked" , 5 , percent( "globalLock.totalTime" , "globalLock.lockTime" , a , b ) ); + cell( ss , "% idx miss" , 5 , percent( "indexCounters.btree.accesses" , "indexCounters.btree.misses" , a , b ) ); + + if ( _rowNum % 20 == 0 ) + cout << endl; + _rowNum++; + + return ss.str(); + } + + int run(){ + BSONObj prev = stats(); + if ( prev.isEmpty() ) + return -1; + + while ( 1 ){ + sleepsecs(_sleep); + BSONObj now = stats(); + if ( now.isEmpty() ) + return -2; + + cout << doRow( prev , now ) << endl; + + prev = now; + } + return 0; + } + + + int _sleep; + int _rowNum; + }; + +} + +int main( int argc , char ** argv ) { + mongo::Stat stat; + return stat.main( argc , argv ); +} +