Files
mongo/db/stats/counters.cpp

208 lines
5.7 KiB
C++
Raw Normal View History

2010-02-01 10:38:00 -05:00
// counters.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/>.
*/
2010-01-16 00:50:02 -05:00
2010-04-27 15:27:52 -04:00
#include "pch.h"
2010-02-01 10:38:00 -05:00
#include "../jsobj.h"
#include "counters.h"
2010-01-16 00:50:02 -05:00
namespace mongo {
2011-01-04 00:40:41 -05:00
OpCounters::OpCounters() {
2010-01-16 00:50:02 -05:00
int zero = 0;
BSONObjBuilder b;
b.append( "insert" , zero );
b.append( "query" , zero );
b.append( "update" , zero );
b.append( "delete" , zero );
b.append( "getmore" , zero );
2010-02-11 12:52:26 -05:00
b.append( "command" , zero );
2010-01-16 00:50:02 -05:00
_obj = b.obj();
2010-05-05 16:27:43 -04:00
_insert = (AtomicUInt*)_obj["insert"].value();
_query = (AtomicUInt*)_obj["query"].value();
_update = (AtomicUInt*)_obj["update"].value();
_delete = (AtomicUInt*)_obj["delete"].value();
_getmore = (AtomicUInt*)_obj["getmore"].value();
_command = (AtomicUInt*)_obj["command"].value();
2010-01-16 00:50:02 -05:00
}
2011-01-04 00:40:41 -05:00
void OpCounters::gotOp( int op , bool isCommand ) {
switch ( op ) {
2010-05-05 18:41:59 -04:00
case dbInsert: /*gotInsert();*/ break; // need to handle multi-insert
2011-01-04 00:40:41 -05:00
case dbQuery:
2010-02-11 12:52:26 -05:00
if ( isCommand )
gotCommand();
2011-01-04 00:40:41 -05:00
else
gotQuery();
2010-02-11 12:52:26 -05:00
break;
2011-01-04 00:40:41 -05:00
2010-01-16 08:00:42 -05:00
case dbUpdate: gotUpdate(); break;
case dbDelete: gotDelete(); break;
case dbGetMore: gotGetMore(); break;
case dbKillCursors:
case opReply:
case dbMsg:
break;
2010-01-18 11:06:10 -05:00
default: log() << "OpCounters::gotOp unknown op: " << op << endl;
2010-01-16 08:00:42 -05:00
}
}
2011-01-04 00:40:41 -05:00
BSONObj& OpCounters::getObj() {
const unsigned MAX = 1 << 30;
RARELY {
2011-01-04 00:40:41 -05:00
bool wrap =
_insert->get() > MAX ||
_query->get() > MAX ||
_update->get() > MAX ||
_delete->get() > MAX ||
_getmore->get() > MAX ||
_command->get() > MAX;
if ( wrap ) {
_insert->zero();
_query->zero();
_update->zero();
_delete->zero();
_getmore->zero();
_command->zero();
}
2011-01-04 00:40:41 -05:00
}
2011-01-04 00:40:41 -05:00
return _obj;
}
2011-01-04 00:40:41 -05:00
IndexCounters::IndexCounters() {
_memSupported = _pi.blockCheckSupported();
2011-01-04 00:40:41 -05:00
_btreeMemHits = 0;
_btreeMemMisses = 0;
_btreeAccesses = 0;
2011-01-04 00:40:41 -05:00
_maxAllowed = ( numeric_limits< long long >::max() ) / 2;
_resets = 0;
2010-01-16 08:00:42 -05:00
_sampling = 0;
_samplingrate = 100;
}
2011-01-04 00:40:41 -05:00
void IndexCounters::append( BSONObjBuilder& b ) {
if ( ! _memSupported ) {
b.append( "note" , "not supported on this platform" );
return;
}
BSONObjBuilder bb( b.subobjStart( "btree" ) );
bb.appendNumber( "accesses" , _btreeAccesses );
bb.appendNumber( "hits" , _btreeMemHits );
bb.appendNumber( "misses" , _btreeMemMisses );
2010-02-01 13:56:52 -05:00
bb.append( "resets" , _resets );
2011-01-04 00:40:41 -05:00
bb.append( "missRatio" , (_btreeAccesses ? (_btreeMemMisses / (double)_btreeAccesses) : 0) );
2011-01-04 00:40:41 -05:00
bb.done();
2011-01-04 00:40:41 -05:00
if ( _btreeAccesses > _maxAllowed ) {
_btreeAccesses = 0;
_btreeMemMisses = 0;
_btreeMemHits = 0;
_resets++;
}
}
2011-01-04 00:40:41 -05:00
2010-03-15 16:02:24 -04:00
FlushCounters::FlushCounters()
: _total_time(0)
, _flushes(0)
, _last()
{}
2011-01-04 00:40:41 -05:00
void FlushCounters::flushed(int ms) {
2010-03-15 16:02:24 -04:00
_flushes++;
_total_time += ms;
_last_time = ms;
_last = jsTime();
}
2011-01-04 00:40:41 -05:00
void FlushCounters::append( BSONObjBuilder& b ) {
2010-03-15 16:02:24 -04:00
b.appendNumber( "flushes" , _flushes );
b.appendNumber( "total_ms" , _total_time );
b.appendNumber( "average_ms" , (_flushes ? (_total_time / double(_flushes)) : 0.0) );
b.appendNumber( "last_ms" , _last_time );
b.append("last_finished", _last);
}
2011-01-04 00:40:41 -05:00
void GenericCounter::hit( const string& name , int count ) {
scoped_lock lk( _mutex );
_counts[name]++;
}
2011-01-04 00:40:41 -05:00
BSONObj GenericCounter::getObj() {
BSONObjBuilder b(128);
{
mongo::mutex::scoped_lock lk( _mutex );
2011-01-04 00:40:41 -05:00
for ( map<string,long long>::iterator i=_counts.begin(); i!=_counts.end(); i++ ) {
2010-07-20 12:39:35 -04:00
b.appendNumber( i->first , i->second );
}
}
return b.obj();
}
void NetworkCounter::hit( long long bytesIn , long long bytesOut ) {
2010-11-08 20:45:19 -05:00
const long long MAX = 1ULL << 60;
2010-11-09 00:14:52 -05:00
// don't care about the race as its just a counter
bool overflow = _bytesIn > MAX || _bytesOut > MAX;
2011-01-04 00:40:41 -05:00
if ( overflow ) {
2010-11-09 00:14:52 -05:00
_lock.lock();
_overflows++;
_bytesIn = bytesIn;
_bytesOut = bytesOut;
2010-11-09 00:14:52 -05:00
_requests = 1;
_lock.unlock();
}
else {
2010-11-09 00:14:52 -05:00
_lock.lock();
_bytesIn += bytesIn;
_bytesOut += bytesOut;
2010-11-09 00:14:52 -05:00
_requests++;
2011-01-04 00:40:41 -05:00
_lock.unlock();
}
}
2011-01-04 00:40:41 -05:00
2010-11-09 00:14:52 -05:00
void NetworkCounter::append( BSONObjBuilder& b ) {
_lock.lock();
b.appendNumber( "bytesIn" , _bytesIn );
b.appendNumber( "bytesOut" , _bytesOut );
2010-11-09 00:14:52 -05:00
b.appendNumber( "numRequests" , _requests );
_lock.unlock();
}
2011-01-04 00:40:41 -05:00
2010-01-16 08:00:42 -05:00
2010-01-16 00:50:02 -05:00
OpCounters globalOpCounters;
2010-11-09 17:01:58 -05:00
OpCounters replOpCounters;
IndexCounters globalIndexCounters;
2010-03-15 16:02:24 -04:00
FlushCounters globalFlushCounters;
NetworkCounter networkCounter;
2011-01-04 00:40:41 -05:00
2010-01-16 00:50:02 -05:00
}