23 #include "mongorrd_thread.h" 25 #include <utils/time/wait.h> 28 #include <mongo/client/dbclient.h> 30 using namespace mongo;
33 #define DB_CONF_PREFIX "/plugins/mongorrd/databases/" 63 __opcounters_graph = NULL;
64 __memory_graph = NULL;
65 __indexes_graph = NULL;
67 std::vector<RRDDataSource> rrds;
68 rrds.push_back(
RRDDataSource(
"insert", RRDDataSource::COUNTER));
69 rrds.push_back(
RRDDataSource(
"query", RRDDataSource::COUNTER));
70 rrds.push_back(
RRDDataSource(
"update", RRDDataSource::COUNTER));
71 rrds.push_back(
RRDDataSource(
"delete", RRDDataSource::COUNTER));
72 rrds.push_back(
RRDDataSource(
"getmore", RRDDataSource::COUNTER));
73 rrds.push_back(
RRDDataSource(
"command", RRDDataSource::COUNTER));
77 rrds.push_back(
RRDDataSource(
"resident", RRDDataSource::GAUGE));
78 rrds.push_back(
RRDDataSource(
"virtual", RRDDataSource::GAUGE));
79 rrds.push_back(
RRDDataSource(
"mapped", RRDDataSource::GAUGE));
83 rrds.push_back(
RRDDataSource(
"accesses", RRDDataSource::COUNTER));
84 rrds.push_back(
RRDDataSource(
"hits", RRDDataSource::COUNTER));
85 rrds.push_back(
RRDDataSource(
"misses", RRDDataSource::COUNTER));
86 rrds.push_back(
RRDDataSource(
"resets", RRDDataSource::COUNTER));
90 rrds.push_back(
RRDDataSource(
"locktime", RRDDataSource::COUNTER));
105 std::vector<RRDGraphDataDefinition> defs;
106 std::vector<RRDGraphElement *> els;
121 els.push_back(
new RRDGraphLine(
"insert", 1,
"FF7200",
"Inserts"));
123 " Current\\:%8.2lf %s"));
125 "Average\\:%8.2lf %s"));
127 "Maximum\\:%8.2lf %s\\n"));
129 els.push_back(
new RRDGraphLine(
"query", 1,
"503001",
"Queries"));
131 " Current\\:%8.2lf %s"));
133 "Average\\:%8.2lf %s"));
135 "Maximum\\:%8.2lf %s\\n"));
137 els.push_back(
new RRDGraphLine(
"update", 1,
"EDAC00",
"Updates"));
139 " Current\\:%8.2lf %s"));
141 "Average\\:%8.2lf %s"));
143 "Maximum\\:%8.2lf %s\\n"));
145 els.push_back(
new RRDGraphLine(
"delete", 1,
"506101",
"Deletes"));
147 " Current\\:%8.2lf %s"));
149 "Average\\:%8.2lf %s"));
151 "Maximum\\:%8.2lf %s\\n"));
153 els.push_back(
new RRDGraphLine(
"getmore", 1,
"0CCCCC",
"Getmores"));
155 "Current\\:%8.2lf %s"));
157 "Average\\:%8.2lf %s"));
159 "Maximum\\:%8.2lf %s\\n"));
161 els.push_back(
new RRDGraphLine(
"command", 1,
"53CA05",
"Commands"));
163 "Current\\:%8.2lf %s"));
165 "Average\\:%8.2lf %s"));
167 "Maximum\\:%8.2lf %s\\n"));
170 "MongoDB Op Counters",
"Ops/sec",
174 defs.clear(); els.clear();
176 __memory_rrd,
"resident"));
178 __memory_rrd,
"virtual"));
180 __memory_rrd,
"mapped"));
185 els.push_back(
new RRDGraphArea(
"virtual",
"3B7AD9",
"Virtual"));
187 " Current\\:%8.2lf %s"));
189 "Average\\:%8.2lf %s"));
191 "Maximum\\:%8.2lf %s\\n"));
193 els.push_back(
new RRDGraphArea(
"mapped",
"6FD1BF",
"Mapped"));
195 " Current\\:%8.2lf %s"));
197 "Average\\:%8.2lf %s"));
199 "Maximum\\:%8.2lf %s\\n"));
201 els.push_back(
new RRDGraphArea(
"resident",
"0E6E5C",
"Resident"));
203 "Current\\:%8.2lf %s"));
205 "Average\\:%8.2lf %s"));
207 "Maximum\\:%8.2lf %s\\n"));
210 "MongoDB Memory Usage",
"MB",
213 defs.clear(); els.clear();
223 els.push_back(
new RRDGraphLine(
"accesses", 1,
"FF7200",
"Accesses"));
225 "Current\\:%8.2lf %s"));
227 "Average\\:%8.2lf %s"));
229 "Maximum\\:%8.2lf %s\\n"));
231 els.push_back(
new RRDGraphLine(
"hits", 1,
"503001",
"Hits"));
233 " Current\\:%8.2lf %s"));
235 "Average\\:%8.2lf %s"));
237 "Maximum\\:%8.2lf %s\\n"));
239 els.push_back(
new RRDGraphLine(
"misses", 1,
"EDAC00",
"Misses"));
241 " Current\\:%8.2lf %s"));
243 "Average\\:%8.2lf %s"));
245 "Maximum\\:%8.2lf %s\\n"));
247 els.push_back(
new RRDGraphLine(
"resets", 1,
"506101",
"Resets"));
249 " Current\\:%8.2lf %s"));
251 "Average\\:%8.2lf %s"));
253 "Maximum\\:%8.2lf %s\\n"));
256 "MongoDB Indexes",
"",
269 std::string dbprefix = DB_CONF_PREFIX;
281 if (dbname.find(
".") != std::string::npos) {
288 add_dbstats(i->
path(), dbname);
310 for (DbStatsMap::iterator i = __dbstats.begin(); i != __dbstats.end(); ++i) {
311 DbStatsInfo &info = i->second;
320 delete __opcounters_graph;
321 delete __memory_graph;
322 delete __indexes_graph;
324 delete __opcounters_rrd;
326 delete __indexes_rrd;
331 MongoRRDThread::add_dbstats(
const char *path, std::string dbname)
333 if (__dbstats.find(path) != __dbstats.end()) {
334 throw Exception(
"Database stats for config %s already monitored", path);
339 std::vector<RRDDataSource> rrds;
340 rrds.push_back(
RRDDataSource(
"collections", RRDDataSource::GAUGE));
341 rrds.push_back(
RRDDataSource(
"objects", RRDDataSource::GAUGE));
342 rrds.push_back(
RRDDataSource(
"avgObjSize", RRDDataSource::GAUGE));
343 rrds.push_back(
RRDDataSource(
"dataSize", RRDDataSource::GAUGE));
344 rrds.push_back(
RRDDataSource(
"storageSize", RRDDataSource::GAUGE));
345 rrds.push_back(
RRDDataSource(
"numExtents", RRDDataSource::GAUGE));
346 rrds.push_back(
RRDDataSource(
"indexes", RRDDataSource::GAUGE));
347 rrds.push_back(
RRDDataSource(
"indexSize", RRDDataSource::GAUGE));
348 rrds.push_back(
RRDDataSource(
"fileSize", RRDDataSource::GAUGE));
350 info.db_name = dbname;
351 info.rrd_name = std::string(
"dbstats_")+dbname;
354 std::vector<RRDGraphDataDefinition> defs;
355 std::vector<RRDGraphElement *> els;
364 els.push_back(
new RRDGraphLine(
"collections", 1,
"FF7200",
"Collections"));
366 "Current\\:%8.2lf %s"));
367 els.push_back(
new RRDGraphGPrint(
"collections", RRDArchive::AVERAGE,
368 "Average\\:%8.2lf %s"));
370 "Maximum\\:%8.2lf %s\\n"));
372 els.push_back(
new RRDGraphLine(
"indexes", 1,
"EDAC00",
"Indexes"));
374 " Current\\:%8.2lf %s"));
376 "Average\\:%8.2lf %s"));
378 "Maximum\\:%8.2lf %s\\n"));
380 els.push_back(
new RRDGraphLine(
"numExtents", 1,
"506101",
"Extents"));
382 " Current\\:%8.2lf %s"));
383 els.push_back(
new RRDGraphGPrint(
"numExtents", RRDArchive::AVERAGE,
384 "Average\\:%8.2lf %s"));
386 "Maximum\\:%8.2lf %s\\n"));
388 std::string g1name = info.rrd_name +
"_collindext";
389 std::string g1title = std::string(
"MongoDB Collections, Indexes, Extents for ")
392 g1title.c_str(),
"", defs, els);
395 defs.clear(); els.clear();
399 els.push_back(
new RRDGraphLine(
"objects", 1,
"FF7200",
"Objects"));
401 " Current\\:%8.2lf %s"));
403 "Average\\:%8.2lf %s"));
405 "Maximum\\:%8.2lf %s\\n"));
407 std::string g2name = info.rrd_name +
"_objects";
408 std::string g2title = std::string(
"MongoDB Objects for ") + dbname;
410 g2title.c_str(),
"", defs, els);
413 defs.clear(); els.clear();
425 els.push_back(
new RRDGraphLine(
"avgObjSize", 1,
"FF7200",
"Avg Obj Sz"));
427 "Current\\:%8.2lf %s"));
428 els.push_back(
new RRDGraphGPrint(
"avgObjSize", RRDArchive::AVERAGE,
429 "Average\\:%8.2lf %s"));
431 "Maximum\\:%8.2lf %s\\n"));
433 els.push_back(
new RRDGraphLine(
"dataSize", 1,
"503001",
"Data"));
435 " Current\\:%8.2lf %s"));
437 "Average\\:%8.2lf %s"));
439 "Maximum\\:%8.2lf %s\\n"));
441 els.push_back(
new RRDGraphLine(
"storageSize", 1,
"EDAC00",
"Storage"));
443 " Current\\:%8.2lf %s"));
444 els.push_back(
new RRDGraphGPrint(
"storageSize", RRDArchive::AVERAGE,
445 "Average\\:%8.2lf %s"));
447 "Maximum\\:%8.2lf %s\\n"));
449 els.push_back(
new RRDGraphLine(
"indexSize", 1,
"506101",
"Index"));
451 " Current\\:%8.2lf %s"));
452 els.push_back(
new RRDGraphGPrint(
"indexSize", RRDArchive::AVERAGE,
453 "Average\\:%8.2lf %s"));
455 "Maximum\\:%8.2lf %s\\n"));
457 els.push_back(
new RRDGraphLine(
"fileSize", 1,
"0CCCCC",
"File"));
459 " Current\\:%8.2lf %s"));
461 "Average\\:%8.2lf %s"));
463 "Maximum\\:%8.2lf %s\\n"));
465 std::string g3name = info.rrd_name +
"_sizes";
466 std::string g3title = std::string(
"MongoDB Sizes for ") + dbname;
468 g3title.c_str(),
"Mem", defs, els);
477 __dbstats[dbname] = info;
479 info.db_name.c_str());
492 MongoRRDThread::remove_dbstats(
const char *path)
494 if (__dbstats.find(path) != __dbstats.end()) {
495 DbStatsInfo &info = __dbstats[path];
503 info.db_name.c_str());
504 __dbstats.erase(path);
516 if (
mongodb_client->simpleCommand(
"admin", &reply,
"serverStatus")) {
517 BSONObj opcounters = reply[
"opcounters"].Obj();
518 int insert, query, update, del, getmore, command;
519 insert = opcounters[
"insert"].Int();
520 query = opcounters[
"query"].Int();
521 update = opcounters[
"update"].Int();
522 del = opcounters[
"delete"].Int();
523 getmore = opcounters[
"getmore"].Int();
524 command = opcounters[
"command"].Int();
528 update, del, getmore, command);
531 "exception follows");
535 BSONObj mem = reply[
"mem"].Obj();
536 int resident, virtmem, mapped;
537 resident = mem[
"resident"].Int();
538 virtmem = mem[
"virtual"].Int();
539 mapped = mem[
"mapped"].Int();
549 BSONObj indexc = reply[
"indexCounters"].Obj()[
"btree"].Obj();
550 int accesses, hits, misses, resets;
551 accesses = indexc[
"accesses"].Int();
552 hits = indexc[
"hits"].Int();
553 misses = indexc[
"misses"].Int();
554 resets = indexc[
"resets"].Int();
558 accesses, hits, misses, resets);
561 "exception follows");
565 for (DbStatsMap::iterator i = __dbstats.begin(); i != __dbstats.end(); ++i) {
567 if (
mongodb_client->simpleCommand(i->second.db_name, &dbstats,
"dbStats"))
569 long int collections, objects, numExtents, indexes, dataSize,
570 storageSize, indexSize, fileSize;
574 collections = dbstats[
"collections"].numberLong();
575 objects = dbstats[
"objects"].numberLong();
576 avgObjSize = dbstats[
"avgObjSize"].Double();
577 dataSize = dbstats[
"dataSize"].numberLong();
578 storageSize = dbstats[
"storageSize"].numberLong();
579 numExtents = dbstats[
"numExtents"].numberLong();
580 indexes = dbstats[
"indexes"].numberLong();
581 indexSize = dbstats[
"indexSize"].numberLong();
582 fileSize = dbstats[
"fileSize"].numberLong();
586 "N:%li:%li:%f:%li:%li:%li:%li:%li:%li", collections,
587 objects, avgObjSize, dataSize, storageSize,
588 numExtents, indexes, indexSize, fileSize);
591 "%s exception follows", i->second.db_name.c_str());
595 }
catch (mongo::MsgAssertionException &ue) {
597 "%s: %s", i->second.db_name.c_str(), ue.what());
598 }
catch (mongo::UserException &ue) {
600 "%s: %s", i->second.db_name.c_str(), ue.what());
604 i->second.db_name.c_str(),
616 }
catch (mongo::UserException &e) {
624 MongoRRDThread::config_tag_changed(
const char *new_tag)
634 remove_dbstats(v->
path());
647 MongoRRDThread::config_value_erased(
const char *path)
650 remove_dbstats(path);
virtual void loop()
Code to execute in the thread.
RRDManager * rrd_manager
Manager class to access RRD features.
virtual void add_rrd(RRDDefinition *rrd_def)=0
Add RRD.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
virtual const char * type() const =0
Type of value.
Fawkes library namespace.
Interface for configuration change handling.
mongo::DBClientBase * mongodb_client
MongoDB client to use to interact with the database.
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
virtual bool next()=0
Check if there is another element and advance to this if possible.
virtual void add_graph(RRDGraphDefinition *rrd_graph_def)=0
Add graph.
Thread class encapsulation of pthreads.
void set_prepfin_conc_loop(bool concurrent=true)
Set concurrent execution of prepare_finalize() and loop().
virtual void add_data(const char *rrd_name, const char *format,...)=0
Add data.
Logger * logger
This is the Logger member used to access the logger.
void wait_systime()
Wait until minimum loop time has been reached in real time.
Clock * clock
By means of this member access to the clock is given.
virtual bool is_string() const =0
Check if current value is a string.
Represent data definition in graph arguments.
Base class for exceptions in Fawkes.
Class representing a graph definition.
virtual void finalize()
Finalize the thread.
virtual void rem_change_handler(ConfigurationChangeHandler *h)
Remove a configuration change handler.
Class to represent a RRD data source.
virtual std::string get_string() const =0
Get string value.
const char * name() const
Get name of thread.
virtual void remove_rrd(RRDDefinition *rrd_def)=0
Remove RRD.
MongoRRDThread()
Constructor.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual const char * path() const =0
Path of value.
void mark_start()
Mark start of loop.
Iterator interface to iterate over config values.
virtual void add_change_handler(ConfigurationChangeHandler *h)
Add a configuration change handler.
Print string inside graph.
Configuration * config
This is the Configuration member used to access the configuration.
virtual ~MongoRRDThread()
Destructor.
virtual void init()
Initialize the thread.