blob: e04a85cfa08cd7b6ae06ad304da379ae0d393263 [file] [log] [blame]
[email protected]df32e89c2012-05-17 17:47:341// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]896220042010-03-23 18:14:282// Use of this source code is governed by a BSD-style license that can be
[email protected]5ccaa412009-11-13 22:00:163// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/external_metrics.h"
6
avi8a07d53892015-12-24 22:13:537#include <stddef.h>
8
[email protected]f4124992013-06-20 03:34:179#include <map>
[email protected]d8e1cf9c2011-11-03 19:37:5710#include <string>
11
[email protected]7f6f44c2011-12-14 13:23:3812#include "base/bind.h"
[email protected]835d7c82010-10-14 04:38:3813#include "base/metrics/histogram.h"
[email protected]85bbf092013-05-07 08:23:4014#include "base/metrics/sparse_histogram.h"
[email protected]cbf14442012-09-05 03:00:2515#include "base/metrics/statistics_recorder.h"
[email protected]c1834a92011-01-21 18:21:0316#include "chrome/browser/browser_process.h"
[email protected]8304f61a2014-05-24 12:17:3317#include "chrome/browser/metrics/chromeos_metrics_provider.h"
[email protected]d6147bd2014-06-11 01:58:1918#include "components/metrics/metrics_service.h"
[email protected]1ebdce332014-07-17 21:19:1919#include "components/metrics/serialization/metric_sample.h"
20#include "components/metrics/serialization/serialization_utils.h"
[email protected]c38831a12011-10-28 12:44:4921#include "content/public/browser/browser_thread.h"
[email protected]7f6f44c2011-12-14 13:23:3822#include "content/public/browser/user_metrics.h"
[email protected]5ccaa412009-11-13 22:00:1623
[email protected]e6e30ac2014-01-13 21:24:3924using base::UserMetricsAction;
[email protected]631bb742011-11-02 11:29:3925using content::BrowserThread;
26
[email protected]5ccaa412009-11-13 22:00:1627namespace chromeos {
28
[email protected]abae9b022012-10-24 08:18:5229namespace {
30
31bool CheckValues(const std::string& name,
32 int minimum,
33 int maximum,
jam1eacd7e2016-02-08 22:48:1634 uint32_t bucket_count) {
[email protected]abae9b022012-10-24 08:18:5235 if (!base::Histogram::InspectConstructionArguments(
36 name, &minimum, &maximum, &bucket_count))
37 return false;
38 base::HistogramBase* histogram =
39 base::StatisticsRecorder::FindHistogram(name);
40 if (!histogram)
41 return true;
42 return histogram->HasConstructionArguments(minimum, maximum, bucket_count);
43}
44
45bool CheckLinearValues(const std::string& name, int maximum) {
46 return CheckValues(name, 1, maximum, maximum + 1);
47}
48
49} // namespace
50
[email protected]df32e89c2012-05-17 17:47:3451// The interval between external metrics collections in seconds
52static const int kExternalMetricsCollectionIntervalSeconds = 30;
semenzatoba56da02015-03-12 21:05:1953const char kEventsFilePath[] = "/var/lib/metrics/uma-events";
[email protected]5ccaa412009-11-13 22:00:1654
[email protected]d5985de2014-05-28 15:24:4855ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath) {
56}
[email protected]5ccaa412009-11-13 22:00:1657
[email protected]41baad02011-05-15 20:37:4658ExternalMetrics::~ExternalMetrics() {}
59
[email protected]29cf16772010-04-21 15:13:4760void ExternalMetrics::Start() {
ishermande9efab2015-03-31 00:01:2561 ScheduleCollector();
[email protected]5ccaa412009-11-13 22:00:1662}
63
[email protected]d5985de2014-05-28 15:24:4864// static
65scoped_refptr<ExternalMetrics> ExternalMetrics::CreateForTesting(
66 const std::string& filename) {
67 scoped_refptr<ExternalMetrics> external_metrics(new ExternalMetrics());
68 external_metrics->uma_events_file_ = filename;
69 return external_metrics;
70}
71
ishermande9efab2015-03-31 00:01:2572void ExternalMetrics::RecordActionUI(const std::string& action_string) {
73 content::RecordComputedAction(action_string);
[email protected]5ccaa412009-11-13 22:00:1674}
75
[email protected]d5985de2014-05-28 15:24:4876void ExternalMetrics::RecordAction(const std::string& action) {
[email protected]cca169b52010-10-08 22:15:5577 BrowserThread::PostTask(
[email protected]d5985de2014-05-28 15:24:4878 BrowserThread::UI,
79 FROM_HERE,
80 base::Bind(&ExternalMetrics::RecordActionUI, this, action));
[email protected]29cf16772010-04-21 15:13:4781}
82
[email protected]c1834a92011-01-21 18:21:0383void ExternalMetrics::RecordCrashUI(const std::string& crash_kind) {
[email protected]8304f61a2014-05-24 12:17:3384 ChromeOSMetricsProvider::LogCrash(crash_kind);
[email protected]c1834a92011-01-21 18:21:0385}
86
87void ExternalMetrics::RecordCrash(const std::string& crash_kind) {
88 BrowserThread::PostTask(
89 BrowserThread::UI, FROM_HERE,
[email protected]d8e1cf9c2011-11-03 19:37:5790 base::Bind(&ExternalMetrics::RecordCrashUI, this, crash_kind));
[email protected]c1834a92011-01-21 18:21:0391}
92
[email protected]d5985de2014-05-28 15:24:4893void ExternalMetrics::RecordHistogram(const metrics::MetricSample& sample) {
94 CHECK_EQ(metrics::MetricSample::HISTOGRAM, sample.type());
95 if (!CheckValues(
96 sample.name(), sample.min(), sample.max(), sample.bucket_count())) {
97 DLOG(ERROR) << "Invalid histogram: " << sample.name();
[email protected]29cf16772010-04-21 15:13:4798 return;
99 }
[email protected]e24a8532012-08-03 07:18:44100
[email protected]d5985de2014-05-28 15:24:48101 base::HistogramBase* counter =
102 base::Histogram::FactoryGet(sample.name(),
103 sample.min(),
104 sample.max(),
105 sample.bucket_count(),
106 base::Histogram::kUmaTargetedHistogramFlag);
107 counter->Add(sample.sample());
[email protected]29cf16772010-04-21 15:13:47108}
109
[email protected]d5985de2014-05-28 15:24:48110void ExternalMetrics::RecordLinearHistogram(
111 const metrics::MetricSample& sample) {
112 CHECK_EQ(metrics::MetricSample::LINEAR_HISTOGRAM, sample.type());
113 if (!CheckLinearValues(sample.name(), sample.max())) {
114 DLOG(ERROR) << "Invalid linear histogram: " << sample.name();
[email protected]29cf16772010-04-21 15:13:47115 return;
116 }
[email protected]de415552013-01-23 04:12:17117 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
[email protected]d5985de2014-05-28 15:24:48118 sample.name(),
119 1,
120 sample.max(),
121 sample.max() + 1,
122 base::Histogram::kUmaTargetedHistogramFlag);
123 counter->Add(sample.sample());
[email protected]29cf16772010-04-21 15:13:47124}
125
[email protected]d5985de2014-05-28 15:24:48126void ExternalMetrics::RecordSparseHistogram(
127 const metrics::MetricSample& sample) {
128 CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM, sample.type());
[email protected]85bbf092013-05-07 08:23:40129 base::HistogramBase* counter = base::SparseHistogram::FactoryGet(
[email protected]d5985de2014-05-28 15:24:48130 sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag);
131 counter->Add(sample.sample());
[email protected]85bbf092013-05-07 08:23:40132}
133
[email protected]d5985de2014-05-28 15:24:48134int ExternalMetrics::CollectEvents() {
135 ScopedVector<metrics::MetricSample> samples;
136 metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_,
137 &samples);
138
139 for (ScopedVector<metrics::MetricSample>::iterator it = samples.begin();
140 it != samples.end();
141 ++it) {
142 const metrics::MetricSample& sample = **it;
143
144 // Do not use the UMA_HISTOGRAM_... macros here. They cache the Histogram
145 // instance and thus only work if |sample.name()| is constant.
146 switch (sample.type()) {
147 case metrics::MetricSample::CRASH:
148 RecordCrash(sample.name());
149 break;
150 case metrics::MetricSample::USER_ACTION:
151 RecordAction(sample.name());
152 break;
153 case metrics::MetricSample::HISTOGRAM:
154 RecordHistogram(sample);
155 break;
156 case metrics::MetricSample::LINEAR_HISTOGRAM:
157 RecordLinearHistogram(sample);
158 break;
159 case metrics::MetricSample::SPARSE_HISTOGRAM:
160 RecordSparseHistogram(sample);
161 break;
[email protected]5ccaa412009-11-13 22:00:16162 }
163 }
164
[email protected]d5985de2014-05-28 15:24:48165 return samples.size();
[email protected]5ccaa412009-11-13 22:00:16166}
167
168void ExternalMetrics::CollectEventsAndReschedule() {
169 CollectEvents();
170 ScheduleCollector();
171}
172
173void ExternalMetrics::ScheduleCollector() {
hashimotod562a722015-04-10 13:44:27174 bool result = BrowserThread::GetBlockingPool()->PostDelayedWorkerTask(
175 FROM_HERE,
[email protected]85bbf092013-05-07 08:23:40176 base::Bind(&chromeos::ExternalMetrics::CollectEventsAndReschedule, this),
177 base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds));
[email protected]5ccaa412009-11-13 22:00:16178 DCHECK(result);
179}
180
[email protected]5ccaa412009-11-13 22:00:16181} // namespace chromeos