diff options
Diffstat (limited to 'db/modules/mms.cpp')
-rw-r--r-- | db/modules/mms.cpp | 180 |
1 files changed, 103 insertions, 77 deletions
diff --git a/db/modules/mms.cpp b/db/modules/mms.cpp index 9c00e60..248a4e4 100644 --- a/db/modules/mms.cpp +++ b/db/modules/mms.cpp @@ -1,4 +1,20 @@ // mms.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 "stdafx.h" #include "../db.h" @@ -6,6 +22,7 @@ #include "../module.h" #include "../../util/httpclient.h" #include "../../util/background.h" +#include "../commands.h" namespace po = boost::program_options; @@ -13,24 +30,26 @@ namespace mongo { /** Mongo Monitoring Service if enabled, this runs in the background ands pings mss - */ + */ class MMS : public BackgroundJob , Module { public: MMS() - : Module( "mms" ) , _baseurl( "http://mms.10gen.com/ping/" ) , + : Module( "mms" ) , _baseurl( "" ) , _secsToSleep(1) , _token( "" ) , _name( "" ) { add_options() + ( "mms-url" , po::value<string>()->default_value("http://mms.10gen.com/ping") , "url for mongo monitoring server" ) ( "mms-token" , po::value<string>() , "account token for mongo monitoring server" ) - ( "mms-name" , po::value<string>() , "server name mongo monitoring server" ) - ( "mms-interval" , po::value<int>()->default_value(30) , "ping interval for mongo monitoring server" ) + ( "mms-name" , po::value<string>() , "server name for mongo monitoring server" ) + ( "mms-interval" , po::value<int>()->default_value(30) , "ping interval (in seconds) for mongo monitoring server" ) ; } ~MMS(){} - + void config( program_options::variables_map& params ){ + _baseurl = params["mms-url"].as<string>(); if ( params.count( "mms-token" ) ){ _token = params["mms-token"].as<string>(); } @@ -41,87 +60,94 @@ namespace mongo { } void run(){ - if ( _token.size() == 0 && _name.size() == 0 ){ - log(1) << "mms not configured" << endl; - return; - } - - if ( _token.size() == 0 ){ - log() << "no token for mms - not running" << endl; - return; - } - - if ( _name.size() == 0 ){ - log() << "no name for mms - not running" << endl; - return; - } - - log() << "mms monitor staring... token:" << _token << " name:" << _name << " interval: " << _secsToSleep << endl; - - unsigned long long lastTime = 0; - unsigned long long lastLockTime = 0; - - while ( ! inShutdown() ){ - sleepsecs( _secsToSleep ); - - stringstream url; - url << _baseurl << _token << "?"; - url << "monitor_name=" << _name << "&"; - url << "version=" << versionString << "&"; - url << "git_hash=" << gitVersion() << "&"; + if ( _token.size() == 0 && _name.size() == 0 ){ + log(1) << "mms not configured" << endl; + return; + } - { //percent_locked - unsigned long long time = curTimeMicros64(); - unsigned long long start , lock; - dbMutex.info().getTimingInfo( start , lock ); - if ( lastTime ){ - double timeDiff = (double) (time - lastTime); - double lockDiff = (double) (lock - lastLockTime); - url << "percent_locked=" << (int)ceil( 100 * ( lockDiff / timeDiff ) ) << "&"; - } - lastTime = time; - lastLockTime = lock; + if ( _token.size() == 0 ){ + log() << "no token for mms - not running" << endl; + return; } - - vector< string > dbNames; - getDatabaseNames( dbNames ); - boost::intmax_t totalSize = 0; - for ( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { - boost::intmax_t size = dbSize( i->c_str() ); - totalSize += size; + + if ( _name.size() == 0 ){ + log() << "no name for mms - not running" << endl; + return; } - url << "data_size=" << totalSize / ( 1024 * 1024 ) << "&"; - + log() << "mms monitor staring... token:" << _token << " name:" << _name << " interval: " << _secsToSleep << endl; + Client::initThread( "mms" ); + Client& c = cc(); - /* TODO: - message_operations - update_operations - insert_operations - get_more_operations - delete_operations - kill_cursors_operations - */ - - log(1) << "mms url: " << url.str() << endl; + // TODO: using direct client is bad, but easy for now - try { - HttpClient c; - map<string,string> headers; - stringstream ss; - int rc = c.get( url.str() , headers , ss ); - log(1) << "\t response code: " << rc << endl; - if ( rc != 200 ){ - log() << "mms error response code:" << rc << endl; - log(1) << "mms error body:" << ss.str() << endl; + while ( ! inShutdown() ){ + sleepsecs( _secsToSleep ); + + try { + stringstream url; + url << _baseurl << "?" + << "token=" << _token << "&" + << "name=" << _name << "&" + << "ts=" << time(0) + ; + + BSONObjBuilder bb; + // duplicated so the post has everything + bb.append( "token" , _token ); + bb.append( "name" , _name ); + bb.appendDate( "ts" , jsTime() ); + + // any commands + _add( bb , "buildinfo" ); + _add( bb , "serverStatus" ); + + BSONObj postData = bb.obj(); + + log(1) << "mms url: " << url.str() << "\n\t post: " << postData << endl;; + + HttpClient c; + HttpClient::Result r; + int rc = c.post( url.str() , postData.jsonString() , &r ); + log(1) << "\t response code: " << rc << endl; + if ( rc != 200 ){ + log() << "mms error response code:" << rc << endl; + log(1) << "mms error body:" << r.getEntireResponse() << endl; + } + } + catch ( std::exception& e ){ + log() << "mms exception: " << e.what() << endl; } } - catch ( std::exception& e ){ - log() << "mms get exception: " << e.what() << endl; - } + + c.shutdown(); } + + void _add( BSONObjBuilder& postData , const char* cmd ){ + Command * c = Command::findCommand( cmd ); + if ( ! c ){ + log() << "MMS can't find command: " << cmd << endl; + postData.append( cmd , "can't find command" ); + return; + } + + if ( c->locktype() ){ + log() << "MMS can only use noLocking commands not: " << cmd << endl; + postData.append( cmd , "not noLocking" ); + return; + } + + BSONObj co = BSON( cmd << 1 ); + + string errmsg; + BSONObjBuilder sub; + if ( ! c->run( "admin.$cmd" , co , errmsg , sub , false ) ) + postData.append( cmd , errmsg ); + else + postData.append( cmd , sub.obj() ); } + void init(){ go(); } @@ -135,8 +161,8 @@ namespace mongo { string _token; string _name; - - } /* mms */; + + } /*mms*/ ; } |