blob: 490ae3ede5cdef866693f52f96e45d890190ea43 [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
[email protected]f4124992013-06-20 03:34:177#include <map>
[email protected]d8e1cf9c2011-11-03 19:37:578#include <string>
9
[email protected]7f6f44c2011-12-14 13:23:3810#include "base/bind.h"
[email protected]835d7c82010-10-14 04:38:3811#include "base/metrics/histogram.h"
[email protected]85bbf092013-05-07 08:23:4012#include "base/metrics/sparse_histogram.h"
[email protected]cbf14442012-09-05 03:00:2513#include "base/metrics/statistics_recorder.h"
[email protected]bd5a3742013-09-29 18:06:1314#include "base/timer/elapsed_timer.h"
[email protected]c1834a92011-01-21 18:21:0315#include "chrome/browser/browser_process.h"
[email protected]8304f61a2014-05-24 12:17:3316#include "chrome/browser/metrics/chromeos_metrics_provider.h"
[email protected]d6147bd2014-06-11 01:58:1917#include "components/metrics/metrics_service.h"
[email protected]1ebdce332014-07-17 21:19:1918#include "components/metrics/serialization/metric_sample.h"
19#include "components/metrics/serialization/serialization_utils.h"
[email protected]c38831a12011-10-28 12:44:4920#include "content/public/browser/browser_thread.h"
[email protected]7f6f44c2011-12-14 13:23:3821#include "content/public/browser/user_metrics.h"
[email protected]5ccaa412009-11-13 22:00:1622
[email protected]e6e30ac2014-01-13 21:24:3923using base::UserMetricsAction;
[email protected]631bb742011-11-02 11:29:3924using content::BrowserThread;
[email protected]631bb742011-11-02 11:29:3925
[email protected]5ccaa412009-11-13 22:00:1626namespace chromeos {
27
[email protected]abae9b022012-10-24 08:18:5228namespace {
29
30bool CheckValues(const std::string& name,
31 int minimum,
32 int maximum,
33 size_t bucket_count) {
34 if (!base::Histogram::InspectConstructionArguments(
35 name, &minimum, &maximum, &bucket_count))
36 return false;
37 base::HistogramBase* histogram =
38 base::StatisticsRecorder::FindHistogram(name);
39 if (!histogram)
40 return true;
41 return histogram->HasConstructionArguments(minimum, maximum, bucket_count);
42}
43
44bool CheckLinearValues(const std::string& name, int maximum) {
45 return CheckValues(name, 1, maximum, maximum + 1);
46}
47
48} // namespace
49
[email protected]df32e89c2012-05-17 17:47:3450// The interval between external metrics collections in seconds
51static const int kExternalMetricsCollectionIntervalSeconds = 30;
semenzatoba56da02015-03-12 21:05:1952const char kEventsFilePath[] = "/var/lib/metrics/uma-events";
[email protected]5ccaa412009-11-13 22:00:1653
[email protected]d5985de2014-05-28 15:24:4854ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath) {
55}
[email protected]5ccaa412009-11-13 22:00:1656
[email protected]41baad02011-05-15 20:37:4657ExternalMetrics::~ExternalMetrics() {}
58
[email protected]29cf16772010-04-21 15:13:4759void ExternalMetrics::Start() {
ishermande9efab2015-03-31 00:01:2560 ScheduleCollector();
[email protected]5ccaa412009-11-13 22:00:1661}
62
[email protected]d5985de2014-05-28 15:24:4863// static
64scoped_refptr<ExternalMetrics> ExternalMetrics::CreateForTesting(
65 const std::string& filename) {
66 scoped_refptr<ExternalMetrics> external_metrics(new ExternalMetrics());
67 external_metrics->uma_events_file_ = filename;
68 return external_metrics;
69}
70
ishermande9efab2015-03-31 00:01:2571void ExternalMetrics::RecordActionUI(const std::string& action_string) {
72 content::RecordComputedAction(action_string);
[email protected]5ccaa412009-11-13 22:00:1673}
74
[email protected]d5985de2014-05-28 15:24:4875void ExternalMetrics::RecordAction(const std::string& action) {
[email protected]cca169b52010-10-08 22:15:5576 BrowserThread::PostTask(
[email protected]d5985de2014-05-28 15:24:4877 BrowserThread::UI,
78 FROM_HERE,
79 base::Bind(&ExternalMetrics::RecordActionUI, this, action));
[email protected]29cf16772010-04-21 15:13:4780}
81
[email protected]c1834a92011-01-21 18:21:0382void ExternalMetrics::RecordCrashUI(const std::string& crash_kind) {
[email protected]8304f61a2014-05-24 12:17:3383 ChromeOSMetricsProvider::LogCrash(crash_kind);
[email protected]c1834a92011-01-21 18:21:0384}
85
86void ExternalMetrics::RecordCrash(const std::string& crash_kind) {
87 BrowserThread::PostTask(
88 BrowserThread::UI, FROM_HERE,
[email protected]d8e1cf9c2011-11-03 19:37:5789 base::Bind(&ExternalMetrics::RecordCrashUI, this, crash_kind));
[email protected]c1834a92011-01-21 18:21:0390}
91
[email protected]d5985de2014-05-28 15:24:4892void ExternalMetrics::RecordHistogram(const metrics::MetricSample& sample) {
93 CHECK_EQ(metrics::MetricSample::HISTOGRAM, sample.type());
94 if (!CheckValues(
95 sample.name(), sample.min(), sample.max(), sample.bucket_count())) {
96 DLOG(ERROR) << "Invalid histogram: " << sample.name();
[email protected]29cf16772010-04-21 15:13:4797 return;
98 }
[email protected]e24a8532012-08-03 07:18:4499
[email protected]d5985de2014-05-28 15:24:48100 base::HistogramBase* counter =
101 base::Histogram::FactoryGet(sample.name(),
102 sample.min(),
103 sample.max(),
104 sample.bucket_count(),
105 base::Histogram::kUmaTargetedHistogramFlag);
106 counter->Add(sample.sample());
[email protected]29cf16772010-04-21 15:13:47107}
108
[email protected]d5985de2014-05-28 15:24:48109void ExternalMetrics::RecordLinearHistogram(
110 const metrics::MetricSample& sample) {
111 CHECK_EQ(metrics::MetricSample::LINEAR_HISTOGRAM, sample.type());
112 if (!CheckLinearValues(sample.name(), sample.max())) {
113 DLOG(ERROR) << "Invalid linear histogram: " << sample.name();
[email protected]29cf16772010-04-21 15:13:47114 return;
115 }
[email protected]de415552013-01-23 04:12:17116 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
[email protected]d5985de2014-05-28 15:24:48117 sample.name(),
118 1,
119 sample.max(),
120 sample.max() + 1,
121 base::Histogram::kUmaTargetedHistogramFlag);
122 counter->Add(sample.sample());
[email protected]29cf16772010-04-21 15:13:47123}
124
[email protected]d5985de2014-05-28 15:24:48125void ExternalMetrics::RecordSparseHistogram(
126 const metrics::MetricSample& sample) {
127 CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM, sample.type());
[email protected]85bbf092013-05-07 08:23:40128 base::HistogramBase* counter = base::SparseHistogram::FactoryGet(
[email protected]d5985de2014-05-28 15:24:48129 sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag);
130 counter->Add(sample.sample());
[email protected]85bbf092013-05-07 08:23:40131}
132
[email protected]d5985de2014-05-28 15:24:48133int ExternalMetrics::CollectEvents() {
134 ScopedVector<metrics::MetricSample> samples;
135 metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_,
136 &samples);
137
138 for (ScopedVector<metrics::MetricSample>::iterator it = samples.begin();
139 it != samples.end();
140 ++it) {
141 const metrics::MetricSample& sample = **it;
142
143 // Do not use the UMA_HISTOGRAM_... macros here. They cache the Histogram
144 // instance and thus only work if |sample.name()| is constant.
145 switch (sample.type()) {
146 case metrics::MetricSample::CRASH:
147 RecordCrash(sample.name());
148 break;
149 case metrics::MetricSample::USER_ACTION:
150 RecordAction(sample.name());
151 break;
152 case metrics::MetricSample::HISTOGRAM:
153 RecordHistogram(sample);
154 break;
155 case metrics::MetricSample::LINEAR_HISTOGRAM:
156 RecordLinearHistogram(sample);
157 break;
158 case metrics::MetricSample::SPARSE_HISTOGRAM:
159 RecordSparseHistogram(sample);
160 break;
[email protected]5ccaa412009-11-13 22:00:16161 }
162 }
163
[email protected]d5985de2014-05-28 15:24:48164 return samples.size();
[email protected]5ccaa412009-11-13 22:00:16165}
166
167void ExternalMetrics::CollectEventsAndReschedule() {
[email protected]bd5a3742013-09-29 18:06:13168 base::ElapsedTimer timer;
[email protected]5ccaa412009-11-13 22:00:16169 CollectEvents();
[email protected]d2b6af672010-07-01 20:38:54170 UMA_HISTOGRAM_TIMES("UMA.CollectExternalEventsTime", timer.Elapsed());
[email protected]5ccaa412009-11-13 22:00:16171 ScheduleCollector();
172}
173
174void ExternalMetrics::ScheduleCollector() {
ishermande9efab2015-03-31 00:01:25175 bool result = BrowserThread::PostDelayedTask(
[email protected]85bbf092013-05-07 08:23:40176 BrowserThread::FILE, FROM_HERE,
177 base::Bind(&chromeos::ExternalMetrics::CollectEventsAndReschedule, this),
178 base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds));
[email protected]5ccaa412009-11-13 22:00:16179 DCHECK(result);
180}
181
[email protected]5ccaa412009-11-13 22:00:16182} // namespace chromeos