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

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: removed some unnecessary includes 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_run_.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 initial metrics since they're always reported
282 // before the first call to this method. It couldn't be released after
283 // being reported in RecordInitialHistogramSnapshots because the data
284 // will continue to be used by the caller after that method returns. Once
285 // here, though, all actions to be done on the data have been completed.
286 #if DCHECK_IS_ON()
287 for (const std::unique_ptr<FileInfo>& file : files_for_previous_run_)
288 DCHECK(file->read_complete);
289 #endif
290 files_for_previous_run_.clear();
291 }
292
293 bool FileMetricsProvider::HasInitialStabilityMetrics() {
294 DCHECK(thread_checker_.CalledOnValidThread());
295
296 // Measure the total time spent checking all files as well as the time
297 // per individual file. This method is called during startup and thus blocks
298 // the initial showing of the browser window so it's important to know the
299 // total delay.
300 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.InitialCheckTime.Total");
301
302 // Check all files for previous run to see if they need to be read.
303 for (auto iter = files_for_previous_run_.begin();
304 iter != files_for_previous_run_.end();) {
305 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.InitialCheckTime.File");
306
307 auto temp = iter++;
308 FileInfo* file = temp->get();
309
310 // This would normally be done on a background I/O thread but there
311 // hasn't been a chance to run any at the time this method is called.
312 // Do the check in-line.
313 AccessResult result = CheckAndMapNewMetrics(file);
314 UMA_HISTOGRAM_ENUMERATION("UMA.FileMetricsProvider.InitialAccessResult",
315 result, ACCESS_RESULT_MAX);
316
317 // If it couldn't be accessed, remove it from the list. There is only ever
318 // one chance to record it so no point keeping it around for later. Also
319 // mark it as having been read since uploading it with a future browser
320 // run would associate it with the previous run which would no longer be
321 // the run from which it came.
322 if (result != ACCESS_RESULT_SUCCESS) {
323 RecordFileAsSeen(file);
324 files_for_previous_run_.erase(temp);
325 }
326 }
327
328 return !files_for_previous_run_.empty();
271 } 329 }
272 330
273 void FileMetricsProvider::RecordHistogramSnapshots( 331 void FileMetricsProvider::RecordHistogramSnapshots(
274 base::HistogramSnapshotManager* snapshot_manager) { 332 base::HistogramSnapshotManager* snapshot_manager) {
275 DCHECK(thread_checker_.CalledOnValidThread()); 333 DCHECK(thread_checker_.CalledOnValidThread());
276 334
335 // Measure the total time spent processing all files as well as the time
336 // per individual file. This method is called on the UI thread so it's
337 // important to know how much total "jank" may be introduced.
338 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.SnapshotTime.Total");
339
277 for (std::unique_ptr<FileInfo>& file : files_to_read_) { 340 for (std::unique_ptr<FileInfo>& file : files_to_read_) {
278 // Skip this file if the data has already been read. 341 // Skip this file if the data has already been read.
279 if (file->read_complete) 342 if (file->read_complete)
280 continue; 343 continue;
281 344
345 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.SnapshotTime.File");
346
282 // If the file is mapped or loaded then it needs to have an allocator 347 // If the file is mapped or loaded then it needs to have an allocator
283 // attached to it in order to read histograms out of it. 348 // attached to it in order to read histograms out of it.
284 if (file->mapped || !file->data.empty()) 349 if (file->mapped || !file->data.empty())
285 CreateAllocatorForFile(file.get()); 350 CreateAllocatorForFile(file.get());
286 351
287 // A file should not be under "files to read" unless it has an allocator 352 // A file should not be under "files to read" unless it has an allocator
288 // or is memory-mapped (at which point it will have received an allocator 353 // or is memory-mapped (at which point it will have received an allocator
289 // above). However, if this method gets called twice before the scheduled- 354 // above). However, if this method gets called twice before the scheduled-
290 // files-check has a chance to clean up, this may trigger. This also 355 // files-check has a chance to clean up, this may trigger. This also
291 // catches the case where creating an allocator from the file has failed. 356 // catches the case where creating an allocator from the file has failed.
292 if (!file->allocator) 357 if (!file->allocator)
293 continue; 358 continue;
294 359
295 // Dump all histograms contained within the file to the snapshot-manager. 360 // Dump all histograms contained within the file to the snapshot-manager.
296 RecordHistogramSnapshotsFromFile(snapshot_manager, file.get()); 361 RecordHistogramSnapshotsFromFile(snapshot_manager, file.get());
297 362
298 // Update the last-seen time so it isn't read again unless it changes. 363 // Update the last-seen time so it isn't read again unless it changes.
299 RecordFileAsSeen(file.get()); 364 RecordFileAsSeen(file.get());
300 } 365 }
301 } 366 }
302 367
368 void FileMetricsProvider::RecordInitialHistogramSnapshots(
369 base::HistogramSnapshotManager* snapshot_manager) {
370 DCHECK(thread_checker_.CalledOnValidThread());
371
372 // Measure the total time spent processing all files as well as the time
373 // per individual file. This method is called during startup and thus blocks
374 // the initial showing of the browser window so it's important to know the
375 // total delay.
376 SCOPED_UMA_HISTOGRAM_TIMER(
377 "UMA.FileMetricsProvider.InitialTotalSnapshotTime");
378
379 for (const std::unique_ptr<FileInfo>& file : files_for_previous_run_) {
380 SCOPED_UMA_HISTOGRAM_TIMER(
381 "UMA.FileMetricsProvider.InitialFileSnapshotTime");
382
383 // The file needs to have an allocator attached to it in order to read
384 // histograms out of it.
385 DCHECK(file->mapped || !file->data.empty());
386 CreateAllocatorForFile(file.get());
387 DCHECK(file->allocator);
388
389 // Dump all histograms contained within the file to the snapshot-manager.
390 RecordHistogramSnapshotsFromFile(snapshot_manager, file.get());
391
392 // Update the last-seen time so it isn't read again unless it changes.
393 RecordFileAsSeen(file.get());
394 }
395 }
396
303 } // namespace metrics 397 } // namespace metrics
OLDNEW
« no previous file with comments | « components/metrics/file_metrics_provider.h ('k') | components/metrics/file_metrics_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698