0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 01:21:03 +01:00
mongodb/db/dbwebserver.cpp

204 lines
5.6 KiB
C++
Raw Normal View History

2008-11-30 02:01:58 +01:00
// dbwebserver.cpp
/**
* Copyright (C) 2008 10gen Inc.
2008-12-29 02:28:49 +01:00
*
2008-11-30 02:01:58 +01:00
* 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.
2008-12-29 02:28:49 +01:00
*
2008-11-30 02:01:58 +01:00
* 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.
2008-12-29 02:28:49 +01:00
*
2008-11-30 02:01:58 +01:00
* 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 "stdafx.h"
#include "../util/miniwebserver.h"
#include "db.h"
2008-12-01 03:00:54 +01:00
#include "repl.h"
#include "replset.h"
2008-11-30 02:01:58 +01:00
extern int port;
2008-12-04 20:33:18 +01:00
extern const char *replInfo;
2008-12-15 23:23:54 +01:00
bool getInitialSyncCompleted();
2008-11-30 02:01:58 +01:00
time_t started = time(0);
2008-12-05 22:45:10 +01:00
/*
2008-12-29 02:28:49 +01:00
string toString() {
2008-12-05 22:45:10 +01:00
stringstream ss;
unsigned long long dt = last - start;
ss << dt/1000;
ss << '\t';
ss << timeLocked/1000 << '\t';
if( dt )
ss << (timeLocked*100)/dt << '%';
return ss.str();
}
*/
2008-12-29 02:28:49 +01:00
struct Timing {
Timing() {
start = timeLocked = 0;
}
2008-12-10 22:52:25 +01:00
unsigned long long start, timeLocked;
2008-12-05 22:45:10 +01:00
};
Timing tlast;
const int NStats = 32;
string lockStats[NStats];
unsigned q = 0;
extern bool quiet;
2008-12-05 22:45:10 +01:00
void statsThread() {
2008-12-10 22:52:25 +01:00
unsigned long long timeLastPass = 0;
2008-12-29 02:28:49 +01:00
while ( 1 ) {
{
2008-12-10 22:52:25 +01:00
Timer lktm;
dblock lk;
q = (q+1)%NStats;
Timing timing;
2008-12-10 22:52:25 +01:00
dbMutexInfo.timingInfo(timing.start, timing.timeLocked);
unsigned long long now = curTimeMicros64();
2008-12-29 02:28:49 +01:00
if ( timeLastPass ) {
2008-12-10 22:52:25 +01:00
unsigned long long dt = now - timeLastPass;
unsigned long long dlocked = timing.timeLocked - tlast.timeLocked;
{
stringstream ss;
2008-12-10 22:52:25 +01:00
ss << dt / 1000 << '\t';
ss << dlocked / 1000 << '\t';
2008-12-29 02:28:49 +01:00
if ( dt )
2008-12-10 22:52:25 +01:00
ss << (dlocked*100)/dt << '%';
string s = ss.str();
2008-12-29 02:28:49 +01:00
if ( !quiet )
2008-12-26 02:05:31 +01:00
log() << "cpu: " << s << endl;
lockStats[q] = s;
}
2008-12-05 22:45:10 +01:00
}
2008-12-10 22:52:25 +01:00
timeLastPass = now;
tlast = timing;
2008-12-05 22:45:10 +01:00
}
sleepsecs(4);
2008-12-05 22:45:10 +01:00
}
}
unsigned byLocSize();
bool _bold;
2008-12-29 02:28:49 +01:00
string bold(bool x) {
_bold = x;
return x ? "<b>" : "";
}
2008-12-29 02:28:49 +01:00
string bold() {
return _bold ? "</b>" : "";
}
2008-12-29 02:28:49 +01:00
class DbWebServer : public MiniWebServer {
2008-11-30 02:01:58 +01:00
public:
2008-12-05 22:45:10 +01:00
// caller locks
2008-12-29 02:28:49 +01:00
void doLockedStuff(stringstream& ss) {
ss << "# databases: " << databases.size() << '\n';
2008-12-29 02:28:49 +01:00
if ( database ) {
ss << "curclient: " << database->name;
2008-12-01 03:00:54 +01:00
ss << '\n';
}
ss << bold(byLocSize()>10000) << "Cursors byLoc.size(): " << byLocSize() << bold() << '\n';
2008-12-01 20:55:36 +01:00
ss << "\n<b>replication</b>\n";
2008-12-01 03:00:54 +01:00
ss << "master: " << master << '\n';
ss << "slave: " << slave << '\n';
2008-12-29 02:28:49 +01:00
if ( replPair ) {
2008-12-01 03:00:54 +01:00
ss << "replpair:\n";
ss << replPair->getInfo();
}
2008-12-15 23:23:54 +01:00
bool seemCaughtUp = getInitialSyncCompleted();
2008-12-29 02:28:49 +01:00
if ( !seemCaughtUp ) ss << "<b>";
2008-12-15 23:23:54 +01:00
ss << "initialSyncCompleted: " << seemCaughtUp;
2008-12-29 02:28:49 +01:00
if ( !seemCaughtUp ) ss << "</b>";
2008-12-15 23:23:54 +01:00
ss << '\n';
2008-12-05 22:45:10 +01:00
ss << "\n<b>dt\ttlocked</b>\n";
unsigned i = q;
2008-12-29 02:28:49 +01:00
while ( 1 ) {
2008-12-05 22:45:10 +01:00
ss << lockStats[i] << '\n';
i = (i-1)%NStats;
2008-12-29 02:28:49 +01:00
if ( i == q )
2008-12-05 22:45:10 +01:00
break;
}
2008-12-01 03:00:54 +01:00
}
2008-12-29 02:28:49 +01:00
void doUnlockedStuff(stringstream& ss) {
2008-12-01 03:00:54 +01:00
ss << "port: " << port << '\n';
2008-12-05 22:45:10 +01:00
ss << "dblocked: " << dbMutexInfo.isLocked() << " (initial)\n";
ss << "uptime: " << time(0)-started << " seconds\n";
2008-12-29 02:28:49 +01:00
if ( allDead )
2008-12-01 20:55:36 +01:00
ss << "<b>replication allDead=" << allDead << "</b>\n";
2008-12-05 00:11:25 +01:00
ss << "\nassertions:\n";
2008-12-29 02:28:49 +01:00
for ( int i = 0; i < 4; i++ ) {
if ( lastAssert[i].isSet() ) {
2008-12-05 00:11:25 +01:00
ss << "<b>";
2008-12-29 02:28:49 +01:00
if ( i == 3 ) ss << "usererr";
2008-12-05 00:11:25 +01:00
else ss << i;
ss << "</b>" << ' ' << lastAssert[i].toString();
}
}
ss << "\nreplInfo: " << replInfo << '\n';
2008-12-01 03:00:54 +01:00
}
2008-11-30 02:01:58 +01:00
virtual void doRequest(
const char *rq, // the full request
string url,
// set these and return them:
2008-12-29 02:28:49 +01:00
string& responseMsg,
2008-11-30 02:01:58 +01:00
int& responseCode,
vector<string>& headers // if completely empty, content-type: text/html will be added
2008-12-29 02:28:49 +01:00
)
2008-11-30 02:01:58 +01:00
{
responseCode = 200;
stringstream ss;
2008-12-04 20:33:18 +01:00
ss << "<html><head><title>";
string dbname;
{
stringstream z;
z << "db " << getHostName() << ':' << port << ' ';
dbname = z.str();
}
ss << dbname << "</title></head><body><h2>" << dbname << "</h2><p>\n<pre>";
2008-11-30 02:01:58 +01:00
2008-12-01 03:00:54 +01:00
doUnlockedStuff(ss);
2008-11-30 02:01:58 +01:00
int n = 2000;
2008-12-29 02:28:49 +01:00
Timer t;
while ( 1 ) {
if ( !dbMutexInfo.isLocked() ) {
2008-12-05 22:45:10 +01:00
{
dblock lk;
ss << "time to get dblock: " << t.millis() << "ms\n";
doLockedStuff(ss);
}
2008-11-30 02:01:58 +01:00
break;
}
sleepmillis(1);
2008-12-29 02:28:49 +01:00
if ( --n < 0 ) {
2008-12-05 22:45:10 +01:00
ss << "\n<b>timed out getting dblock</b>\n";
2008-11-30 02:01:58 +01:00
break;
}
}
ss << "</pre></body></html>";
responseMsg = ss.str();
}
};
void webServerThread() {
2008-12-05 22:45:10 +01:00
boost::thread thr(statsThread);
2008-11-30 02:01:58 +01:00
DbWebServer mini;
2008-12-29 02:28:49 +01:00
if ( mini.init(port+1000) )
2008-11-30 02:01:58 +01:00
mini.run();
}