| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromecast/base/metrics/grouped_histogram.h" | 5 #include "chromecast/base/metrics/grouped_histogram.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/metrics/statistics_recorder.h" | 14 #include "base/metrics/statistics_recorder.h" |
| 15 #include "base/strings/string_piece.h" |
| 15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 16 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
| 17 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 18 | 19 |
| 19 namespace chromecast { | 20 namespace chromecast { |
| 20 namespace metrics { | 21 namespace metrics { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 const char kAppNameErrorNoApp[] = "ERROR_NO_APP_REGISTERED"; | 25 const char kAppNameErrorNoApp[] = "ERROR_NO_APP_REGISTERED"; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 1000 * 10, | 81 1000 * 10, |
| 81 50, | 82 50, |
| 82 }, | 83 }, |
| 83 }; | 84 }; |
| 84 | 85 |
| 85 // This class is used to override a Histogram to generate per-app metrics. | 86 // This class is used to override a Histogram to generate per-app metrics. |
| 86 // It intercepts calls to Add() for a given metric and generates new metrics | 87 // It intercepts calls to Add() for a given metric and generates new metrics |
| 87 // of the form "<metric-name>.<app-name>". | 88 // of the form "<metric-name>.<app-name>". |
| 88 class GroupedHistogram : public base::Histogram { | 89 class GroupedHistogram : public base::Histogram { |
| 89 public: | 90 public: |
| 90 GroupedHistogram(const std::string& metric_to_override, | 91 GroupedHistogram(const char* metric_to_override, |
| 91 Sample minimum, | 92 Sample minimum, |
| 92 Sample maximum, | 93 Sample maximum, |
| 93 const base::BucketRanges* ranges) | 94 const base::BucketRanges* ranges) |
| 94 : Histogram(metric_to_override, minimum, maximum, ranges), | 95 : Histogram(metric_to_override, minimum, maximum, ranges), |
| 95 metric_to_group_(metric_to_override), | |
| 96 minimum_(minimum), | 96 minimum_(minimum), |
| 97 maximum_(maximum), | 97 maximum_(maximum), |
| 98 bucket_count_(ranges->bucket_count()) { | 98 bucket_count_(ranges->bucket_count()) { |
| 99 } | 99 } |
| 100 | 100 |
| 101 ~GroupedHistogram() override { | 101 ~GroupedHistogram() override { |
| 102 } | 102 } |
| 103 | 103 |
| 104 // base::Histogram implementation: | 104 // base::Histogram implementation: |
| 105 void Add(Sample value) override { | 105 void Add(Sample value) override { |
| 106 Histogram::Add(value); | 106 Histogram::Add(value); |
| 107 |
| 108 // Note: This is very inefficient. Fetching the app name (which has a lock) |
| 109 // plus doing a search by name with FactoryGet (which also has a lock) makes |
| 110 // incrementing a metric relatively slow. |
| 107 std::string name(base::StringPrintf("%s.%s", | 111 std::string name(base::StringPrintf("%s.%s", |
| 108 histogram_name().c_str(), | 112 histogram_name(), |
| 109 GetAppName().c_str())); | 113 GetAppName().c_str())); |
| 110 HistogramBase* grouped_histogram = | 114 HistogramBase* grouped_histogram = |
| 111 base::Histogram::FactoryGet(name, | 115 base::Histogram::FactoryGet(name, |
| 112 minimum_, | 116 minimum_, |
| 113 maximum_, | 117 maximum_, |
| 114 bucket_count_, | 118 bucket_count_, |
| 115 flags()); | 119 flags()); |
| 116 DCHECK(grouped_histogram); | 120 DCHECK(grouped_histogram); |
| 117 grouped_histogram->Add(value); | 121 grouped_histogram->Add(value); |
| 118 } | 122 } |
| 119 | 123 |
| 120 private: | 124 private: |
| 121 // Saved construction arguments for reconstructing the Histogram later (with | 125 // Saved construction arguments for reconstructing the Histogram later (with |
| 122 // a suffixed app name). | 126 // a suffixed app name). |
| 123 std::string metric_to_group_; | |
| 124 Sample minimum_; | 127 Sample minimum_; |
| 125 Sample maximum_; | 128 Sample maximum_; |
| 126 uint32_t bucket_count_; | 129 uint32_t bucket_count_; |
| 127 | 130 |
| 128 DISALLOW_COPY_AND_ASSIGN(GroupedHistogram); | 131 DISALLOW_COPY_AND_ASSIGN(GroupedHistogram); |
| 129 }; | 132 }; |
| 130 | 133 |
| 131 // Registers a GroupedHistogram with StatisticsRecorder. Must be called | 134 // Registers a GroupedHistogram with StatisticsRecorder. Must be called |
| 132 // before any Histogram of the same name has been used. | 135 // before any Histogram of the same name has been used. |
| 133 // It acts similarly to Histogram::FactoryGet but checks that | 136 // It acts similarly to Histogram::FactoryGet but checks that |
| 134 // the histogram is being newly created and does not already exist. | 137 // the histogram is being newly created and does not already exist. |
| 135 void PreregisterHistogram(const std::string& name, | 138 void PreregisterHistogram(const char* name, |
| 136 GroupedHistogram::Sample minimum, | 139 GroupedHistogram::Sample minimum, |
| 137 GroupedHistogram::Sample maximum, | 140 GroupedHistogram::Sample maximum, |
| 138 uint32_t bucket_count, | 141 uint32_t bucket_count, |
| 139 int32_t flags) { | 142 int32_t flags) { |
| 143 base::StringPiece name_piece(name); |
| 144 |
| 140 DCHECK(base::StatisticsRecorder::IsActive()); | 145 DCHECK(base::StatisticsRecorder::IsActive()); |
| 141 DCHECK(base::Histogram::InspectConstructionArguments( | 146 DCHECK(base::Histogram::InspectConstructionArguments( |
| 142 name, &minimum, &maximum, &bucket_count)); | 147 name_piece, &minimum, &maximum, &bucket_count)); |
| 143 DCHECK(!base::StatisticsRecorder::FindHistogram(name)) | 148 DCHECK(!base::StatisticsRecorder::FindHistogram(name_piece)) |
| 144 << "Failed to preregister " << name << ", Histogram already exists."; | 149 << "Failed to preregister " << name << ", Histogram already exists."; |
| 145 | 150 |
| 146 // To avoid racy destruction at shutdown, the following will be leaked. | 151 // To avoid racy destruction at shutdown, the following will be leaked. |
| 147 base::BucketRanges* ranges = new base::BucketRanges(bucket_count + 1); | 152 base::BucketRanges* ranges = new base::BucketRanges(bucket_count + 1); |
| 148 base::Histogram::InitializeBucketRanges(minimum, maximum, ranges); | 153 base::Histogram::InitializeBucketRanges(minimum, maximum, ranges); |
| 149 const base::BucketRanges* registered_ranges = | 154 const base::BucketRanges* registered_ranges = |
| 150 base::StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); | 155 base::StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); |
| 151 | 156 |
| 152 GroupedHistogram* tentative_histogram = | 157 GroupedHistogram* tentative_histogram = |
| 153 new GroupedHistogram(name, minimum, maximum, registered_ranges); | 158 new GroupedHistogram(name, minimum, maximum, registered_ranges); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 175 } | 180 } |
| 176 } | 181 } |
| 177 | 182 |
| 178 void TagAppStartForGroupedHistograms(const std::string& app_name) { | 183 void TagAppStartForGroupedHistograms(const std::string& app_name) { |
| 179 base::AutoLock lock(g_current_app.Get().lock); | 184 base::AutoLock lock(g_current_app.Get().lock); |
| 180 g_current_app.Get().app_name = app_name; | 185 g_current_app.Get().app_name = app_name; |
| 181 } | 186 } |
| 182 | 187 |
| 183 } // namespace metrics | 188 } // namespace metrics |
| 184 } // namespace chromecast | 189 } // namespace chromecast |
| OLD | NEW |