1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef ANDROID_COUNTER_METRIC_H_
17#define ANDROID_COUNTER_METRIC_H_
18
19#include <functional>
20#include <map>
21#include <string>
22
23#include <media/MediaAnalyticsItem.h>
24#include <utils/Log.h>
25
26namespace android {
27
28
29// The CounterMetric class is used to hold counts of operations or events.
30// A CounterMetric can break down counts by a dimension specified by the
31// application. E.g. an application may want to track counts broken out by
32// error code or the size of some parameter.
33//
34// Example:
35//
36//   CounterMetric<status_t> workCounter;
37//   workCounter("workCounterName", "result_status");
38//
39//   status_t err = DoWork();
40//
41//   // Increments the number of times called with the given error code.
42//   workCounter.Increment(err);
43//
44//   std::map<int, int64_t> values;
45//    metric.ExportValues(
46//        [&] (int attribute_value, int64_t value) {
47//             values[attribute_value] = value;
48//        });
49//
50//   // Do something with the exported stat.
51//
52template<typename AttributeType>
53class CounterMetric {
54 public:
55  // Instantiate the counter with the given metric name and
56  // attribute names. |attribute_names| must not be null.
57  CounterMetric(
58      const std::string& metric_name,
59      const std::string& attribute_name)
60          : metric_name_(metric_name),
61            attribute_name_(attribute_name) {}
62
63  // Increment the count of times the operation occurred with this
64  // combination of attributes.
65  void Increment(AttributeType attribute) {
66    if (values_.find(attribute) == values_.end()) {
67      values_[attribute] = 1;
68    } else {
69      values_[attribute] = values_[attribute] + 1;
70    }
71  };
72
73  // Export the metrics to the provided |function|. Each value for Attribute
74  // has a separate count. As such, |function| will be called once per value
75  // of Attribute.
76  void ExportValues(
77      std::function<void (const AttributeType&,
78                          const int64_t count)> function) const {
79    for (auto it = values_.begin(); it != values_.end(); it++) {
80      function(it->first, it->second);
81    }
82  }
83
84  const std::string& metric_name() const { return metric_name_; };
85
86 private:
87  const std::string metric_name_;
88  const std::string attribute_name_;
89  std::map<AttributeType, int64_t> values_;
90};
91
92}  // namespace android
93
94#endif  // ANDROID_COUNTER_METRIC_H_
95