1 // server_status.h
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 #pragma once
34 
35 #include "mongo/db/commands.h"
36 #include "mongo/db/jsobj.h"
37 #include "mongo/db/stats/counters.h"
38 #include "mongo/platform/atomic_word.h"
39 #include <string>
40 
41 namespace mongo {
42 
43 class ServerStatusSection {
44 public:
45     ServerStatusSection(const std::string& sectionName);
~ServerStatusSection()46     virtual ~ServerStatusSection() {}
47 
getSectionName()48     const std::string& getSectionName() const {
49         return _sectionName;
50     }
51 
52     /**
53      * if this returns true, if the user doesn't mention this section
54      * it will be included in the result
55      * if they do : 1, it will be included
56      * if they do : 0, it will not
57      *
58      * examples (section 'foo')
59      *  includeByDefault returning true
60      *     foo : 0 = not included
61      *     foo : 1 = included
62      *     foo missing = included
63      *  includeByDefault returning false
64      *     foo : 0 = not included
65      *     foo : 1 = included
66      *     foo missing = false
67      */
68     virtual bool includeByDefault() const = 0;
69 
70     /**
71      * Adds the privileges that are required to view this section
72      * TODO: Remove this empty default implementation and implement for every section.
73      */
addRequiredPrivileges(std::vector<Privilege> * out)74     virtual void addRequiredPrivileges(std::vector<Privilege>* out){};
75 
76     /**
77      * actually generate the result
78      *
79      * You should either implement this function or appendSection below, but not both. In
80      * most cases you should just implement this function.
81      *
82      * @param configElement the element from the actual command related to this section
83      *                      so if the section is 'foo', this is cmdObj['foo']
84      */
generateSection(OperationContext * opCtx,const BSONElement & configElement)85     virtual BSONObj generateSection(OperationContext* opCtx,
86                                     const BSONElement& configElement) const {
87         return BSONObj{};
88     };
89 
90     /**
91      * This is what gets called by the serverStatus command to append the section to the
92      * command result.
93      *
94      * If you are just implementing a normal ServerStatusSection, then you don't need to
95      * implement this.
96      *
97      * If you are doing something a bit more complicated, you can implement this and have
98      * full control over what gets included in the command result.
99      */
appendSection(OperationContext * opCtx,const BSONElement & configElement,BSONObjBuilder * result)100     virtual void appendSection(OperationContext* opCtx,
101                                const BSONElement& configElement,
102                                BSONObjBuilder* result) const {
103         const auto ret = generateSection(opCtx, configElement);
104         if (ret.isEmpty())
105             return;
106         result->append(getSectionName(), ret);
107     }
108 
109 private:
110     const std::string _sectionName;
111 };
112 
113 class OpCounterServerStatusSection : public ServerStatusSection {
114 public:
115     OpCounterServerStatusSection(const std::string& sectionName, OpCounters* counters);
includeByDefault()116     virtual bool includeByDefault() const {
117         return true;
118     }
119 
120     virtual BSONObj generateSection(OperationContext* opCtx,
121                                     const BSONElement& configElement) const;
122 
123 private:
124     const OpCounters* _counters;
125 };
126 }
127