Coverage Report

Created: 2026-09-01 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/bvar/variable.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
// Date: 2014/09/22 11:57:43
19
20
#ifndef  BVAR_VARIABLE_H
21
#define  BVAR_VARIABLE_H
22
23
#include <ostream>                     // std::ostream
24
#include <string>                      // std::string
25
#include <vector>                      // std::vector
26
#include <memory>                      // std::shared_ptr
27
#include <gflags/gflags_declare.h>
28
#include "butil/macros.h"               // DISALLOW_COPY_AND_ASSIGN
29
#include "butil/strings/string_piece.h" // butil::StringPiece
30
#include "bvar/detail/exposed_ref.h"     // detail::ExposedRef
31
32
#ifdef BAIDU_INTERNAL
33
#include <boost/any.hpp>
34
#else
35
namespace boost {
36
class any;
37
}
38
#endif
39
40
namespace bvar {
41
42
DECLARE_bool(save_series);
43
44
#define COMMON_VARIABLE_CONSTRUCTOR(TypeName)                                    \
45
    TypeName() = default;                                                        \
46
    TypeName(const butil::StringPiece& name) {                                   \
47
        this->expose(name);                                                      \
48
    }                                                                            \
49
    TypeName(const butil::StringPiece& prefix, const butil::StringPiece& name) { \
50
        this->expose_as(prefix, name);                                           \
51
    }                                                                            \
52
53
54
// Bitwise masks of displayable targets 
55
enum DisplayFilter {
56
    DISPLAY_ON_HTML = 1,
57
    DISPLAY_ON_PLAIN_TEXT = 2,
58
    DISPLAY_ON_ALL = 3,
59
};
60
61
// Implement this class to write variables into different places.
62
// If dump() returns false, Variable::dump_exposed() stops and returns -1.
63
class Dumper {
64
public:
65
0
    virtual ~Dumper() { }
66
    virtual bool dump(const std::string& name,
67
                      const butil::StringPiece& description) = 0;
68
    // Only for dumping value of multiple dimension var to prometheus service
69
    virtual bool dump_mvar(const std::string& name,
70
0
                           const butil::StringPiece& description) {
71
0
        return true;
72
0
    }
73
    // Only for dumping comment of multiple dimension var to prometheus service
74
0
    virtual bool dump_comment(const std::string&, const std::string& /*type*/) {
75
0
        return true;
76
0
    }
77
};
78
79
// Options for Variable::dump_exposed().
80
struct DumpOptions {
81
    // Constructed with default options.
82
    DumpOptions();
83
84
    // If this is true, string-type values will be quoted.
85
    bool quote_string;
86
87
    // The ? in wildcards. Wildcards in URL need to use another character
88
    // because ? is reserved.
89
    char question_mark;
90
91
    // Dump variables with matched display_filter
92
    DisplayFilter display_filter;
93
94
    // Name matched by these wildcards (or exact names) are kept.
95
    std::string white_wildcards;
96
97
    // Name matched by these wildcards (or exact names) are skipped.
98
    std::string black_wildcards;
99
};
100
101
struct SeriesOptions {
102
0
    SeriesOptions() : fixed_length(true), test_only(false) {}
103
    
104
    bool fixed_length; // useless now
105
    bool test_only;
106
};
107
108
// Base class of all bvar.
109
//
110
// About thread-safety:
111
//   bvar is thread-compatible:
112
//     Namely you can create/destroy/expose/hide or do whatever you want to
113
//     different bvar simultaneously in different threads.
114
//   bvar is NOT thread-safe:
115
//     You should not operate one bvar from different threads simultaneously.
116
//     If you need to, protect the ops with locks. Similarly with ordinary
117
//     variables, const methods are thread-safe, namely you can call
118
//     describe()/get_description()/get_value() etc from diferent threads
119
//     safely (provided that there's no non-const methods going on).
120
class Variable {
121
public:
122
    using SharedExposedRef = detail::SharedExposedRef<Variable>;
123
124
35
    Variable() = default;
125
126
    // bvar uses TLS, thus copying/assignment need to copy TLS stuff as well,
127
    // which is heavy. We disable copying/assignment now.
128
    DISALLOW_COPY_AND_ASSIGN(Variable);
129
130
    virtual ~Variable();
131
132
    // Implement this method to print the variable into ostream.
133
    virtual void describe(std::ostream&, bool quote_string) const = 0;
134
135
    // string form of describe().
136
    std::string get_description() const;
137
138
#ifdef BAIDU_INTERNAL
139
    // Get value.
140
    // If subclass does not override this method, the value is the description
141
    // and the type is std::string.
142
    virtual void get_value(boost::any* value) const;
143
#endif
144
145
    // Describe saved series as a json-string into the stream.
146
    // The output will be ploted by flot.js
147
    // Returns 0 on success, 1 otherwise(this variable does not save series).
148
    virtual int describe_series(std::ostream&, const SeriesOptions&) const
149
0
    { return 1; }
150
151
    // Expose this variable globally so that it's counted in following
152
    // functions:
153
    //   list_exposed
154
    //   count_exposed
155
    //   describe_exposed
156
    //   find_exposed
157
    // Return 0 on success, -1 otherwise.
158
    int expose(const butil::StringPiece& name,
159
31
               DisplayFilter display_filter = DISPLAY_ON_ALL) {
160
31
        return expose_impl(butil::StringPiece(), name, display_filter);
161
31
    }
162
 
163
    // Expose this variable with a prefix.
164
    // Example:
165
    //   namespace foo {
166
    //   namespace bar {
167
    //   class ApplePie {
168
    //       ApplePie() {
169
    //           // foo_bar_apple_pie_error
170
    //           _error.expose_as("foo_bar_apple_pie", "error");
171
    //       }
172
    //   private:
173
    //       bvar::Adder<int> _error;
174
    //   };
175
    //   }  // foo
176
    //   }  // bar
177
    // Returns 0 on success, -1 otherwise.
178
    int expose_as(const butil::StringPiece& prefix,
179
                  const butil::StringPiece& name,
180
0
                  DisplayFilter display_filter = DISPLAY_ON_ALL) {
181
0
        return expose_impl(prefix, name, display_filter);
182
0
    }
183
184
    // Hide this variable so that it's not counted in *_exposed functions.
185
    // Returns false if this variable is already hidden.
186
    // CAUTION!! Subclasses must call hide() manually to avoid displaying
187
    // a variable that is just destructing.
188
    bool hide();
189
190
    // Check if this variable is is_hidden.
191
    bool is_hidden() const;
192
193
    // Get exposed name. If this variable is not exposed, the name is empty.
194
3
    const std::string& name() const { return _name; }
195
196
    // ====================================================================
197
    
198
    // Put names of all exposed variables into `names'.
199
    // If you want to print all variables, you have to go through `names'
200
    // and call `describe_exposed' on each name. This prevents an iteration
201
    // from taking the lock too long.
202
    static void list_exposed(std::vector<std::string>* names,
203
                             DisplayFilter = DISPLAY_ON_ALL);
204
205
    // Get number of exposed variables.
206
    static size_t count_exposed();
207
208
    // Find an exposed variable by `name' and put its description into `os'.
209
    // Returns 0 on found, -1 otherwise.
210
    static int describe_exposed(const std::string& name,
211
                                std::ostream& os,
212
                                bool quote_string = false,
213
                                DisplayFilter = DISPLAY_ON_ALL);
214
    // String form. Returns empty string when not found.
215
    static std::string describe_exposed(const std::string& name,
216
                                        bool quote_string = false,
217
                                        DisplayFilter = DISPLAY_ON_ALL);
218
219
    // Describe saved series of variable `name' as a json-string into `os'.
220
    // The output will be ploted by flot.js
221
    // Returns 0 on success, 1 when the variable does not save series, -1
222
    // otherwise (no variable named so).
223
    static int describe_series_exposed(const std::string& name,
224
                                       std::ostream&,
225
                                       const SeriesOptions&);
226
227
#ifdef BAIDU_INTERNAL
228
    // Find an exposed variable by `name' and put its value into `value'.
229
    // Returns 0 on found, -1 otherwise.
230
    static int get_exposed(const std::string& name, boost::any* value);
231
#endif
232
233
    // Find all exposed variables matching `white_wildcards' but
234
    // `black_wildcards' and send them to `dumper'.
235
    // Use default options when `options' is nullptr.
236
    // Return number of dumped variables, -1 on error.
237
    static int dump_exposed(Dumper* dumper, const DumpOptions* options);
238
239
protected:
240
    virtual int expose_impl(const butil::StringPiece& prefix,
241
                            const butil::StringPiece& name,
242
                            DisplayFilter display_filter);
243
244
private:
245
    std::string _name;
246
    // Shared indirection handle for calling describe() outside the VarMap lock.
247
    SharedExposedRef _ref;
248
};
249
250
// Make name only use lowercased alphabets / digits / underscores, and append
251
// the result to `out'.
252
// Examples:
253
//   foo-inl.h       -> foo_inl_h
254
//   foo::bar::Apple -> foo_bar_apple
255
//   Car_Rot         -> car_rot
256
//   FooBar          -> foo_bar
257
//   RPCTest         -> rpctest
258
//   HELLO           -> hello
259
void to_underscored_name(std::string* out, const butil::StringPiece& name);
260
261
}  // namespace bvar
262
263
// Make variables printable.
264
namespace std {
265
266
0
inline ostream& operator<<(ostream &os, const ::bvar::Variable &var) {
267
0
    var.describe(os, false);
268
0
    return os;
269
0
}
270
271
}  // namespace std
272
273
#endif  // BVAR_VARIABLE_H