248 lines
8.5 KiB
C++
248 lines
8.5 KiB
C++
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
// Date: 2014/09/22 11:57:43
|
|
|
|
#ifndef BVAR_VARIABLE_H
|
|
#define BVAR_VARIABLE_H
|
|
|
|
#include <ostream> // std::ostream
|
|
#include <string> // std::string
|
|
#include <vector> // std::vector
|
|
#include <gflags/gflags_declare.h>
|
|
#include "butil/macros.h" // DISALLOW_COPY_AND_ASSIGN
|
|
#include "butil/strings/string_piece.h" // butil::StringPiece
|
|
|
|
#ifdef BAIDU_INTERNAL
|
|
#include <boost/any.hpp>
|
|
#else
|
|
namespace boost {
|
|
class any;
|
|
}
|
|
#endif
|
|
|
|
namespace bvar {
|
|
|
|
DECLARE_bool(save_series);
|
|
|
|
// Bitwise masks of displayable targets
|
|
enum DisplayFilter {
|
|
DISPLAY_ON_HTML = 1,
|
|
DISPLAY_ON_PLAIN_TEXT = 2,
|
|
DISPLAY_ON_ALL = 3,
|
|
};
|
|
|
|
// Implement this class to write variables into different places.
|
|
// If dump() returns false, Variable::dump_exposed() stops and returns -1.
|
|
class Dumper {
|
|
public:
|
|
virtual ~Dumper() { }
|
|
virtual bool dump(const std::string& name,
|
|
const butil::StringPiece& description) = 0;
|
|
virtual bool dump_comment(const std::string&, const std::string& /*type*/) {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// Options for Variable::dump_exposed().
|
|
struct DumpOptions {
|
|
// Constructed with default options.
|
|
DumpOptions();
|
|
|
|
// If this is true, string-type values will be quoted.
|
|
bool quote_string;
|
|
|
|
// The ? in wildcards. Wildcards in URL need to use another character
|
|
// because ? is reserved.
|
|
char question_mark;
|
|
|
|
// Dump variables with matched display_filter
|
|
DisplayFilter display_filter;
|
|
|
|
// Name matched by these wildcards (or exact names) are kept.
|
|
std::string white_wildcards;
|
|
|
|
// Name matched by these wildcards (or exact names) are skipped.
|
|
std::string black_wildcards;
|
|
};
|
|
|
|
struct SeriesOptions {
|
|
SeriesOptions() : fixed_length(true), test_only(false) {}
|
|
|
|
bool fixed_length; // useless now
|
|
bool test_only;
|
|
};
|
|
|
|
// Base class of all bvar.
|
|
//
|
|
// About thread-safety:
|
|
// bvar is thread-compatible:
|
|
// Namely you can create/destroy/expose/hide or do whatever you want to
|
|
// different bvar simultaneously in different threads.
|
|
// bvar is NOT thread-safe:
|
|
// You should not operate one bvar from different threads simultaneously.
|
|
// If you need to, protect the ops with locks. Similarly with ordinary
|
|
// variables, const methods are thread-safe, namely you can call
|
|
// describe()/get_description()/get_value() etc from diferent threads
|
|
// safely (provided that there's no non-const methods going on).
|
|
class Variable {
|
|
public:
|
|
Variable() {}
|
|
virtual ~Variable();
|
|
|
|
// Implement this method to print the variable into ostream.
|
|
virtual void describe(std::ostream&, bool quote_string) const = 0;
|
|
|
|
// string form of describe().
|
|
std::string get_description() const;
|
|
|
|
#ifdef BAIDU_INTERNAL
|
|
// Get value.
|
|
// If subclass does not override this method, the value is the description
|
|
// and the type is std::string.
|
|
virtual void get_value(boost::any* value) const;
|
|
#endif
|
|
|
|
// Describe saved series as a json-string into the stream.
|
|
// The output will be ploted by flot.js
|
|
// Returns 0 on success, 1 otherwise(this variable does not save series).
|
|
virtual int describe_series(std::ostream&, const SeriesOptions&) const
|
|
{ return 1; }
|
|
|
|
// Expose this variable globally so that it's counted in following
|
|
// functions:
|
|
// list_exposed
|
|
// count_exposed
|
|
// describe_exposed
|
|
// find_exposed
|
|
// Return 0 on success, -1 otherwise.
|
|
int expose(const butil::StringPiece& name,
|
|
DisplayFilter display_filter = DISPLAY_ON_ALL) {
|
|
return expose_impl(butil::StringPiece(), name, display_filter);
|
|
}
|
|
|
|
// Expose this variable with a prefix.
|
|
// Example:
|
|
// namespace foo {
|
|
// namespace bar {
|
|
// class ApplePie {
|
|
// ApplePie() {
|
|
// // foo_bar_apple_pie_error
|
|
// _error.expose_as("foo_bar_apple_pie", "error");
|
|
// }
|
|
// private:
|
|
// bvar::Adder<int> _error;
|
|
// };
|
|
// } // foo
|
|
// } // bar
|
|
// Returns 0 on success, -1 otherwise.
|
|
int expose_as(const butil::StringPiece& prefix,
|
|
const butil::StringPiece& name,
|
|
DisplayFilter display_filter = DISPLAY_ON_ALL) {
|
|
return expose_impl(prefix, name, display_filter);
|
|
}
|
|
|
|
// Hide this variable so that it's not counted in *_exposed functions.
|
|
// Returns false if this variable is already hidden.
|
|
// CAUTION!! Subclasses must call hide() manually to avoid displaying
|
|
// a variable that is just destructing.
|
|
bool hide();
|
|
|
|
// Get exposed name. If this variable is not exposed, the name is empty.
|
|
const std::string& name() const { return _name; }
|
|
|
|
// ====================================================================
|
|
|
|
// Put names of all exposed variables into `names'.
|
|
// If you want to print all variables, you have to go through `names'
|
|
// and call `describe_exposed' on each name. This prevents an iteration
|
|
// from taking the lock too long.
|
|
static void list_exposed(std::vector<std::string>* names,
|
|
DisplayFilter = DISPLAY_ON_ALL);
|
|
|
|
// Get number of exposed variables.
|
|
static size_t count_exposed();
|
|
|
|
// Find an exposed variable by `name' and put its description into `os'.
|
|
// Returns 0 on found, -1 otherwise.
|
|
static int describe_exposed(const std::string& name,
|
|
std::ostream& os,
|
|
bool quote_string = false,
|
|
DisplayFilter = DISPLAY_ON_ALL);
|
|
// String form. Returns empty string when not found.
|
|
static std::string describe_exposed(const std::string& name,
|
|
bool quote_string = false,
|
|
DisplayFilter = DISPLAY_ON_ALL);
|
|
|
|
// Describe saved series of variable `name' as a json-string into `os'.
|
|
// The output will be ploted by flot.js
|
|
// Returns 0 on success, 1 when the variable does not save series, -1
|
|
// otherwise (no variable named so).
|
|
static int describe_series_exposed(const std::string& name,
|
|
std::ostream&,
|
|
const SeriesOptions&);
|
|
|
|
#ifdef BAIDU_INTERNAL
|
|
// Find an exposed variable by `name' and put its value into `value'.
|
|
// Returns 0 on found, -1 otherwise.
|
|
static int get_exposed(const std::string& name, boost::any* value);
|
|
#endif
|
|
|
|
// Find all exposed variables matching `white_wildcards' but
|
|
// `black_wildcards' and send them to `dumper'.
|
|
// Use default options when `options' is NULL.
|
|
// Return number of dumped variables, -1 on error.
|
|
static int dump_exposed(Dumper* dumper, const DumpOptions* options);
|
|
|
|
protected:
|
|
virtual int expose_impl(const butil::StringPiece& prefix,
|
|
const butil::StringPiece& name,
|
|
DisplayFilter display_filter);
|
|
|
|
private:
|
|
std::string _name;
|
|
|
|
// bvar uses TLS, thus copying/assignment need to copy TLS stuff as well,
|
|
// which is heavy. We disable copying/assignment now.
|
|
DISALLOW_COPY_AND_ASSIGN(Variable);
|
|
};
|
|
|
|
// Make name only use lowercased alphabets / digits / underscores, and append
|
|
// the result to `out'.
|
|
// Examples:
|
|
// foo-inl.h -> foo_inl_h
|
|
// foo::bar::Apple -> foo_bar_apple
|
|
// Car_Rot -> car_rot
|
|
// FooBar -> foo_bar
|
|
// RPCTest -> rpctest
|
|
// HELLO -> hello
|
|
void to_underscored_name(std::string* out, const butil::StringPiece& name);
|
|
|
|
} // namespace bvar
|
|
|
|
// Make variables printable.
|
|
namespace std {
|
|
|
|
inline ostream& operator<<(ostream &os, const ::bvar::Variable &var) {
|
|
var.describe(os, false);
|
|
return os;
|
|
}
|
|
|
|
} // namespace std
|
|
|
|
#endif // BVAR_VARIABLE_H
|