Coverage Report

Created: 2026-04-02 06:41

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