/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 |