OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "chromecast/browser/metrics/external_metrics.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/bind.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 "base/timer/elapsed_timer.h" |
| 16 #include "chromecast/base/metrics/cast_histograms.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" |
| 22 #include "content/public/browser/user_metrics.h" |
| 23 |
| 24 namespace chromecast { |
| 25 namespace metrics { |
| 26 |
| 27 namespace { |
| 28 |
| 29 bool CheckValues(const std::string& name, |
| 30 int minimum, |
| 31 int maximum, |
| 32 size_t bucket_count) { |
| 33 if (!base::Histogram::InspectConstructionArguments( |
| 34 name, &minimum, &maximum, &bucket_count)) |
| 35 return false; |
| 36 base::HistogramBase* histogram = |
| 37 base::StatisticsRecorder::FindHistogram(name); |
| 38 if (!histogram) |
| 39 return true; |
| 40 return histogram->HasConstructionArguments(minimum, maximum, bucket_count); |
| 41 } |
| 42 |
| 43 bool CheckLinearValues(const std::string& name, int maximum) { |
| 44 return CheckValues(name, 1, maximum, maximum + 1); |
| 45 } |
| 46 |
| 47 } // namespace |
| 48 |
| 49 // The interval between external metrics collections in seconds |
| 50 static const int kExternalMetricsCollectionIntervalSeconds = 30; |
| 51 const char kEventsFilePath[] = "/data/share/chrome/metrics/uma-events"; |
| 52 |
| 53 ExternalMetrics::ExternalMetrics( |
| 54 CastStabilityMetricsProvider* stability_provider) |
| 55 : stability_provider_(stability_provider), |
| 56 uma_events_file_(kEventsFilePath), |
| 57 weak_factory_(this) { |
| 58 DCHECK(stability_provider); |
| 59 } |
| 60 |
| 61 ExternalMetrics::~ExternalMetrics() {} |
| 62 |
| 63 void ExternalMetrics::Start() { |
| 64 ScheduleCollector(); |
| 65 } |
| 66 |
| 67 void ExternalMetrics::RecordAction(const std::string& action) { |
| 68 content::BrowserThread::PostTask( |
| 69 content::BrowserThread::UI, |
| 70 FROM_HERE, |
| 71 base::Bind(&content::RecordComputedAction, action)); |
| 72 } |
| 73 |
| 74 void ExternalMetrics::RecordCrash(const std::string& crash_kind) { |
| 75 content::BrowserThread::PostTask( |
| 76 content::BrowserThread::UI, FROM_HERE, |
| 77 base::Bind(&CastStabilityMetricsProvider::LogExternalCrash, |
| 78 base::Unretained(stability_provider_), |
| 79 crash_kind)); |
| 80 } |
| 81 |
| 82 void ExternalMetrics::RecordSparseHistogram( |
| 83 const ::metrics::MetricSample& sample) { |
| 84 CHECK_EQ(::metrics::MetricSample::SPARSE_HISTOGRAM, sample.type()); |
| 85 base::HistogramBase* counter = base::SparseHistogram::FactoryGet( |
| 86 sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag); |
| 87 counter->Add(sample.sample()); |
| 88 } |
| 89 |
| 90 int ExternalMetrics::CollectEvents() { |
| 91 ScopedVector< ::metrics::MetricSample> samples; |
| 92 ::metrics::SerializationUtils::ReadAndTruncateMetricsFromFile( |
| 93 uma_events_file_, &samples); |
| 94 |
| 95 for (ScopedVector< ::metrics::MetricSample>::iterator it = samples.begin(); |
| 96 it != samples.end(); |
| 97 ++it) { |
| 98 const ::metrics::MetricSample& sample = **it; |
| 99 |
| 100 switch (sample.type()) { |
| 101 case ::metrics::MetricSample::CRASH: |
| 102 RecordCrash(sample.name()); |
| 103 break; |
| 104 case ::metrics::MetricSample::USER_ACTION: |
| 105 RecordAction(sample.name()); |
| 106 break; |
| 107 case ::metrics::MetricSample::HISTOGRAM: |
| 108 if (!CheckValues(sample.name(), sample.min(), sample.max(), |
| 109 sample.bucket_count())) { |
| 110 DLOG(ERROR) << "Invalid histogram: " << sample.name(); |
| 111 break; |
| 112 } |
| 113 UMA_HISTOGRAM_CUSTOM_COUNTS_NO_CACHE( |
| 114 sample.name(), sample.sample(), sample.min(), sample.max(), |
| 115 sample.bucket_count()); |
| 116 break; |
| 117 case ::metrics::MetricSample::LINEAR_HISTOGRAM: |
| 118 if (!CheckLinearValues(sample.name(), sample.max())) { |
| 119 DLOG(ERROR) << "Invalid linear histogram: " << sample.name(); |
| 120 break; |
| 121 } |
| 122 UMA_HISTOGRAM_ENUMERATION_NO_CACHE( |
| 123 sample.name(), sample.sample(), sample.max()); |
| 124 break; |
| 125 case ::metrics::MetricSample::SPARSE_HISTOGRAM: |
| 126 RecordSparseHistogram(sample); |
| 127 break; |
| 128 } |
| 129 } |
| 130 |
| 131 return samples.size(); |
| 132 } |
| 133 |
| 134 void ExternalMetrics::CollectEventsAndReschedule() { |
| 135 base::ElapsedTimer timer; |
| 136 CollectEvents(); |
| 137 UMA_HISTOGRAM_TIMES("UMA.CollectExternalEventsTime", timer.Elapsed()); |
| 138 ScheduleCollector(); |
| 139 } |
| 140 |
| 141 void ExternalMetrics::ScheduleCollector() { |
| 142 bool result = content::BrowserThread::PostDelayedTask( |
| 143 content::BrowserThread::FILE, |
| 144 FROM_HERE, |
| 145 base::Bind(&ExternalMetrics::CollectEventsAndReschedule, |
| 146 weak_factory_.GetWeakPtr()), |
| 147 base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds)); |
| 148 DCHECK(result); |
| 149 } |
| 150 |
| 151 } // namespace metrics |
| 152 } // namespace chromecast |
OLD | NEW |