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