1 // Copyright 2014 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 "chromecast/browser/metrics/external_metrics.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/metrics/histogram.h"
13 #include "base/metrics/sparse_histogram.h"
14 #include "base/metrics/statistics_recorder.h"
15 #include "chromecast/base/metrics/cast_histograms.h"
16 #include "chromecast/base/metrics/cast_metrics_helper.h"
17 #include "chromecast/browser/metrics/cast_stability_metrics_provider.h"
18 #include "components/metrics/metrics_service.h"
19 #include "components/metrics/serialization/metric_sample.h"
20 #include "components/metrics/serialization/serialization_utils.h"
21 #include "content/public/browser/browser_thread.h"
23 namespace chromecast
{
28 bool CheckValues(const std::string
& name
,
31 size_t bucket_count
) {
32 if (!base::Histogram::InspectConstructionArguments(
33 name
, &minimum
, &maximum
, &bucket_count
))
35 base::HistogramBase
* histogram
=
36 base::StatisticsRecorder::FindHistogram(name
);
39 return histogram
->HasConstructionArguments(minimum
, maximum
, bucket_count
);
42 bool CheckLinearValues(const std::string
& name
, int maximum
) {
43 return CheckValues(name
, 1, maximum
, maximum
+ 1);
48 // The interval between external metrics collections in seconds
49 static const int kExternalMetricsCollectionIntervalSeconds
= 30;
51 ExternalMetrics::ExternalMetrics(
52 CastStabilityMetricsProvider
* stability_provider
,
53 const std::string
& uma_events_file
)
54 : stability_provider_(stability_provider
),
55 uma_events_file_(uma_events_file
),
57 DCHECK(stability_provider
);
60 ExternalMetrics::~ExternalMetrics() {
61 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
64 void ExternalMetrics::StopAndDestroy() {
65 content::BrowserThread::DeleteSoon(
66 content::BrowserThread::FILE, FROM_HERE
, this);
69 void ExternalMetrics::Start() {
70 bool result
= content::BrowserThread::PostDelayedTask(
71 content::BrowserThread::FILE,
73 base::Bind(&ExternalMetrics::CollectEventsAndReschedule
,
74 weak_factory_
.GetWeakPtr()),
75 base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds
));
79 void ExternalMetrics::RecordCrash(const std::string
& crash_kind
) {
80 content::BrowserThread::PostTask(
81 content::BrowserThread::UI
,
83 base::Bind(&CastStabilityMetricsProvider::LogExternalCrash
,
84 base::Unretained(stability_provider_
),
88 void ExternalMetrics::RecordSparseHistogram(
89 const ::metrics::MetricSample
& sample
) {
90 CHECK_EQ(::metrics::MetricSample::SPARSE_HISTOGRAM
, sample
.type());
91 base::HistogramBase
* counter
= base::SparseHistogram::FactoryGet(
92 sample
.name(), base::HistogramBase::kUmaTargetedHistogramFlag
);
93 counter
->Add(sample
.sample());
96 int ExternalMetrics::CollectEvents() {
97 ScopedVector
< ::metrics::MetricSample
> samples
;
98 ::metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(
99 uma_events_file_
, &samples
);
101 for (ScopedVector
< ::metrics::MetricSample
>::iterator it
= samples
.begin();
104 const ::metrics::MetricSample
& sample
= **it
;
106 switch (sample
.type()) {
107 case ::metrics::MetricSample::CRASH
:
108 RecordCrash(sample
.name());
110 case ::metrics::MetricSample::USER_ACTION
:
111 CastMetricsHelper::GetInstance()->RecordSimpleAction(sample
.name());
113 case ::metrics::MetricSample::HISTOGRAM
:
114 if (!CheckValues(sample
.name(), sample
.min(), sample
.max(),
115 sample
.bucket_count())) {
116 DLOG(ERROR
) << "Invalid histogram: " << sample
.name();
119 UMA_HISTOGRAM_CUSTOM_COUNTS_NO_CACHE(sample
.name(),
123 sample
.bucket_count());
125 case ::metrics::MetricSample::LINEAR_HISTOGRAM
:
126 if (!CheckLinearValues(sample
.name(), sample
.max())) {
127 DLOG(ERROR
) << "Invalid linear histogram: " << sample
.name();
130 UMA_HISTOGRAM_ENUMERATION_NO_CACHE(
131 sample
.name(), sample
.sample(), sample
.max());
133 case ::metrics::MetricSample::SPARSE_HISTOGRAM
:
134 RecordSparseHistogram(sample
);
139 return samples
.size();
142 void ExternalMetrics::CollectEventsAndReschedule() {
143 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
145 bool result
= content::BrowserThread::PostDelayedTask(
146 content::BrowserThread::FILE,
148 base::Bind(&ExternalMetrics::CollectEventsAndReschedule
,
149 weak_factory_
.GetWeakPtr()),
150 base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds
));
154 } // namespace metrics
155 } // namespace chromecast