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/" 62 opcounters_graph_ = NULL;
64 indexes_graph_ = NULL;
66 std::vector<RRDDataSource> rrds;
67 rrds.push_back(
RRDDataSource(
"insert", RRDDataSource::COUNTER));
68 rrds.push_back(
RRDDataSource(
"query", RRDDataSource::COUNTER));
69 rrds.push_back(
RRDDataSource(
"update", RRDDataSource::COUNTER));
70 rrds.push_back(
RRDDataSource(
"delete", RRDDataSource::COUNTER));
71 rrds.push_back(
RRDDataSource(
"getmore", RRDDataSource::COUNTER));
72 rrds.push_back(
RRDDataSource(
"command", RRDDataSource::COUNTER));
76 rrds.push_back(
RRDDataSource(
"resident", RRDDataSource::GAUGE));
77 rrds.push_back(
RRDDataSource(
"virtual", RRDDataSource::GAUGE));
78 rrds.push_back(
RRDDataSource(
"mapped", RRDDataSource::GAUGE));
82 rrds.push_back(
RRDDataSource(
"accesses", RRDDataSource::COUNTER));
83 rrds.push_back(
RRDDataSource(
"hits", RRDDataSource::COUNTER));
84 rrds.push_back(
RRDDataSource(
"misses", RRDDataSource::COUNTER));
85 rrds.push_back(
RRDDataSource(
"resets", RRDDataSource::COUNTER));
89 rrds.push_back(
RRDDataSource(
"locktime", RRDDataSource::COUNTER));
102 std::vector<RRDGraphDataDefinition> defs;
103 std::vector<RRDGraphElement *> els;
112 els.push_back(
new RRDGraphLine(
"insert", 1,
"FF7200",
"Inserts"));
113 els.push_back(
new RRDGraphGPrint(
"insert", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
114 els.push_back(
new RRDGraphGPrint(
"insert", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
115 els.push_back(
new RRDGraphGPrint(
"insert", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
117 els.push_back(
new RRDGraphLine(
"query", 1,
"503001",
"Queries"));
118 els.push_back(
new RRDGraphGPrint(
"query", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
119 els.push_back(
new RRDGraphGPrint(
"query", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
120 els.push_back(
new RRDGraphGPrint(
"query", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
122 els.push_back(
new RRDGraphLine(
"update", 1,
"EDAC00",
"Updates"));
123 els.push_back(
new RRDGraphGPrint(
"update", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
124 els.push_back(
new RRDGraphGPrint(
"update", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
125 els.push_back(
new RRDGraphGPrint(
"update", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
127 els.push_back(
new RRDGraphLine(
"delete", 1,
"506101",
"Deletes"));
128 els.push_back(
new RRDGraphGPrint(
"delete", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
129 els.push_back(
new RRDGraphGPrint(
"delete", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
130 els.push_back(
new RRDGraphGPrint(
"delete", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
132 els.push_back(
new RRDGraphLine(
"getmore", 1,
"0CCCCC",
"Getmores"));
133 els.push_back(
new RRDGraphGPrint(
"getmore", RRDArchive::LAST,
"Current\\:%8.2lf %s"));
134 els.push_back(
new RRDGraphGPrint(
"getmore", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
135 els.push_back(
new RRDGraphGPrint(
"getmore", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
137 els.push_back(
new RRDGraphLine(
"command", 1,
"53CA05",
"Commands"));
138 els.push_back(
new RRDGraphGPrint(
"command", RRDArchive::LAST,
"Current\\:%8.2lf %s"));
139 els.push_back(
new RRDGraphGPrint(
"command", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
140 els.push_back(
new RRDGraphGPrint(
"command", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
143 "opcounters", opcounters_rrd_,
"MongoDB Op Counters",
"Ops/sec", defs, els);
155 els.push_back(
new RRDGraphArea(
"virtual",
"3B7AD9",
"Virtual"));
156 els.push_back(
new RRDGraphGPrint(
"virtual", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
157 els.push_back(
new RRDGraphGPrint(
"virtual", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
158 els.push_back(
new RRDGraphGPrint(
"virtual", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
160 els.push_back(
new RRDGraphArea(
"mapped",
"6FD1BF",
"Mapped"));
161 els.push_back(
new RRDGraphGPrint(
"mapped", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
162 els.push_back(
new RRDGraphGPrint(
"mapped", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
163 els.push_back(
new RRDGraphGPrint(
"mapped", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
165 els.push_back(
new RRDGraphArea(
"resident",
"0E6E5C",
"Resident"));
166 els.push_back(
new RRDGraphGPrint(
"resident", RRDArchive::LAST,
"Current\\:%8.2lf %s"));
167 els.push_back(
new RRDGraphGPrint(
"resident", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
168 els.push_back(
new RRDGraphGPrint(
"resident", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
171 new RRDGraphDefinition(
"memory", memory_rrd_,
"MongoDB Memory Usage",
"MB", defs, els);
180 els.push_back(
new RRDGraphLine(
"accesses", 1,
"FF7200",
"Accesses"));
181 els.push_back(
new RRDGraphGPrint(
"accesses", RRDArchive::LAST,
"Current\\:%8.2lf %s"));
182 els.push_back(
new RRDGraphGPrint(
"accesses", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
183 els.push_back(
new RRDGraphGPrint(
"accesses", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
185 els.push_back(
new RRDGraphLine(
"hits", 1,
"503001",
"Hits"));
186 els.push_back(
new RRDGraphGPrint(
"hits", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
187 els.push_back(
new RRDGraphGPrint(
"hits", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
188 els.push_back(
new RRDGraphGPrint(
"hits", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
190 els.push_back(
new RRDGraphLine(
"misses", 1,
"EDAC00",
"Misses"));
191 els.push_back(
new RRDGraphGPrint(
"misses", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
192 els.push_back(
new RRDGraphGPrint(
"misses", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
193 els.push_back(
new RRDGraphGPrint(
"misses", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
195 els.push_back(
new RRDGraphLine(
"resets", 1,
"506101",
"Resets"));
196 els.push_back(
new RRDGraphGPrint(
"resets", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
197 els.push_back(
new RRDGraphGPrint(
"resets", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
198 els.push_back(
new RRDGraphGPrint(
"resets", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
213 std::string dbprefix = DB_CONF_PREFIX;
219 "Entry %s is not a string, but of type %s, " 227 if (dbname.find(
".") != std::string::npos) {
233 add_dbstats(i->
path(), dbname);
254 for (DbStatsMap::iterator i = dbstats_.begin(); i != dbstats_.end(); ++i) {
255 DbStatsInfo &info = i->second;
264 delete opcounters_graph_;
265 delete memory_graph_;
266 delete indexes_graph_;
268 delete opcounters_rrd_;
275 MongoRRDThread::add_dbstats(
const char *path, std::string dbname)
277 if (dbstats_.find(path) != dbstats_.end()) {
278 throw Exception(
"Database stats for config %s already monitored", path);
283 std::vector<RRDDataSource> rrds;
284 rrds.push_back(
RRDDataSource(
"collections", RRDDataSource::GAUGE));
285 rrds.push_back(
RRDDataSource(
"objects", RRDDataSource::GAUGE));
286 rrds.push_back(
RRDDataSource(
"avgObjSize", RRDDataSource::GAUGE));
287 rrds.push_back(
RRDDataSource(
"dataSize", RRDDataSource::GAUGE));
288 rrds.push_back(
RRDDataSource(
"storageSize", RRDDataSource::GAUGE));
289 rrds.push_back(
RRDDataSource(
"numExtents", RRDDataSource::GAUGE));
290 rrds.push_back(
RRDDataSource(
"indexes", RRDDataSource::GAUGE));
291 rrds.push_back(
RRDDataSource(
"indexSize", RRDDataSource::GAUGE));
292 rrds.push_back(
RRDDataSource(
"fileSize", RRDDataSource::GAUGE));
294 info.db_name = dbname;
295 info.rrd_name = std::string(
"dbstats_") + dbname;
298 std::vector<RRDGraphDataDefinition> defs;
299 std::vector<RRDGraphElement *> els;
305 els.push_back(
new RRDGraphLine(
"collections", 1,
"FF7200",
"Collections"));
306 els.push_back(
new RRDGraphGPrint(
"collections", RRDArchive::LAST,
"Current\\:%8.2lf %s"));
307 els.push_back(
new RRDGraphGPrint(
"collections", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
308 els.push_back(
new RRDGraphGPrint(
"collections", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
310 els.push_back(
new RRDGraphLine(
"indexes", 1,
"EDAC00",
"Indexes"));
311 els.push_back(
new RRDGraphGPrint(
"indexes", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
312 els.push_back(
new RRDGraphGPrint(
"indexes", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
313 els.push_back(
new RRDGraphGPrint(
"indexes", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
315 els.push_back(
new RRDGraphLine(
"numExtents", 1,
"506101",
"Extents"));
316 els.push_back(
new RRDGraphGPrint(
"numExtents", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
317 els.push_back(
new RRDGraphGPrint(
"numExtents", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
318 els.push_back(
new RRDGraphGPrint(
"numExtents", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
320 std::string g1name = info.rrd_name +
"_collindext";
321 std::string g1title = std::string(
"MongoDB Collections, Indexes, Extents for ") + dbname;
322 info.graph1 =
new RRDGraphDefinition(g1name.c_str(), info.rrd, g1title.c_str(),
"", defs, els);
328 els.push_back(
new RRDGraphLine(
"objects", 1,
"FF7200",
"Objects"));
329 els.push_back(
new RRDGraphGPrint(
"objects", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
330 els.push_back(
new RRDGraphGPrint(
"objects", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
331 els.push_back(
new RRDGraphGPrint(
"objects", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
333 std::string g2name = info.rrd_name +
"_objects";
334 std::string g2title = std::string(
"MongoDB Objects for ") + dbname;
335 info.graph2 =
new RRDGraphDefinition(g2name.c_str(), info.rrd, g2title.c_str(),
"", defs, els);
345 els.push_back(
new RRDGraphLine(
"avgObjSize", 1,
"FF7200",
"Avg Obj Sz"));
346 els.push_back(
new RRDGraphGPrint(
"avgObjSize", RRDArchive::LAST,
"Current\\:%8.2lf %s"));
347 els.push_back(
new RRDGraphGPrint(
"avgObjSize", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
348 els.push_back(
new RRDGraphGPrint(
"avgObjSize", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
350 els.push_back(
new RRDGraphLine(
"dataSize", 1,
"503001",
"Data"));
351 els.push_back(
new RRDGraphGPrint(
"dataSize", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
352 els.push_back(
new RRDGraphGPrint(
"dataSize", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
353 els.push_back(
new RRDGraphGPrint(
"dataSize", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
355 els.push_back(
new RRDGraphLine(
"storageSize", 1,
"EDAC00",
"Storage"));
356 els.push_back(
new RRDGraphGPrint(
"storageSize", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
357 els.push_back(
new RRDGraphGPrint(
"storageSize", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
358 els.push_back(
new RRDGraphGPrint(
"storageSize", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
360 els.push_back(
new RRDGraphLine(
"indexSize", 1,
"506101",
"Index"));
361 els.push_back(
new RRDGraphGPrint(
"indexSize", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
362 els.push_back(
new RRDGraphGPrint(
"indexSize", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
363 els.push_back(
new RRDGraphGPrint(
"indexSize", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
365 els.push_back(
new RRDGraphLine(
"fileSize", 1,
"0CCCCC",
"File"));
366 els.push_back(
new RRDGraphGPrint(
"fileSize", RRDArchive::LAST,
" Current\\:%8.2lf %s"));
367 els.push_back(
new RRDGraphGPrint(
"fileSize", RRDArchive::AVERAGE,
"Average\\:%8.2lf %s"));
368 els.push_back(
new RRDGraphGPrint(
"fileSize", RRDArchive::MAX,
"Maximum\\:%8.2lf %s\\n"));
370 std::string g3name = info.rrd_name +
"_sizes";
371 std::string g3title = std::string(
"MongoDB Sizes for ") + dbname;
372 info.graph3 =
new RRDGraphDefinition(g3name.c_str(), info.rrd, g3title.c_str(),
"Mem", defs, els);
380 dbstats_[dbname] = info;
393 MongoRRDThread::remove_dbstats(
const char *path)
395 if (dbstats_.find(path) != dbstats_.end()) {
396 DbStatsInfo &info = dbstats_[path];
404 dbstats_.erase(path);
415 if (
mongodb_client->simpleCommand(
"admin", &reply,
"serverStatus")) {
416 BSONObj opcounters = reply[
"opcounters"].Obj();
417 int insert, query, update, del, getmore, command;
418 insert = opcounters[
"insert"].Int();
419 query = opcounters[
"query"].Int();
420 update = opcounters[
"update"].Int();
421 del = opcounters[
"delete"].Int();
422 getmore = opcounters[
"getmore"].Int();
423 command = opcounters[
"command"].Int();
427 "opcounters",
"N:%i:%i:%i:%i:%i:%i", insert, query, update, del, getmore, command);
430 "Failed to update opcounters RRD, " 431 "exception follows");
435 BSONObj mem = reply[
"mem"].Obj();
436 int resident, virtmem, mapped;
437 resident = mem[
"resident"].Int();
438 virtmem = mem[
"virtual"].Int();
439 mapped = mem[
"mapped"].Int();
448 BSONObj indexc = reply[
"indexCounters"].Obj()[
"btree"].Obj();
449 int accesses, hits, misses, resets;
450 accesses = indexc[
"accesses"].Int();
451 hits = indexc[
"hits"].Int();
452 misses = indexc[
"misses"].Int();
453 resets = indexc[
"resets"].Int();
459 "Failed to update indexes RRD, " 460 "exception follows");
464 for (DbStatsMap::iterator i = dbstats_.begin(); i != dbstats_.end(); ++i) {
466 if (
mongodb_client->simpleCommand(i->second.db_name, &dbstats,
"dbStats")) {
468 long int collections, objects, numExtents, indexes, dataSize, storageSize, indexSize,
472 collections = dbstats[
"collections"].numberLong();
473 objects = dbstats[
"objects"].numberLong();
474 avgObjSize = dbstats[
"avgObjSize"].Double();
475 dataSize = dbstats[
"dataSize"].numberLong();
476 storageSize = dbstats[
"storageSize"].numberLong();
477 numExtents = dbstats[
"numExtents"].numberLong();
478 indexes = dbstats[
"indexes"].numberLong();
479 indexSize = dbstats[
"indexSize"].numberLong();
480 fileSize = dbstats[
"fileSize"].numberLong();
484 "N:%li:%li:%f:%li:%li:%li:%li:%li:%li",
496 "Failed to update dbstates RRD for " 497 "%s exception follows",
498 i->second.db_name.c_str());
502 }
catch (mongo::MsgAssertionException &ue) {
504 "Failed to update MongoDB RRD for database " 506 i->second.db_name.c_str(),
508 }
catch (mongo::UserException &ue) {
510 "Failed to update MongoDB RRD for database " 512 i->second.db_name.c_str(),
517 "Failed to retrieve db stats for %s: %s",
518 i->second.db_name.c_str(),
527 "Failed to retrieve server status: %s",
531 }
catch (mongo::UserException &e) {
539 MongoRRDThread::config_tag_changed(
const char *new_tag)
548 remove_dbstats(v->
path());
561 MongoRRDThread::config_value_erased(
const char *path)
563 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.
Thread aspect to access MongoDB.
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.