Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
metrics.h
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef IMPALA_UTIL_METRICS_H
16 #define IMPALA_UTIL_METRICS_H
17 
18 #include <map>
19 #include <string>
20 #include <sstream>
21 #include <stack>
22 #include <boost/foreach.hpp>
23 #include <boost/function.hpp>
24 #include <boost/scoped_ptr.hpp>
25 #include <boost/thread/locks.hpp>
26 #include <boost/thread/mutex.hpp>
27 
28 #include "common/logging.h"
29 #include "common/status.h"
30 #include "common/object-pool.h"
31 #include "util/debug-util.h"
32 #include "util/json-util.h"
33 #include "util/pretty-printer.h"
34 #include "util/webserver.h"
35 
36 namespace impala {
37 
41 //
45 //
48 //
50 class Metric {
51  public:
53  virtual ~Metric() {}
54 
57  //
59  virtual void ToJson(rapidjson::Document* document, rapidjson::Value* val) = 0;
60 
63  //
65  virtual void ToLegacyJson(rapidjson::Document* document) = 0;
66 
69  virtual std::string ToHumanReadable() = 0;
70 
71  const std::string& key() const { return key_; }
72  const std::string& description() const { return description_; }
73 
74  protected:
76  const std::string key_;
77 
80  const std::string description_;
81 
82  friend class MetricGroup;
83 
84  Metric(const std::string& key, const std::string& description) :
85  key_(key), description_(description) { }
86 
89  void AddStandardFields(rapidjson::Document* document, rapidjson::Value* val);
90 };
91 
97 //
100 //
103 template<typename T, TMetricKind::type metric_kind=TMetricKind::GAUGE>
104 class SimpleMetric : public Metric {
105  public:
106  SimpleMetric(const std::string& key, const TUnit::type unit,
107  const T& initial_value, const std::string& description = "")
108  : Metric(key, description), unit_(unit), value_(initial_value)
109  { }
110 
111  SimpleMetric(const std::string& key, const TUnit::type unit,
112  const std::string& description = "")
113  : Metric(key, description), unit_(unit) { }
114 
115  virtual ~SimpleMetric() { }
116 
118  T value() {
119  boost::lock_guard<boost::mutex> l(lock_);
120  CalculateValue();
121  return value_;
122  }
123 
125  void set_value(const T& value) {
126  boost::lock_guard<boost::mutex> l(lock_);
127  value_ = value;
128  }
129 
131  void Increment(const T& delta) {
132  DCHECK(kind() != TMetricKind::PROPERTY)
133  << "Can't change value of PROPERTY metric: " << key();
134  DCHECK(kind() != TMetricKind::COUNTER || delta >= 0)
135  << "Can't decrement value of COUNTER metric: " << key();
136  boost::lock_guard<boost::mutex> l(lock_);
137  value_ += delta;
138  }
139 
140  virtual void ToJson(rapidjson::Document* document, rapidjson::Value* val) {
141  rapidjson::Value container(rapidjson::kObjectType);
142  AddStandardFields(document, &container);
143 
144  rapidjson::Value metric_value;
145  ToJsonValue(value(), TUnit::NONE, document, &metric_value);
146  container.AddMember("value", metric_value, document->GetAllocator());
147 
148  rapidjson::Value type_value(PrintTMetricKind(kind()).c_str(),
149  document->GetAllocator());
150  container.AddMember("kind", type_value, document->GetAllocator());
151  rapidjson::Value units(PrintTUnit(unit()).c_str(), document->GetAllocator());
152  container.AddMember("units", units, document->GetAllocator());
153  *val = container;
154  }
155 
156  virtual std::string ToHumanReadable() {
157  return PrettyPrinter::Print(value(), unit());
158  }
159 
160  virtual void ToLegacyJson(rapidjson::Document* document) {
161  rapidjson::Value val;
162  ToJsonValue(value(), TUnit::NONE, document, &val);
163  document->AddMember(key_.c_str(), val, document->GetAllocator());
164  }
165 
166  const TUnit::type unit() const { return unit_; }
167  const TMetricKind::type kind() const { return metric_kind; }
168 
169  protected:
172  //
175  virtual void CalculateValue() { }
176 
178  const TUnit::type unit_;
179 
181  boost::mutex lock_;
182 
185 };
186 
191 //
193 //
197 //
200 class MetricGroup {
201  public:
202  MetricGroup(const std::string& name);
203 
207  //
210  template <typename M>
211  M* RegisterMetric(M* metric) {
212  boost::lock_guard<boost::mutex> l(lock_);
213  DCHECK(!metric->key_.empty());
214  DCHECK(metric_map_.find(metric->key_) == metric_map_.end());
215 
216  M* mt = obj_pool_->Add(metric);
217  metric_map_[metric->key_] = mt;
218  return mt;
219  }
220 
222  template<typename T>
223  SimpleMetric<T>* AddGauge(const std::string& key,
224  const T& value, const TUnit::type unit = TUnit::NONE,
225  const std::string& description = "") {
227  (key, unit, value, description));
228  }
229 
230  template<typename T>
232  const std::string& key, const T& value,
233  const std::string& description = "") {
235  TUnit::NONE, value, description));
236  }
237 
238  template<typename T>
240  const T& value, const TUnit::type unit = TUnit::UNIT,
241  const std::string& description = "") {
242  return RegisterMetric(
243  new SimpleMetric<T, TMetricKind::COUNTER>(key, unit, value, description));
244  }
245 
250  //
252  template <typename M>
253  M* FindMetricForTesting(const std::string& key) {
254  boost::lock_guard<boost::mutex> l(lock_);
255  std::stack<MetricGroup*> groups;
256  groups.push(this);
257  while (!groups.empty()) {
258  MetricGroup* group = groups.top();
259  groups.pop();
260  MetricMap::const_iterator it = group->metric_map_.find(key);
261  if (it != group->metric_map_.end()) return reinterpret_cast<M*>(it->second);
262  BOOST_FOREACH(const ChildGroupMap::value_type& child, group->children_) {
263  groups.push(child.second);
264  }
265  }
266  return NULL;
267  }
268 
271  Status Init(Webserver* webserver);
272 
274  void ToJson(bool include_children, rapidjson::Document* document,
275  rapidjson::Value* out_val);
276 
278  MetricGroup* GetChildGroup(const std::string& name);
279 
281  std::string DebugString();
282 
283  const std::string& name() const { return name_; }
284 
285  private:
287  boost::scoped_ptr<ObjectPool> obj_pool_;
288 
290  std::string name_;
291 
293  boost::mutex lock_;
294 
296  typedef std::map<std::string, Metric*> MetricMap;
298 
300  typedef std::map<std::string, MetricGroup*> ChildGroupMap;
302 
306  void TemplateCallback(const Webserver::ArgumentMap& args,
307  rapidjson::Document* document);
308 
313  rapidjson::Document* document);
314 };
315 
317 typedef class SimpleMetric<int64_t, TMetricKind::GAUGE> IntGauge;
318 typedef class SimpleMetric<uint64_t, TMetricKind::GAUGE> UIntGauge;
319 typedef class SimpleMetric<double, TMetricKind::GAUGE> DoubleGauge;
320 typedef class SimpleMetric<int64_t, TMetricKind::COUNTER> IntCounter;
321 
322 typedef class SimpleMetric<bool, TMetricKind::PROPERTY> BooleanProperty;
323 typedef class SimpleMetric<std::string, TMetricKind::PROPERTY> StringProperty;
324 
325 }
326 
327 #endif // IMPALA_UTIL_METRICS_H
SimpleMetric< T, TMetricKind::COUNTER > * AddCounter(const std::string &key, const T &value, const TUnit::type unit=TUnit::UNIT, const std::string &description="")
Definition: metrics.h:239
class SimpleMetric< std::string, TMetricKind::PROPERTY > StringProperty
Definition: metrics.h:323
const std::string key_
Unique key identifying this metric.
Definition: metrics.h:76
boost::scoped_ptr< ObjectPool > obj_pool_
Pool containing all metric objects.
Definition: metrics.h:287
void AddStandardFields(rapidjson::Document *document, rapidjson::Value *val)
Definition: metrics.cc:46
std::string PrintTUnit(const TUnit::type &type)
virtual void ToLegacyJson(rapidjson::Document *document)
This method is kept for backwards-compatibility with CM5.0.
Definition: metrics.h:160
virtual void ToJson(rapidjson::Document *document, rapidjson::Value *val)
name, value, human_readable, description
Definition: metrics.h:140
SimpleMetric(const std::string &key, const TUnit::type unit, const std::string &description="")
Definition: metrics.h:111
std::map< std::string, MetricGroup * > ChildGroupMap
All child metric groups.
Definition: metrics.h:300
MetricGroup(const std::string &name)
Definition: metrics.cc:55
class SimpleMetric< int64_t, TMetricKind::COUNTER > IntCounter
Definition: metrics.h:320
M * RegisterMetric(M *metric)
Definition: metrics.h:211
MetricGroup * GetChildGroup(const std::string &name)
Creates or returns an already existing child metric group.
Definition: metrics.cc:169
MetricGroups may be organised hierarchically as a tree.
Definition: metrics.h:200
std::map< std::string, Metric * > MetricMap
Contains all Metric objects, indexed by key.
Definition: metrics.h:296
virtual void ToJson(rapidjson::Document *document, rapidjson::Value *val)=0
name, value, human_readable, description
const TUnit::type unit_
Units of this metric.
Definition: metrics.h:178
static std::string Print(bool value, TUnit::type ignored, bool verbose=false)
SimpleMetric(const std::string &key, const TUnit::type unit, const T &initial_value, const std::string &description="")
Definition: metrics.h:106
Status Init(Webserver *webserver)
Definition: metrics.cc:58
std::map< std::string, std::string > ArgumentMap
Definition: webserver.h:36
std::string PrintTMetricKind(const TMetricKind::type &type)
M * FindMetricForTesting(const std::string &key)
Used for testing only.
Definition: metrics.h:253
const std::string description_
Definition: metrics.h:80
virtual void ToLegacyJson(rapidjson::Document *document)=0
This method is kept for backwards-compatibility with CM5.0.
const std::string & name() const
Definition: metrics.h:283
std::string DebugString()
Useful for debuggers, returns the output of CMCompatibleCallback().
Definition: metrics.cc:178
void TemplateCallback(const Webserver::ArgumentMap &args, rapidjson::Document *document)
Definition: metrics.cc:103
SimpleMetric< T, TMetricKind::PROPERTY > * AddProperty(const std::string &key, const T &value, const std::string &description="")
Definition: metrics.h:231
const std::string & key() const
Definition: metrics.h:71
T value()
Returns the current value, updating it if necessary. Thread-safe.
Definition: metrics.h:118
virtual void CalculateValue()
Definition: metrics.h:175
std::string name_
Name of this metric group.
Definition: metrics.h:290
MetricMap metric_map_
Definition: metrics.h:297
void set_value(const T &value)
Sets the current value. Thread-safe.
Definition: metrics.h:125
const std::string & description() const
Definition: metrics.h:72
class SimpleMetric< bool, TMetricKind::PROPERTY > BooleanProperty
Definition: metrics.h:322
class SimpleMetric< double, TMetricKind::GAUGE > DoubleGauge
Definition: metrics.h:319
void ToJson(bool include_children, rapidjson::Document *document, rapidjson::Value *out_val)
Converts this metric group (and optionally all of its children recursively) to JSON.
Definition: metrics.cc:145
SimpleMetric< T > * AddGauge(const std::string &key, const T &value, const TUnit::type unit=TUnit::NONE, const std::string &description="")
Create a gauge metric object with given key and initial value (owned by this object) ...
Definition: metrics.h:223
ChildGroupMap children_
Definition: metrics.h:301
void CMCompatibleCallback(const Webserver::ArgumentMap &args, rapidjson::Document *document)
Definition: metrics.cc:73
boost::mutex lock_
Guards access to value_.
Definition: metrics.h:181
const TUnit::type unit() const
Definition: metrics.h:166
void Increment(const T &delta)
Adds 'delta' to the current value atomically.
Definition: metrics.h:131
virtual std::string ToHumanReadable()=0
virtual ~SimpleMetric()
Definition: metrics.h:115
Metric(const std::string &key, const std::string &description)
Definition: metrics.h:84
TODO: Add ToThrift() for conversion to an RPC-friendly format.
Definition: metrics.h:50
boost::mutex lock_
Guards metric_map_ and children_.
Definition: metrics.h:293
T value_
The current value of the metric.
Definition: metrics.h:184
virtual ~Metric()
Empty virtual destructor.
Definition: metrics.h:53
const TMetricKind::type kind() const
Definition: metrics.h:167
virtual std::string ToHumanReadable()
Definition: metrics.h:156
ToJsonValue(const T &value, const TUnit::type unit, rapidjson::Document *document, rapidjson::Value *out_val)
Definition: json-util.h:33