OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |