1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/external_metrics.h"
10 #include "base/bind.h"
11 #include "base/metrics/histogram.h"
12 #include "base/metrics/sparse_histogram.h"
13 #include "base/metrics/statistics_recorder.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/metrics/chromeos_metrics_provider.h"
16 #include "components/metrics/metrics_service.h"
17 #include "components/metrics/serialization/metric_sample.h"
18 #include "components/metrics/serialization/serialization_utils.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/user_metrics.h"
22 using base::UserMetricsAction
;
23 using content::BrowserThread
;
29 bool CheckValues(const std::string
& name
,
32 size_t bucket_count
) {
33 if (!base::Histogram::InspectConstructionArguments(
34 name
, &minimum
, &maximum
, &bucket_count
))
36 base::HistogramBase
* histogram
=
37 base::StatisticsRecorder::FindHistogram(name
);
40 return histogram
->HasConstructionArguments(minimum
, maximum
, bucket_count
);
43 bool CheckLinearValues(const std::string
& name
, int maximum
) {
44 return CheckValues(name
, 1, maximum
, maximum
+ 1);
49 // The interval between external metrics collections in seconds
50 static const int kExternalMetricsCollectionIntervalSeconds
= 30;
51 const char kEventsFilePath
[] = "/var/lib/metrics/uma-events";
53 ExternalMetrics::ExternalMetrics() : uma_events_file_(kEventsFilePath
) {
56 ExternalMetrics::~ExternalMetrics() {}
58 void ExternalMetrics::Start() {
63 scoped_refptr
<ExternalMetrics
> ExternalMetrics::CreateForTesting(
64 const std::string
& filename
) {
65 scoped_refptr
<ExternalMetrics
> external_metrics(new ExternalMetrics());
66 external_metrics
->uma_events_file_
= filename
;
67 return external_metrics
;
70 void ExternalMetrics::RecordActionUI(const std::string
& action_string
) {
71 content::RecordComputedAction(action_string
);
74 void ExternalMetrics::RecordAction(const std::string
& action
) {
75 BrowserThread::PostTask(
78 base::Bind(&ExternalMetrics::RecordActionUI
, this, action
));
81 void ExternalMetrics::RecordCrashUI(const std::string
& crash_kind
) {
82 ChromeOSMetricsProvider::LogCrash(crash_kind
);
85 void ExternalMetrics::RecordCrash(const std::string
& crash_kind
) {
86 BrowserThread::PostTask(
87 BrowserThread::UI
, FROM_HERE
,
88 base::Bind(&ExternalMetrics::RecordCrashUI
, this, crash_kind
));
91 void ExternalMetrics::RecordHistogram(const metrics::MetricSample
& sample
) {
92 CHECK_EQ(metrics::MetricSample::HISTOGRAM
, sample
.type());
94 sample
.name(), sample
.min(), sample
.max(), sample
.bucket_count())) {
95 DLOG(ERROR
) << "Invalid histogram: " << sample
.name();
99 base::HistogramBase
* counter
=
100 base::Histogram::FactoryGet(sample
.name(),
103 sample
.bucket_count(),
104 base::Histogram::kUmaTargetedHistogramFlag
);
105 counter
->Add(sample
.sample());
108 void ExternalMetrics::RecordLinearHistogram(
109 const metrics::MetricSample
& sample
) {
110 CHECK_EQ(metrics::MetricSample::LINEAR_HISTOGRAM
, sample
.type());
111 if (!CheckLinearValues(sample
.name(), sample
.max())) {
112 DLOG(ERROR
) << "Invalid linear histogram: " << sample
.name();
115 base::HistogramBase
* counter
= base::LinearHistogram::FactoryGet(
120 base::Histogram::kUmaTargetedHistogramFlag
);
121 counter
->Add(sample
.sample());
124 void ExternalMetrics::RecordSparseHistogram(
125 const metrics::MetricSample
& sample
) {
126 CHECK_EQ(metrics::MetricSample::SPARSE_HISTOGRAM
, sample
.type());
127 base::HistogramBase
* counter
= base::SparseHistogram::FactoryGet(
128 sample
.name(), base::HistogramBase::kUmaTargetedHistogramFlag
);
129 counter
->Add(sample
.sample());
132 int ExternalMetrics::CollectEvents() {
133 ScopedVector
<metrics::MetricSample
> samples
;
134 metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(uma_events_file_
,
137 for (ScopedVector
<metrics::MetricSample
>::iterator it
= samples
.begin();
140 const metrics::MetricSample
& sample
= **it
;
142 // Do not use the UMA_HISTOGRAM_... macros here. They cache the Histogram
143 // instance and thus only work if |sample.name()| is constant.
144 switch (sample
.type()) {
145 case metrics::MetricSample::CRASH
:
146 RecordCrash(sample
.name());
148 case metrics::MetricSample::USER_ACTION
:
149 RecordAction(sample
.name());
151 case metrics::MetricSample::HISTOGRAM
:
152 RecordHistogram(sample
);
154 case metrics::MetricSample::LINEAR_HISTOGRAM
:
155 RecordLinearHistogram(sample
);
157 case metrics::MetricSample::SPARSE_HISTOGRAM
:
158 RecordSparseHistogram(sample
);
163 return samples
.size();
166 void ExternalMetrics::CollectEventsAndReschedule() {
171 void ExternalMetrics::ScheduleCollector() {
172 bool result
= BrowserThread::GetBlockingPool()->PostDelayedWorkerTask(
174 base::Bind(&chromeos::ExternalMetrics::CollectEventsAndReschedule
, this),
175 base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds
));
179 } // namespace chromeos