summaryrefslogtreecommitdiff
path: root/src/mongo/db/stats/counters.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/stats/counters.cpp')
-rw-r--r--src/mongo/db/stats/counters.cpp207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/mongo/db/stats/counters.cpp b/src/mongo/db/stats/counters.cpp
new file mode 100644
index 00000000000..889e8a86c4c
--- /dev/null
+++ b/src/mongo/db/stats/counters.cpp
@@ -0,0 +1,207 @@
+// 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/>.
+ */
+
+
+#include "pch.h"
+#include "../jsobj.h"
+#include "counters.h"
+
+namespace mongo {
+
+ OpCounters::OpCounters() {
+ 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 );
+ b.append( "command" , zero );
+ _obj = b.obj();
+
+ _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();
+ }
+
+ void OpCounters::gotOp( int op , bool isCommand ) {
+ switch ( op ) {
+ case dbInsert: /*gotInsert();*/ break; // need to handle multi-insert
+ case dbQuery:
+ if ( isCommand )
+ gotCommand();
+ else
+ gotQuery();
+ break;
+
+ case dbUpdate: gotUpdate(); break;
+ case dbDelete: gotDelete(); break;
+ case dbGetMore: gotGetMore(); break;
+ case dbKillCursors:
+ case opReply:
+ case dbMsg:
+ break;
+ default: log() << "OpCounters::gotOp unknown op: " << op << endl;
+ }
+ }
+
+ BSONObj& OpCounters::getObj() {
+ const unsigned MAX = 1 << 30;
+ RARELY {
+ 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();
+ }
+
+ }
+ return _obj;
+ }
+
+ IndexCounters::IndexCounters() {
+ _memSupported = _pi.blockCheckSupported();
+
+ _btreeMemHits = 0;
+ _btreeMemMisses = 0;
+ _btreeAccesses = 0;
+
+
+ _maxAllowed = ( numeric_limits< long long >::max() ) / 2;
+ _resets = 0;
+
+ _sampling = 0;
+ _samplingrate = 100;
+ }
+
+ 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 );
+
+ bb.append( "resets" , _resets );
+
+ bb.append( "missRatio" , (_btreeAccesses ? (_btreeMemMisses / (double)_btreeAccesses) : 0) );
+
+ bb.done();
+
+ if ( _btreeAccesses > _maxAllowed ) {
+ _btreeAccesses = 0;
+ _btreeMemMisses = 0;
+ _btreeMemHits = 0;
+ _resets++;
+ }
+ }
+
+ FlushCounters::FlushCounters()
+ : _total_time(0)
+ , _flushes(0)
+ , _last()
+ {}
+
+ void FlushCounters::flushed(int ms) {
+ _flushes++;
+ _total_time += ms;
+ _last_time = ms;
+ _last = jsTime();
+ }
+
+ void FlushCounters::append( BSONObjBuilder& b ) {
+ 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);
+ }
+
+
+ void GenericCounter::hit( const string& name , int count ) {
+ scoped_lock lk( _mutex );
+ _counts[name]++;
+ }
+
+ BSONObj GenericCounter::getObj() {
+ BSONObjBuilder b(128);
+ {
+ mongo::mutex::scoped_lock lk( _mutex );
+ for ( map<string,long long>::iterator i=_counts.begin(); i!=_counts.end(); i++ ) {
+ b.appendNumber( i->first , i->second );
+ }
+ }
+ return b.obj();
+ }
+
+
+ void NetworkCounter::hit( long long bytesIn , long long bytesOut ) {
+ const long long MAX = 1ULL << 60;
+
+ // 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();
+ }
+ }
+
+ void NetworkCounter::append( BSONObjBuilder& b ) {
+ _lock.lock();
+ b.appendNumber( "bytesIn" , _bytesIn );
+ b.appendNumber( "bytesOut" , _bytesOut );
+ b.appendNumber( "numRequests" , _requests );
+ _lock.unlock();
+ }
+
+
+ OpCounters globalOpCounters;
+ OpCounters replOpCounters;
+ IndexCounters globalIndexCounters;
+ FlushCounters globalFlushCounters;
+ NetworkCounter networkCounter;
+
+}