diff --git a/db/db.cpp b/db/db.cpp index 0326e3e0244..304775b2c99 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -217,6 +217,7 @@ namespace mongo { Message m; while ( 1 ) { + inPort->clearCounters(); if ( !dbMsgPort->recv(m) ) { if( !cmdLine.quiet ) @@ -275,6 +276,8 @@ sendmore: } } + networkCounter.hit( inPort->getBytesIn() , inPort->getBytesOut() ); + m.reset(); } diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp index 8697b270556..304a846db92 100644 --- a/db/dbcommands.cpp +++ b/db/dbcommands.cpp @@ -397,6 +397,13 @@ namespace mongo { ClientCursor::appendStats( bb ); bb.done(); } + + { + BSONObjBuilder bb( result.subobjStart( "network" ) ); + networkCounter.append( bb ); + bb.done(); + } + timeBuilder.appendNumber( "after counters" , Listener::getElapsedTimeMillis() - start ); diff --git a/db/stats/counters.cpp b/db/stats/counters.cpp index 69861a8ec76..fad0f364c5e 100644 --- a/db/stats/counters.cpp +++ b/db/stats/counters.cpp @@ -144,25 +144,33 @@ namespace mongo { void NetworkCounter::hit( long long bytesIn , long long bytesOut ) { const long long MAX = 1ULL << 60; - mongo::mutex::scoped_lock lk( _mutex ); - if ( _bytesIn > MAX || _bytesOut > MAX ){ + + // don't care about the race as its just a counter + bool overflow = _bytesIn > MAX || _bytesOut > MAX; + + if ( overflow ){ + _lock.lock(); _overflows++; _bytesIn = bytesIn; _bytesOut = bytesOut; + _requests = 1; + _lock.unlock(); } else { + _lock.lock(); _bytesIn += bytesIn; _bytesOut += bytesOut; - + _requests++; + _lock.unlock(); } } - BSONObj NetworkCounter::getObj() { - BSONObjBuilder b( 64 ); - mongo::mutex::scoped_lock lk( _mutex ); + void NetworkCounter::append( BSONObjBuilder& b ) { + _lock.lock(); b.appendNumber( "bytesIn" , _bytesIn ); b.appendNumber( "bytesOut" , _bytesOut ); - return b.obj(); + b.appendNumber( "numRequests" , _requests ); + _lock.unlock(); } diff --git a/db/stats/counters.h b/db/stats/counters.h index 730602c5a01..1af7ba94b98 100644 --- a/db/stats/counters.h +++ b/db/stats/counters.h @@ -21,6 +21,7 @@ #include "../jsobj.h" #include "../../util/message.h" #include "../../util/processinfo.h" +#include "../../util/concurrency/spin_lock.h" namespace mongo { @@ -133,14 +134,17 @@ namespace mongo { class NetworkCounter { public: - NetworkCounter() : _bytesIn(0), _bytesOut(0), _overflows(0) , _mutex( "NetworkCounter" ){} + NetworkCounter() : _bytesIn(0), _bytesOut(0), _requests(0), _overflows(0){} void hit( long long bytesIn , long long bytesOut ); - BSONObj getObj(); + void append( BSONObjBuilder& b ); private: long long _bytesIn; long long _bytesOut; + long long _requests; + long long _overflows; - mongo::mutex _mutex; + + SpinLock _lock; }; extern NetworkCounter networkCounter; diff --git a/s/commands_admin.cpp b/s/commands_admin.cpp index d9c714d86fd..dee072c4a35 100644 --- a/s/commands_admin.cpp +++ b/s/commands_admin.cpp @@ -141,6 +141,13 @@ namespace mongo { asserts.append( "rollovers" , assertionCount.rollovers ); asserts.done(); } + + { + BSONObjBuilder bb( result.subobjStart( "network" ) ); + networkCounter.append( bb ); + bb.done(); + } + return 1; } diff --git a/util/message.cpp b/util/message.cpp index 8c53531d224..915cf7801b6 100644 --- a/util/message.cpp +++ b/util/message.cpp @@ -311,12 +311,12 @@ namespace mongo { ports.closeAll(mask); } - MessagingPort::MessagingPort(int _sock, const SockAddr& _far) : sock(_sock), piggyBackData(0), farEnd(_far), _timeout(), tag(0) { + MessagingPort::MessagingPort(int _sock, const SockAddr& _far) : sock(_sock), piggyBackData(0), farEnd(_far), _timeout(), tag(0), _bytesIn(0), _bytesOut(0) { _logLevel = 0; ports.insert(this); } - MessagingPort::MessagingPort( double timeout, int ll ) : tag(0) { + MessagingPort::MessagingPort( double timeout, int ll ) : tag(0), _bytesIn(0), _bytesOut(0) { _logLevel = ll; ports.insert(this); sock = -1; @@ -452,6 +452,7 @@ namespace mongo { throw; } + _bytesIn += len; m.setData(md, true); return true; @@ -519,6 +520,7 @@ namespace mongo { // sends all data or throws an exception void MessagingPort::send( const char * data , int len, const char *context ) { + _bytesOut += len; while( len > 0 ) { int ret = ::send( sock , data , len , portSendFlags ); if ( ret == -1 ) { diff --git a/util/message.h b/util/message.h index 40c8ffef621..f23f02c01fa 100644 --- a/util/message.h +++ b/util/message.h @@ -128,9 +128,17 @@ namespace mongo { void recv( char * data , int len ); int unsafe_recv( char *buf, int max ); + + void clearCounters() { _bytesIn = 0; _bytesOut = 0; } + long long getBytesIn() const { return _bytesIn; } + long long getBytesOut() const { return _bytesOut; } private: int sock; PiggyBackData * piggyBackData; + + long long _bytesIn; + long long _bytesOut; + public: SockAddr farEnd; double _timeout; diff --git a/util/message_server_port.cpp b/util/message_server_port.cpp index 6365ac7d888..cb789366a25 100644 --- a/util/message_server_port.cpp +++ b/util/message_server_port.cpp @@ -23,6 +23,7 @@ #include "message_server.h" #include "../db/cmdline.h" +#include "../db/stats/counters.h" namespace mongo { @@ -46,6 +47,7 @@ namespace mongo { while ( 1 ){ m.reset(); + p->clearCounters(); if ( ! p->recv(m) ) { if( !cmdLine.quiet ) @@ -55,6 +57,7 @@ namespace mongo { } handler->process( m , p.get() ); + networkCounter.hit( p->getBytesIn() , p->getBytesOut() ); } } catch ( const SocketException& ){