blob: 604905af17d49f115a7b0c85dc22d02c0661f3ad [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>
ke.hea9da80c2017-02-16 12:45:0010#include <memory>
[email protected]d8e1cf9c2011-11-03 19:37:5711#include <string>
ke.hea9da80c2017-02-16 12:45:0012#include <vector>
[email protected]d8e1cf9c2011-11-03 19:37:5713
[email protected]7f6f44c2011-12-14 13:23:3814#include "base/bind.h"
asvitkineb56637512016-09-01 19:41:4015#include "base/metrics/histogram_macros.h"
[email protected]85bbf092013-05-07 08:23:4016#include "base/metrics/sparse_histogram.h"
[email protected]cbf14442012-09-05 03:00:2517#include "base/metrics/statistics_recorder.h"
bratell0a7406f2017-03-28 07:46:3718#include "base/metrics/user_metrics.h"
fdorayb4046082017-04-27 10:21:0819#include "base/task_scheduler/post_task.h"
[email protected]c1834a92011-01-21 18:21:0320#include "chrome/browser/browser_process.h"
[email protected]8304f61a2014-05-24 12:17:3321#include "chrome/browser/metrics/chromeos_metrics_provider.h"
[email protected]d6147bd2014-06-11 01:58:1922#include "components/metrics/metrics_service.h"
[email protected]1ebdce332014-07-17 21:19:1923#include "components/metrics/serialization/metric_sample.h"
24#include "components/metrics/serialization/serialization_utils.h"
[email protected]c38831a12011-10-28 12:44:4925#include "content/public/browser/browser_thread.h"
[email protected]5ccaa412009-11-13 22:00:1626
[email protected]631bb742011-11-02 11:29:3927using content::BrowserThread;
28
[email protected]5ccaa412009-11-13 22:00:1629namespace chromeos {
30
[email protected]abae9b022012-10-24 08:18:5231namespace {
32
33bool CheckValues(const std::string& name,
34 int minimum,
35 int maximum,
jam1eacd7e2016-02-08 22:48:1636 uint32_t bucket_count) {
[email protected]abae9b022012-10-24 08:18:5237 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
47bool CheckLinearValues(const std::string& name, int maximum) {
48 return CheckValues(name, 1, maximum, maximum + 1);
49}
50
fdorayb4046082017-04-27 10:21:0851// The interval between external metrics collections.
52constexpr base::TimeDelta kExternalMetricsCollectionInterval =
53 base::TimeDelta::FromSeconds(30);
54constexpr char kEventsFilePath[] = "/var/lib/metrics/uma-events";
[email protected]abae9b022012-10-24 08:18:5255
fdorayb4046082017-04-27 10:21:0856} // namespace
[email protected]5ccaa412009-11-13 22:00:1657
[email protected]d5985de2014-05-28 15:24:4858ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath) {
59}
[email protected]5ccaa412009-11-13 22:00:1660
[email protected]41baad02011-05-15 20:37:4661ExternalMetrics::~ExternalMetrics() {}
62
[email protected]29cf16772010-04-21 15:13:4763void ExternalMetrics::Start() {
ishermande9efab2015-03-31 00:01:2564 ScheduleCollector();
[email protected]5ccaa412009-11-13 22:00:1665}
66
[email protected]d5985de2014-05-28 15:24:4867// static
68scoped_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
ishermande9efab2015-03-31 00:01:2575void ExternalMetrics::RecordActionUI(const std::string& action_string) {
bratell0a7406f2017-03-28 07:46:3776 base::RecordComputedAction(action_string);
[email protected]5ccaa412009-11-13 22:00:1677}
78
[email protected]d5985de2014-05-28 15:24:4879void ExternalMetrics::RecordAction(const std::string& action) {
[email protected]cca169b52010-10-08 22:15:5580 BrowserThread::PostTask(
[email protected]d5985de2014-05-28 15:24:4881 BrowserThread::UI,
82 FROM_HERE,
83 base::Bind(&ExternalMetrics::RecordActionUI, this, action));
[email protected]29cf16772010-04-21 15:13:4784}
85
[email protected]c1834a92011-01-21 18:21:0386void ExternalMetrics::RecordCrashUI(const std::string& crash_kind) {
[email protected]8304f61a2014-05-24 12:17:3387 ChromeOSMetricsProvider::LogCrash(crash_kind);
[email protected]c1834a92011-01-21 18:21:0388}
89
90void ExternalMetrics::RecordCrash(const std::string& crash_kind) {
91 BrowserThread::PostTask(
92 BrowserThread::UI, FROM_HERE,
[email protected]d8e1cf9c2011-11-03 19:37:5793 base::Bind(&ExternalMetrics::RecordCrashUI, this, crash_kind));
[email protected]c1834a92011-01-21 18:21:0394}
95
[email protected]d5985de2014-05-28 15:24:4896void 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]29cf16772010-04-21 15:13:47101 return;
102 }
[email protected]e24a8532012-08-03 07:18:44103
[email protected]d5985de2014-05-28 15:24:48104 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]29cf16772010-04-21 15:13:47111}
112
[email protected]d5985de2014-05-28 15:24:48113void 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]29cf16772010-04-21 15:13:47118 return;
119 }
[email protected]de415552013-01-23 04:12:17120 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
[email protected]d5985de2014-05-28 15:24:48121 sample.name(),
122 1,
123 sample.max(),
124 sample.max() + 1,
125 base::Histogram::kUmaTargetedHistogramFlag);
126 counter->Add(sample.sample());
[email protected]29cf16772010-04-21 15:13:47127}
128
[email protected]d5985de2014-05-28 15:24:48129void ExternalMetrics::RecordSparseHistogram(
130 const metrics::MetricSample& sample) {
131 CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM, sample.type());
[email protected]85bbf092013-05-07 08:23:40132 base::HistogramBase* counter = base::SparseHistogram::FactoryGet(
[email protected]d5985de2014-05-28 15:24:48133 sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag);
134 counter->Add(sample.sample());
[email protected]85bbf092013-05-07 08:23:40135}
136
[email protected]d5985de2014-05-28 15:24:48137int ExternalMetrics::CollectEvents() {
ke.hea9da80c2017-02-16 12:45:00138 std::vector<std::unique_ptr<metrics::MetricSample>> samples;
[email protected]d5985de2014-05-28 15:24:48139 metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_,
140 &samples);
141
ke.hea9da80c2017-02-16 12:45:00142 for (auto it = samples.begin(); it != samples.end(); ++it) {
[email protected]d5985de2014-05-28 15:24:48143 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]5ccaa412009-11-13 22:00:16163 }
164 }
165
[email protected]d5985de2014-05-28 15:24:48166 return samples.size();
[email protected]5ccaa412009-11-13 22:00:16167}
168
169void ExternalMetrics::CollectEventsAndReschedule() {
170 CollectEvents();
171 ScheduleCollector();
172}
173
174void ExternalMetrics::ScheduleCollector() {
fdorayb4046082017-04-27 10:21:08175 base::PostDelayedTaskWithTraits(
fdoray4ad14932017-05-03 21:21:11176 FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
fdorayb4046082017-04-27 10:21:08177 base::BindOnce(&chromeos::ExternalMetrics::CollectEventsAndReschedule,
178 this),
179 kExternalMetricsCollectionInterval);
[email protected]5ccaa412009-11-13 22:00:16180}
181
[email protected]5ccaa412009-11-13 22:00:16182} // namespace chromeos