Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: components/metrics/file_metrics_provider.cc

Issue 1891913002: Support saving browser metrics to disk and reading them during next run. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove DCHECK_IS_ON from .h files because it's not always defined and don't want to add the include Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/metrics/file_metrics_provider.h" 5 #include "components/metrics/file_metrics_provider.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/files/file.h" 8 #include "base/files/file.h"
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/files/memory_mapped_file.h" 10 #include "base/files/memory_mapped_file.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 PrefService* local_state) 62 PrefService* local_state)
63 : task_runner_(task_runner), 63 : task_runner_(task_runner),
64 pref_service_(local_state), 64 pref_service_(local_state),
65 weak_factory_(this) { 65 weak_factory_(this) {
66 } 66 }
67 67
68 FileMetricsProvider::~FileMetricsProvider() {} 68 FileMetricsProvider::~FileMetricsProvider() {}
69 69
70 void FileMetricsProvider::RegisterFile(const base::FilePath& path, 70 void FileMetricsProvider::RegisterFile(const base::FilePath& path,
71 FileType type, 71 FileType type,
72 FileAssociation file_association,
72 const base::StringPiece prefs_key) { 73 const base::StringPiece prefs_key) {
73 DCHECK(thread_checker_.CalledOnValidThread()); 74 DCHECK(thread_checker_.CalledOnValidThread());
74 75
75 std::unique_ptr<FileInfo> file(new FileInfo(type)); 76 std::unique_ptr<FileInfo> file(new FileInfo(type));
76 file->path = path; 77 file->path = path;
77 file->prefs_key = prefs_key.as_string(); 78 file->prefs_key = prefs_key.as_string();
78 79
79 // |prefs_key| may be empty if the caller does not wish to persist the 80 // |prefs_key| may be empty if the caller does not wish to persist the
80 // state across instances of the program. 81 // state across instances of the program.
81 if (pref_service_ && !prefs_key.empty()) { 82 if (pref_service_ && !prefs_key.empty()) {
82 file->last_seen = base::Time::FromInternalValue( 83 file->last_seen = base::Time::FromInternalValue(
83 pref_service_->GetInt64(metrics::prefs::kMetricsLastSeenPrefix + 84 pref_service_->GetInt64(metrics::prefs::kMetricsLastSeenPrefix +
84 file->prefs_key)); 85 file->prefs_key));
85 } 86 }
86 87
87 files_to_check_.push_back(std::move(file)); 88 switch (file_association) {
89 case ASSOCIATE_CURRENT_RUN:
90 files_to_check_.push_back(std::move(file));
91 break;
92 case ASSOCIATE_PREVIOUS_RUN:
93 DCHECK_EQ(FILE_HISTOGRAMS_ATOMIC, file->type);
94 files_for_previous_.push_back(std::move(file));
95 break;
96 }
88 } 97 }
89 98
90 // static 99 // static
91 void FileMetricsProvider::RegisterPrefs(PrefRegistrySimple* prefs, 100 void FileMetricsProvider::RegisterPrefs(PrefRegistrySimple* prefs,
92 const base::StringPiece prefs_key) { 101 const base::StringPiece prefs_key) {
93 prefs->RegisterInt64Pref(metrics::prefs::kMetricsLastSeenPrefix + 102 prefs->RegisterInt64Pref(metrics::prefs::kMetricsLastSeenPrefix +
94 prefs_key.as_string(), 0); 103 prefs_key.as_string(), 0);
95 } 104 }
96 105
97 // static 106 // static
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 DCHECK(thread_checker_.CalledOnValidThread()); 189 DCHECK(thread_checker_.CalledOnValidThread());
181 base::PersistentHistogramAllocator::Iterator histogram_iter( 190 base::PersistentHistogramAllocator::Iterator histogram_iter(
182 file->allocator.get()); 191 file->allocator.get());
183 192
184 int histogram_count = 0; 193 int histogram_count = 0;
185 while (true) { 194 while (true) {
186 std::unique_ptr<base::HistogramBase> histogram = histogram_iter.GetNext(); 195 std::unique_ptr<base::HistogramBase> histogram = histogram_iter.GetNext();
187 if (!histogram) 196 if (!histogram)
188 break; 197 break;
189 if (file->type == FILE_HISTOGRAMS_ATOMIC) 198 if (file->type == FILE_HISTOGRAMS_ATOMIC)
190 snapshot_manager->PrepareAbsoluteTakingOwnership(std::move(histogram)); 199 snapshot_manager->PrepareFinalDeltaTakingOwnership(std::move(histogram));
191 else 200 else
192 snapshot_manager->PrepareDeltaTakingOwnership(std::move(histogram)); 201 snapshot_manager->PrepareDeltaTakingOwnership(std::move(histogram));
193 ++histogram_count; 202 ++histogram_count;
194 } 203 }
195 204
196 DVLOG(1) << "Reported " << histogram_count << " histograms from " 205 DVLOG(1) << "Reported " << histogram_count << " histograms from "
197 << file->path.value(); 206 << file->path.value();
198 } 207 }
199 208
200 void FileMetricsProvider::CreateAllocatorForFile(FileInfo* file) { 209 void FileMetricsProvider::CreateAllocatorForFile(FileInfo* file) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 270
262 if (!file->allocator && !file->mapped && file->data.empty()) 271 if (!file->allocator && !file->mapped && file->data.empty())
263 files_to_check_.splice(files_to_check_.end(), files_to_read_, temp); 272 files_to_check_.splice(files_to_check_.end(), files_to_read_, temp);
264 } 273 }
265 274
266 // Schedule a check to see if there are new metrics to load. If so, they 275 // Schedule a check to see if there are new metrics to load. If so, they
267 // will be reported during the next collection run after this one. The 276 // will be reported during the next collection run after this one. The
268 // check is run off of the worker-pool so as to not cause delays on the 277 // check is run off of the worker-pool so as to not cause delays on the
269 // main UI thread (which is currently where metric collection is done). 278 // main UI thread (which is currently where metric collection is done).
270 ScheduleFilesCheck(); 279 ScheduleFilesCheck();
280
281 // Clear any data for stability metrics since they're always reported
282 // before the first call to this method.
Ilya Sherman 2016/05/04 06:48:07 Hrm, why not clear them when they're reported?
bcwhite 2016/05/04 14:12:51 They have to live until the reporting is complete
Ilya Sherman 2016/05/05 07:22:37 FileInfo just provides file metadata, right? How
bcwhite 2016/05/05 16:01:17 It has all the information related to the file, in
283 #if DCHECK_IS_ON()
284 for (std::unique_ptr<FileInfo>& file : files_for_previous_)
Ilya Sherman 2016/05/04 06:48:07 nit: "const auto&"?
bcwhite 2016/05/04 14:12:51 Done.
285 DCHECK(file->read_complete);
286 #endif
287 files_for_previous_.clear();
288 }
289
290 bool FileMetricsProvider::HasInitialStabilityMetrics() {
291 DCHECK(thread_checker_.CalledOnValidThread());
292
293 // Check all files for previous run to see if they need to be read.
294 for (auto iter = files_for_previous_.begin();
295 iter != files_for_previous_.end();) {
296 auto temp = iter++;
Ilya Sherman 2016/05/04 06:48:07 "iter++" is strongly discouraged, because it can b
bcwhite 2016/05/04 14:12:51 Post-increment is definitely more efficient but ++
Ilya Sherman 2016/05/05 07:22:37 I disagree pretty strongly on this point. For a l
bcwhite 2016/05/05 16:01:17 My expectations differ from yours, then, because i
297 FileInfo* file = temp->get();
298
299 // This would normally be done on a background I/O thread but there
300 // hasn't been a chance to run any at the time this method is called.
301 // Do the check in-line.
Ilya Sherman 2016/05/04 06:48:07 Hmm, this sounds a bit disconcerting. Are we doin
bcwhite 2016/05/04 14:12:51 This method is called during startup and must retu
Ilya Sherman 2016/05/05 07:22:37 Erm, why does this block startup? If that's true,
bcwhite 2016/05/05 16:01:17 All metrics work is done on the main UI thread. A
Ilya Sherman 2016/05/05 22:22:52 Hmm, I see that you're right. I still find this p
302 AccessResult result = CheckAndMapNewMetrics(file);
303 UMA_HISTOGRAM_ENUMERATION("UMA.FileMetricsProvider.StabilityAccessResult",
304 result, ACCESS_RESULT_MAX);
305
306 // If it couldn't be accessed, remove it from the list. There is only ever
307 // one chance to record it no point keeping it around for later. Also mark
308 // it as having been read since uploading it with a future browser run
309 // would associate it the previous run which would no longer be the run
310 // from which it came.
311 if (result != ACCESS_RESULT_SUCCESS) {
312 RecordFileAsSeen(file);
313 files_for_previous_.erase(temp);
314 }
315 }
316
317 return !files_for_previous_.empty();
271 } 318 }
272 319
273 void FileMetricsProvider::RecordHistogramSnapshots( 320 void FileMetricsProvider::RecordHistogramSnapshots(
274 base::HistogramSnapshotManager* snapshot_manager) { 321 base::HistogramSnapshotManager* snapshot_manager) {
275 DCHECK(thread_checker_.CalledOnValidThread()); 322 DCHECK(thread_checker_.CalledOnValidThread());
276 323
277 for (std::unique_ptr<FileInfo>& file : files_to_read_) { 324 for (std::unique_ptr<FileInfo>& file : files_to_read_) {
278 // Skip this file if the data has already been read. 325 // Skip this file if the data has already been read.
279 if (file->read_complete) 326 if (file->read_complete)
280 continue; 327 continue;
(...skipping 12 matching lines...) Expand all
293 continue; 340 continue;
294 341
295 // Dump all histograms contained within the file to the snapshot-manager. 342 // Dump all histograms contained within the file to the snapshot-manager.
296 RecordHistogramSnapshotsFromFile(snapshot_manager, file.get()); 343 RecordHistogramSnapshotsFromFile(snapshot_manager, file.get());
297 344
298 // Update the last-seen time so it isn't read again unless it changes. 345 // Update the last-seen time so it isn't read again unless it changes.
299 RecordFileAsSeen(file.get()); 346 RecordFileAsSeen(file.get());
300 } 347 }
301 } 348 }
302 349
350 void FileMetricsProvider::RecordStabilityHistogramSnapshots(
351 base::HistogramSnapshotManager* snapshot_manager) {
352 DCHECK(thread_checker_.CalledOnValidThread());
353
354 for (std::unique_ptr<FileInfo>& file : files_for_previous_) {
Ilya Sherman 2016/05/04 06:48:07 nit: "const auto&"?
bcwhite 2016/05/04 14:12:51 Done.
355 // The file needs to have an allocator attached to it in order to read
356 // histograms out of it.
357 DCHECK(file->mapped || !file->data.empty());
358 CreateAllocatorForFile(file.get());
Ilya Sherman 2016/05/04 06:48:07 Is this doing file I/O on the main thread?
bcwhite 2016/05/04 14:12:51 Yes, for the same reason as HasInitialStabilityMet
359 DCHECK(file->allocator);
360
361 // Dump all histograms contained within the file to the snapshot-manager.
362 RecordHistogramSnapshotsFromFile(snapshot_manager, file.get());
363
364 // Update the last-seen time so it isn't read again unless it changes.
365 RecordFileAsSeen(file.get());
366 }
367 }
368
303 } // namespace metrics 369 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698