1 // server_status_internal.cpp
2 
3 
4 /**
5  *    Copyright (C) 2018-present MongoDB, Inc.
6  *
7  *    This program is free software: you can redistribute it and/or modify
8  *    it under the terms of the Server Side Public License, version 1,
9  *    as published by MongoDB, Inc.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    Server Side Public License for more details.
15  *
16  *    You should have received a copy of the Server Side Public License
17  *    along with this program. If not, see
18  *    <http://www.mongodb.com/licensing/server-side-public-license>.
19  *
20  *    As a special exception, the copyright holders give permission to link the
21  *    code of portions of this program with the OpenSSL library under certain
22  *    conditions as described in each individual source file and distribute
23  *    linked combinations including the program with the OpenSSL library. You
24  *    must comply with the Server Side Public License in all respects for
25  *    all of the code used other than as permitted herein. If you modify file(s)
26  *    with this exception, you may extend this exception to your version of the
27  *    file(s), but you are not obligated to do so. If you do not wish to do so,
28  *    delete this exception statement from your version. If you delete this
29  *    exception statement from all source files in the program, then also delete
30  *    it in the license file.
31  */
32 
33 #include "mongo/db/commands/server_status_internal.h"
34 
35 #include <iostream>
36 
37 #include "mongo/db/commands/server_status_metric.h"
38 #include "mongo/util/mongoutils/str.h"
39 
40 namespace mongo {
41 
42 using std::cerr;
43 using std::endl;
44 using std::map;
45 using std::string;
46 
47 using namespace mongoutils;
48 
49 MetricTree* MetricTree::theMetricTree = NULL;
50 
add(ServerStatusMetric * metric)51 void MetricTree::add(ServerStatusMetric* metric) {
52     string name = metric->getMetricName();
53     if (name[0] == '.')
54         _add(name.substr(1), metric);
55     else
56         _add(str::stream() << "metrics." << name, metric);
57 }
58 
_add(const string & path,ServerStatusMetric * metric)59 void MetricTree::_add(const string& path, ServerStatusMetric* metric) {
60     size_t idx = path.find(".");
61     if (idx == string::npos) {
62         _metrics[path] = metric;
63         return;
64     }
65 
66     string myLevel = path.substr(0, idx);
67     if (_metrics.count(myLevel) > 0) {
68         cerr << "metric conflict on: " << myLevel << endl;
69         fassertFailed(16461);
70     }
71 
72     MetricTree*& sub = _subtrees[myLevel];
73     if (!sub)
74         sub = new MetricTree();
75     sub->_add(path.substr(idx + 1), metric);
76 }
77 
appendTo(BSONObjBuilder & b) const78 void MetricTree::appendTo(BSONObjBuilder& b) const {
79     for (map<string, ServerStatusMetric*>::const_iterator i = _metrics.begin(); i != _metrics.end();
80          ++i) {
81         i->second->appendAtLeaf(b);
82     }
83 
84     for (map<string, MetricTree*>::const_iterator i = _subtrees.begin(); i != _subtrees.end();
85          ++i) {
86         BSONObjBuilder bb(b.subobjStart(i->first));
87         i->second->appendTo(bb);
88         bb.done();
89     }
90 }
91 }
92