/** * Copyright (C) 2009 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 . * * As a special exception, the copyright holders give permission to link the * code of portions of this program with the OpenSSL library under certain * conditions as described in each individual source file and distribute * linked combinations including the program with the OpenSSL library. You * must comply with the GNU Affero General Public License in all respects for * all of the code used other than as permitted herein. If you modify file(s) * with this exception, you may extend this exception to your version of the * file(s), but you are not obligated to do so. If you do not wish to do so, * delete this exception statement from your version. If you delete this * exception statement from all source files in the program, then also delete * it in the license file. */ #include "mongo/platform/basic.h" #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/curop.h" #include "mongo/db/global_environment_experiment.h" #include "mongo/db/operation_context.h" #include "mongo/db/dbwebserver.h" #include "mongo/util/mongoutils/html.h" namespace mongo { class OperationsDataBuilder : public GlobalEnvironmentExperiment::ProcessOperationContext { public: OperationsDataBuilder(std::stringstream& stringStream) : _stringStream(stringStream) { } virtual void processOpContext(OperationContext* txn) { using namespace html; CurOp& co = *(txn->getCurOp()); _stringStream << "" << txn->getClient()->desc() << ""; tablecell(_stringStream, co.opNum()); tablecell(_stringStream, co.active()); tablecell(_stringStream, txn->lockState()->reportState()); if (co.active()) { tablecell(_stringStream, co.elapsedSeconds()); } else { tablecell(_stringStream, ""); } tablecell(_stringStream, co.getOp()); tablecell(_stringStream, html::escape(co.getNS())); if (co.haveQuery()) { tablecell(_stringStream, html::escape(co.query().toString())); } else { tablecell(_stringStream, ""); } tablecell(_stringStream, co.getRemoteString()); tablecell(_stringStream, co.getMessage()); tablecell(_stringStream, co.getProgressMeter().toString()); _stringStream << "\n"; } private: std::stringstream& _stringStream; }; namespace { class ClientListPlugin : public WebStatusPlugin { public: ClientListPlugin() : WebStatusPlugin( "clients" , 20 ) {} virtual void init() {} virtual void run(OperationContext* txn, std::stringstream& ss ) { using namespace html; ss << "\n"; ss << "" << th( a("", "Connections to the database, both internal and external.", "Client") ) << th( a("http://dochub.mongodb.org/core/viewingandterminatingcurrentoperation", "", "OpId") ) << "" << "" << "" << "" << th( a("http://dochub.mongodb.org/core/whatisanamespace", "", "Namespace") ) << "" << "" << "" << "" << "\n"; OperationsDataBuilder opCtxDataBuilder(ss); getGlobalEnvironment()->forEachOperationContext(&opCtxDataBuilder); ss << "
LockingWaitingSecsRunningOpQueryclientmsgprogress
\n"; } } clientListPlugin; class CommandHelper : public GlobalEnvironmentExperiment::ProcessOperationContext { public: virtual void processOpContext(OperationContext* txn) { BSONObjBuilder b; if ( txn->getClient() ) txn->getClient()->reportState( b ); if ( txn->getCurOp() ) txn->getCurOp()->reportState( &b ); if ( txn->lockState() ) b.append( "lockState", txn->lockState()->reportState() ); if ( txn->recoveryUnit() ) txn->recoveryUnit()->reportState( &b ); array.append( b.obj() ); } BSONArrayBuilder array; }; class CurrentOpContexts : public Command { public: CurrentOpContexts() : Command( "currentOpCtx" ) { } virtual bool isWriteCommandForConfigServer() const { return false; } virtual bool slaveOk() const { return true; } bool run( OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { CommandHelper helper; getGlobalEnvironment()->forEachOperationContext(&helper); result.appendArray( "operations", helper.array.arr() ); return true; } } currentOpContexts; } // namespace } // namespace mongo