1 /* 2 * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef API_TEST_METRICS_METRICS_ACCUMULATOR_H_ 12 #define API_TEST_METRICS_METRICS_ACCUMULATOR_H_ 13 14 #include <map> 15 #include <string> 16 #include <vector> 17 18 #include "absl/strings/string_view.h" 19 #include "api/numerics/samples_stats_counter.h" 20 #include "api/test/metrics/metric.h" 21 #include "api/units/timestamp.h" 22 #include "rtc_base/synchronization/mutex.h" 23 #include "rtc_base/thread_annotations.h" 24 25 namespace webrtc { 26 namespace test { 27 28 // Accumulates metrics' samples internally and provides API to get collected 29 // ones. 30 // 31 // This object is thread safe. 32 class MetricsAccumulator { 33 public: 34 MetricsAccumulator() = default; 35 36 // Adds sample for the specified `metric_name` within specified 37 // `test_case_name`. If it is the first time when this combination of 38 // `metric_name` and `test_case_name` is used, creates a new Metric to collect 39 // samples, otherwise adds a sample to the previously created Metric. 40 // 41 // By default metric will use `Unit::kUnitless` and 42 // `ImprovementDirection::kNeitherIsBetter`. 43 // 44 // `point_metadata` - the metadata to be added to the single data point that 45 // this method adds to the Metric (it is not a metric global metadata). 46 // 47 // Returns true if a new metric was created and false otherwise. 48 bool AddSample(absl::string_view metric_name, 49 absl::string_view test_case_name, 50 double value, 51 Timestamp timestamp, 52 std::map<std::string, std::string> point_metadata = {}); 53 54 // Adds metadata to the metric specified by `metric_name` within specified 55 // `test_case_name`. If such a metric doesn't exist, creates a new one, 56 // otherwise overrides previously recorded values. 57 // 58 // Returns true if a new metric was created and false otherwise. 59 bool AddMetricMetadata( 60 absl::string_view metric_name, 61 absl::string_view test_case_name, 62 Unit unit, 63 ImprovementDirection improvement_direction, 64 std::map<std::string, std::string> metric_metadata = {}); 65 66 // Returns all metrics collected by this accumulator. No order guarantees 67 // provided. 68 std::vector<Metric> GetCollectedMetrics() const; 69 70 private: 71 struct MetricKey { MetricKeyMetricKey72 MetricKey(absl::string_view metric_name, absl::string_view test_case_name) 73 : metric_name(metric_name), test_case_name(test_case_name) {} 74 75 std::string metric_name; 76 std::string test_case_name; 77 }; 78 friend bool operator<(const MetricKey& a, const MetricKey& b); 79 80 struct MetricValue { 81 SamplesStatsCounter counter; 82 Metric metric; 83 }; 84 85 // Gets existing metrics or creates a new one. If metric was created `created` 86 // will be set to true. 87 MetricValue* GetOrCreateMetric(absl::string_view metric_name, 88 absl::string_view test_case_name, 89 bool* created) 90 RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 91 92 mutable Mutex mutex_; 93 std::map<MetricKey, MetricValue> metrics_ RTC_GUARDED_BY(mutex_); 94 }; 95 96 } // namespace test 97 } // namespace webrtc 98 99 #endif // API_TEST_METRICS_METRICS_ACCUMULATOR_H_ 100