[email protected] | df32e89c | 2012-05-17 17:47:34 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 89622004 | 2010-03-23 18:14:28 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "chrome/browser/chromeos/external_metrics.h" |
| 6 | |
avi | 8a07d5389 | 2015-12-24 22:13:53 | [diff] [blame] | 7 | #include <stddef.h> |
| 8 | |
[email protected] | f412499 | 2013-06-20 03:34:17 | [diff] [blame] | 9 | #include <map> |
ke.he | a9da80c | 2017-02-16 12:45:00 | [diff] [blame] | 10 | #include <memory> |
[email protected] | d8e1cf9c | 2011-11-03 19:37:57 | [diff] [blame] | 11 | #include <string> |
ke.he | a9da80c | 2017-02-16 12:45:00 | [diff] [blame] | 12 | #include <vector> |
[email protected] | d8e1cf9c | 2011-11-03 19:37:57 | [diff] [blame] | 13 | |
[email protected] | 7f6f44c | 2011-12-14 13:23:38 | [diff] [blame] | 14 | #include "base/bind.h" |
asvitkine | b5663751 | 2016-09-01 19:41:40 | [diff] [blame] | 15 | #include "base/metrics/histogram_macros.h" |
[email protected] | 85bbf09 | 2013-05-07 08:23:40 | [diff] [blame] | 16 | #include "base/metrics/sparse_histogram.h" |
[email protected] | cbf1444 | 2012-09-05 03:00:25 | [diff] [blame] | 17 | #include "base/metrics/statistics_recorder.h" |
bratell | 0a7406f | 2017-03-28 07:46:37 | [diff] [blame] | 18 | #include "base/metrics/user_metrics.h" |
fdoray | b404608 | 2017-04-27 10:21:08 | [diff] [blame] | 19 | #include "base/task_scheduler/post_task.h" |
[email protected] | c1834a9 | 2011-01-21 18:21:03 | [diff] [blame] | 20 | #include "chrome/browser/browser_process.h" |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 21 | #include "chrome/browser/metrics/chromeos_metrics_provider.h" |
[email protected] | d6147bd | 2014-06-11 01:58:19 | [diff] [blame] | 22 | #include "components/metrics/metrics_service.h" |
[email protected] | 1ebdce33 | 2014-07-17 21:19:19 | [diff] [blame] | 23 | #include "components/metrics/serialization/metric_sample.h" |
| 24 | #include "components/metrics/serialization/serialization_utils.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 25 | #include "content/public/browser/browser_thread.h" |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 26 | |
[email protected] | 631bb74 | 2011-11-02 11:29:39 | [diff] [blame] | 27 | using content::BrowserThread; |
| 28 | |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 29 | namespace chromeos { |
| 30 | |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 31 | namespace { |
| 32 | |
| 33 | bool CheckValues(const std::string& name, |
| 34 | int minimum, |
| 35 | int maximum, |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 36 | uint32_t bucket_count) { |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 37 | if (!base::Histogram::InspectConstructionArguments( |
| 38 | name, &minimum, &maximum, &bucket_count)) |
| 39 | return false; |
| 40 | base::HistogramBase* histogram = |
| 41 | base::StatisticsRecorder::FindHistogram(name); |
| 42 | if (!histogram) |
| 43 | return true; |
| 44 | return histogram->HasConstructionArguments(minimum, maximum, bucket_count); |
| 45 | } |
| 46 | |
| 47 | bool CheckLinearValues(const std::string& name, int maximum) { |
| 48 | return CheckValues(name, 1, maximum, maximum + 1); |
| 49 | } |
| 50 | |
fdoray | b404608 | 2017-04-27 10:21:08 | [diff] [blame] | 51 | // The interval between external metrics collections. |
| 52 | constexpr base::TimeDelta kExternalMetricsCollectionInterval = |
| 53 | base::TimeDelta::FromSeconds(30); |
| 54 | constexpr char kEventsFilePath[] = "/var/lib/metrics/uma-events"; |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 55 | |
fdoray | b404608 | 2017-04-27 10:21:08 | [diff] [blame] | 56 | } // namespace |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 57 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 58 | ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath) { |
| 59 | } |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 60 | |
[email protected] | 41baad0 | 2011-05-15 20:37:46 | [diff] [blame] | 61 | ExternalMetrics::~ExternalMetrics() {} |
| 62 | |
[email protected] | 29cf1677 | 2010-04-21 15:13:47 | [diff] [blame] | 63 | void ExternalMetrics::Start() { |
isherman | de9efab | 2015-03-31 00:01:25 | [diff] [blame] | 64 | ScheduleCollector(); |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 65 | } |
| 66 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 67 | // static |
| 68 | scoped_refptr<ExternalMetrics> ExternalMetrics::CreateForTesting( |
| 69 | const std::string& filename) { |
| 70 | scoped_refptr<ExternalMetrics> external_metrics(new ExternalMetrics()); |
| 71 | external_metrics->uma_events_file_ = filename; |
| 72 | return external_metrics; |
| 73 | } |
| 74 | |
isherman | de9efab | 2015-03-31 00:01:25 | [diff] [blame] | 75 | void ExternalMetrics::RecordActionUI(const std::string& action_string) { |
bratell | 0a7406f | 2017-03-28 07:46:37 | [diff] [blame] | 76 | base::RecordComputedAction(action_string); |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 77 | } |
| 78 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 79 | void ExternalMetrics::RecordAction(const std::string& action) { |
[email protected] | cca169b5 | 2010-10-08 22:15:55 | [diff] [blame] | 80 | BrowserThread::PostTask( |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 81 | BrowserThread::UI, |
| 82 | FROM_HERE, |
| 83 | base::Bind(&ExternalMetrics::RecordActionUI, this, action)); |
[email protected] | 29cf1677 | 2010-04-21 15:13:47 | [diff] [blame] | 84 | } |
| 85 | |
[email protected] | c1834a9 | 2011-01-21 18:21:03 | [diff] [blame] | 86 | void ExternalMetrics::RecordCrashUI(const std::string& crash_kind) { |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 87 | ChromeOSMetricsProvider::LogCrash(crash_kind); |
[email protected] | c1834a9 | 2011-01-21 18:21:03 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | void ExternalMetrics::RecordCrash(const std::string& crash_kind) { |
| 91 | BrowserThread::PostTask( |
| 92 | BrowserThread::UI, FROM_HERE, |
[email protected] | d8e1cf9c | 2011-11-03 19:37:57 | [diff] [blame] | 93 | base::Bind(&ExternalMetrics::RecordCrashUI, this, crash_kind)); |
[email protected] | c1834a9 | 2011-01-21 18:21:03 | [diff] [blame] | 94 | } |
| 95 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 96 | void ExternalMetrics::RecordHistogram(const metrics::MetricSample& sample) { |
| 97 | CHECK_EQ(metrics::MetricSample::HISTOGRAM, sample.type()); |
| 98 | if (!CheckValues( |
| 99 | sample.name(), sample.min(), sample.max(), sample.bucket_count())) { |
| 100 | DLOG(ERROR) << "Invalid histogram: " << sample.name(); |
[email protected] | 29cf1677 | 2010-04-21 15:13:47 | [diff] [blame] | 101 | return; |
| 102 | } |
[email protected] | e24a853 | 2012-08-03 07:18:44 | [diff] [blame] | 103 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 104 | base::HistogramBase* counter = |
| 105 | base::Histogram::FactoryGet(sample.name(), |
| 106 | sample.min(), |
| 107 | sample.max(), |
| 108 | sample.bucket_count(), |
| 109 | base::Histogram::kUmaTargetedHistogramFlag); |
| 110 | counter->Add(sample.sample()); |
[email protected] | 29cf1677 | 2010-04-21 15:13:47 | [diff] [blame] | 111 | } |
| 112 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 113 | void ExternalMetrics::RecordLinearHistogram( |
| 114 | const metrics::MetricSample& sample) { |
| 115 | CHECK_EQ(metrics::MetricSample::LINEAR_HISTOGRAM, sample.type()); |
| 116 | if (!CheckLinearValues(sample.name(), sample.max())) { |
| 117 | DLOG(ERROR) << "Invalid linear histogram: " << sample.name(); |
[email protected] | 29cf1677 | 2010-04-21 15:13:47 | [diff] [blame] | 118 | return; |
| 119 | } |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 120 | base::HistogramBase* counter = base::LinearHistogram::FactoryGet( |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 121 | sample.name(), |
| 122 | 1, |
| 123 | sample.max(), |
| 124 | sample.max() + 1, |
| 125 | base::Histogram::kUmaTargetedHistogramFlag); |
| 126 | counter->Add(sample.sample()); |
[email protected] | 29cf1677 | 2010-04-21 15:13:47 | [diff] [blame] | 127 | } |
| 128 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 129 | void ExternalMetrics::RecordSparseHistogram( |
| 130 | const metrics::MetricSample& sample) { |
| 131 | CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM, sample.type()); |
[email protected] | 85bbf09 | 2013-05-07 08:23:40 | [diff] [blame] | 132 | base::HistogramBase* counter = base::SparseHistogram::FactoryGet( |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 133 | sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag); |
| 134 | counter->Add(sample.sample()); |
[email protected] | 85bbf09 | 2013-05-07 08:23:40 | [diff] [blame] | 135 | } |
| 136 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 137 | int ExternalMetrics::CollectEvents() { |
ke.he | a9da80c | 2017-02-16 12:45:00 | [diff] [blame] | 138 | std::vector<std::unique_ptr<metrics::MetricSample>> samples; |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 139 | metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_, |
| 140 | &samples); |
| 141 | |
ke.he | a9da80c | 2017-02-16 12:45:00 | [diff] [blame] | 142 | for (auto it = samples.begin(); it != samples.end(); ++it) { |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 143 | const metrics::MetricSample& sample = **it; |
| 144 | |
| 145 | // Do not use the UMA_HISTOGRAM_... macros here. They cache the Histogram |
| 146 | // instance and thus only work if |sample.name()| is constant. |
| 147 | switch (sample.type()) { |
| 148 | case metrics::MetricSample::CRASH: |
| 149 | RecordCrash(sample.name()); |
| 150 | break; |
| 151 | case metrics::MetricSample::USER_ACTION: |
| 152 | RecordAction(sample.name()); |
| 153 | break; |
| 154 | case metrics::MetricSample::HISTOGRAM: |
| 155 | RecordHistogram(sample); |
| 156 | break; |
| 157 | case metrics::MetricSample::LINEAR_HISTOGRAM: |
| 158 | RecordLinearHistogram(sample); |
| 159 | break; |
| 160 | case metrics::MetricSample::SPARSE_HISTOGRAM: |
| 161 | RecordSparseHistogram(sample); |
| 162 | break; |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 163 | } |
| 164 | } |
| 165 | |
[email protected] | d5985de | 2014-05-28 15:24:48 | [diff] [blame] | 166 | return samples.size(); |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 167 | } |
| 168 | |
| 169 | void ExternalMetrics::CollectEventsAndReschedule() { |
| 170 | CollectEvents(); |
| 171 | ScheduleCollector(); |
| 172 | } |
| 173 | |
| 174 | void ExternalMetrics::ScheduleCollector() { |
fdoray | b404608 | 2017-04-27 10:21:08 | [diff] [blame] | 175 | base::PostDelayedTaskWithTraits( |
fdoray | 4ad1493 | 2017-05-03 21:21:11 | [diff] [blame] | 176 | FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, |
fdoray | b404608 | 2017-04-27 10:21:08 | [diff] [blame] | 177 | base::BindOnce(&chromeos::ExternalMetrics::CollectEventsAndReschedule, |
| 178 | this), |
| 179 | kExternalMetricsCollectionInterval); |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 180 | } |
| 181 | |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 182 | } // namespace chromeos |