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

Side by Side Diff: base/metrics/statistics_recorder.cc

Issue 2658163002: Merge histograms from providers into StatisticsRecorder for display. (Closed)
Patch Set: some cleanup; added test Created 3 years, 10 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/metrics/statistics_recorder.h" 5 #include "base/metrics/statistics_recorder.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/at_exit.h" 9 #include "base/at_exit.h"
10 #include "base/debug/leak_annotations.h" 10 #include "base/debug/leak_annotations.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 StatisticsRecorder::~StatisticsRecorder() { 80 StatisticsRecorder::~StatisticsRecorder() {
81 DCHECK(histograms_); 81 DCHECK(histograms_);
82 DCHECK(ranges_); 82 DCHECK(ranges_);
83 83
84 // Clean out what this object created and then restore what existed before. 84 // Clean out what this object created and then restore what existed before.
85 Reset(); 85 Reset();
86 base::AutoLock auto_lock(lock_.Get()); 86 base::AutoLock auto_lock(lock_.Get());
87 histograms_ = existing_histograms_.release(); 87 histograms_ = existing_histograms_.release();
88 callbacks_ = existing_callbacks_.release(); 88 callbacks_ = existing_callbacks_.release();
89 ranges_ = existing_ranges_.release(); 89 ranges_ = existing_ranges_.release();
90 providers_ = existing_providers_.release();
90 } 91 }
91 92
92 // static 93 // static
93 void StatisticsRecorder::Initialize() { 94 void StatisticsRecorder::Initialize() {
94 // Tests sometimes create local StatisticsRecorders in order to provide a 95 // Tests sometimes create local StatisticsRecorders in order to provide a
95 // contained environment of histograms that can be later discarded. If a 96 // contained environment of histograms that can be later discarded. If a
96 // true global instance gets created in this environment then it will 97 // true global instance gets created in this environment then it will
97 // eventually get disconnected when the local instance destructs and 98 // eventually get disconnected when the local instance destructs and
98 // restores the previous state, resulting in no StatisticsRecorder at all. 99 // restores the previous state, resulting in no StatisticsRecorder at all.
99 // The global lazy instance, however, will remain valid thus ensuring that 100 // The global lazy instance, however, will remain valid thus ensuring that
100 // another never gets installed via this method. If a |histograms_| map 101 // another never gets installed via this method. If a |histograms_| map
101 // exists then assume the StatisticsRecorder is already "initialized". 102 // exists then assume the StatisticsRecorder is already "initialized".
102 if (histograms_) 103 if (histograms_)
103 return; 104 return;
104 105
105 // Ensure that an instance of the StatisticsRecorder object is created. 106 // Ensure that an instance of the StatisticsRecorder object is created.
106 g_statistics_recorder_.Get(); 107 g_statistics_recorder_.Get();
107 } 108 }
108 109
109 // static 110 // static
110 bool StatisticsRecorder::IsActive() { 111 bool StatisticsRecorder::IsActive() {
111 base::AutoLock auto_lock(lock_.Get()); 112 base::AutoLock auto_lock(lock_.Get());
112 return histograms_ != nullptr; 113 return histograms_ != nullptr;
113 } 114 }
114 115
115 // static 116 // static
117 void StatisticsRecorder::RegisterHistogramProvider(
118 const WeakPtr<HistogramProvider>& provider) {
119 providers_->push_back(provider);
120 }
121
122 // static
116 HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate( 123 HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate(
117 HistogramBase* histogram) { 124 HistogramBase* histogram) {
118 HistogramBase* histogram_to_delete = nullptr; 125 HistogramBase* histogram_to_delete = nullptr;
119 HistogramBase* histogram_to_return = nullptr; 126 HistogramBase* histogram_to_return = nullptr;
120 { 127 {
121 base::AutoLock auto_lock(lock_.Get()); 128 base::AutoLock auto_lock(lock_.Get());
122 if (!histograms_) { 129 if (!histograms_) {
123 histogram_to_return = histogram; 130 histogram_to_return = histogram;
124 131
125 // As per crbug.com/79322 the histograms are intentionally leaked, so we 132 // As per crbug.com/79322 the histograms are intentionally leaked, so we
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 if (!histograms_) 307 if (!histograms_)
301 return nullptr; 308 return nullptr;
302 309
303 HistogramMap::iterator it = histograms_->find(name); 310 HistogramMap::iterator it = histograms_->find(name);
304 if (histograms_->end() == it) 311 if (histograms_->end() == it)
305 return nullptr; 312 return nullptr;
306 return it->second; 313 return it->second;
307 } 314 }
308 315
309 // static 316 // static
317 void StatisticsRecorder::ImportProvidedHistograms() {
Alexei Svitkine (slow) 2017/01/27 16:22:03 Can you add a thread check here?
bcwhite 2017/01/27 18:05:31 Not sure if I can because base/ doesn't generally
Alexei Svitkine (slow) 2017/01/27 18:06:57 Can you add base::ThreadChecker as a member and us
bcwhite 2017/01/27 18:12:57 These are static methods so there's no object to h
318 if (!providers_)
319 return;
320
321 // Merge histogram data from each provider in turn.
322 for (const WeakPtr<HistogramProvider>& provider : *providers_) {
323 if (provider)
Alexei Svitkine (slow) 2017/01/27 16:22:03 Nit: Maybe add a comment here to mention this is c
bcwhite 2017/01/27 18:05:31 Done.
324 provider->MergeHistogramDeltas();
325 }
326 }
327
328 // static
310 StatisticsRecorder::HistogramIterator StatisticsRecorder::begin( 329 StatisticsRecorder::HistogramIterator StatisticsRecorder::begin(
311 bool include_persistent) { 330 bool include_persistent) {
312 DCHECK(histograms_); 331 DCHECK(histograms_);
313 ImportGlobalPersistentHistograms(); 332 ImportGlobalPersistentHistograms();
314 333
315 HistogramMap::iterator iter_begin; 334 HistogramMap::iterator iter_begin;
316 { 335 {
317 base::AutoLock auto_lock(lock_.Get()); 336 base::AutoLock auto_lock(lock_.Get());
318 iter_begin = histograms_->begin(); 337 iter_begin = histograms_->begin();
319 } 338 }
(...skipping 19 matching lines...) Expand all
339 g_statistics_recorder_.Get().InitLogOnShutdownWithoutLock(); 358 g_statistics_recorder_.Get().InitLogOnShutdownWithoutLock();
340 } 359 }
341 360
342 // static 361 // static
343 void StatisticsRecorder::GetSnapshot(const std::string& query, 362 void StatisticsRecorder::GetSnapshot(const std::string& query,
344 Histograms* snapshot) { 363 Histograms* snapshot) {
345 base::AutoLock auto_lock(lock_.Get()); 364 base::AutoLock auto_lock(lock_.Get());
346 if (!histograms_) 365 if (!histograms_)
347 return; 366 return;
348 367
368 ImportGlobalPersistentHistograms();
369
349 for (const auto& entry : *histograms_) { 370 for (const auto& entry : *histograms_) {
350 if (entry.second->histogram_name().find(query) != std::string::npos) 371 if (entry.second->histogram_name().find(query) != std::string::npos)
351 snapshot->push_back(entry.second); 372 snapshot->push_back(entry.second);
352 } 373 }
353 } 374 }
354 375
355 // static 376 // static
356 bool StatisticsRecorder::SetCallback( 377 bool StatisticsRecorder::SetCallback(
357 const std::string& name, 378 const std::string& name,
358 const StatisticsRecorder::OnSampleCallback& cb) { 379 const StatisticsRecorder::OnSampleCallback& cb) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 472
452 // This singleton instance should be started during the single threaded portion 473 // This singleton instance should be started during the single threaded portion
453 // of main(), and hence it is not thread safe. It initializes globals to 474 // of main(), and hence it is not thread safe. It initializes globals to
454 // provide support for all future calls. 475 // provide support for all future calls.
455 StatisticsRecorder::StatisticsRecorder() { 476 StatisticsRecorder::StatisticsRecorder() {
456 base::AutoLock auto_lock(lock_.Get()); 477 base::AutoLock auto_lock(lock_.Get());
457 478
458 existing_histograms_.reset(histograms_); 479 existing_histograms_.reset(histograms_);
459 existing_callbacks_.reset(callbacks_); 480 existing_callbacks_.reset(callbacks_);
460 existing_ranges_.reset(ranges_); 481 existing_ranges_.reset(ranges_);
482 existing_providers_.reset(providers_);
461 483
462 histograms_ = new HistogramMap; 484 histograms_ = new HistogramMap;
463 callbacks_ = new CallbackMap; 485 callbacks_ = new CallbackMap;
464 ranges_ = new RangesMap; 486 ranges_ = new RangesMap;
487 providers_ = new HistogramProviders;
465 488
466 InitLogOnShutdownWithoutLock(); 489 InitLogOnShutdownWithoutLock();
467 } 490 }
468 491
469 void StatisticsRecorder::InitLogOnShutdownWithoutLock() { 492 void StatisticsRecorder::InitLogOnShutdownWithoutLock() {
470 if (!vlog_initialized_ && VLOG_IS_ON(1)) { 493 if (!vlog_initialized_ && VLOG_IS_ON(1)) {
471 vlog_initialized_ = true; 494 vlog_initialized_ = true;
472 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); 495 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this);
473 } 496 }
474 } 497 }
475 498
476 // static 499 // static
477 void StatisticsRecorder::Reset() { 500 void StatisticsRecorder::Reset() {
478 501
479 std::unique_ptr<HistogramMap> histograms_deleter; 502 std::unique_ptr<HistogramMap> histograms_deleter;
480 std::unique_ptr<CallbackMap> callbacks_deleter; 503 std::unique_ptr<CallbackMap> callbacks_deleter;
481 std::unique_ptr<RangesMap> ranges_deleter; 504 std::unique_ptr<RangesMap> ranges_deleter;
505 std::unique_ptr<HistogramProviders> providers_deleter;
482 { 506 {
483 base::AutoLock auto_lock(lock_.Get()); 507 base::AutoLock auto_lock(lock_.Get());
484 histograms_deleter.reset(histograms_); 508 histograms_deleter.reset(histograms_);
485 callbacks_deleter.reset(callbacks_); 509 callbacks_deleter.reset(callbacks_);
486 ranges_deleter.reset(ranges_); 510 ranges_deleter.reset(ranges_);
511 providers_deleter.reset(providers_);
487 histograms_ = nullptr; 512 histograms_ = nullptr;
488 callbacks_ = nullptr; 513 callbacks_ = nullptr;
489 ranges_ = nullptr; 514 ranges_ = nullptr;
515 providers_ = nullptr;
490 } 516 }
491 // We are going to leak the histograms and the ranges. 517 // We are going to leak the histograms and the ranges.
492 } 518 }
493 519
494 // static 520 // static
495 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) { 521 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) {
496 std::string output; 522 std::string output;
497 StatisticsRecorder::WriteGraph(std::string(), &output); 523 StatisticsRecorder::WriteGraph(std::string(), &output);
498 VLOG(1) << output; 524 VLOG(1) << output;
499 } 525 }
500 526
501 527
502 // static 528 // static
503 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = nullptr; 529 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = nullptr;
504 // static 530 // static
505 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr; 531 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr;
506 // static 532 // static
507 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr; 533 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr;
508 // static 534 // static
535 StatisticsRecorder::HistogramProviders* StatisticsRecorder::providers_;
536 // static
509 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ = 537 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ =
510 LAZY_INSTANCE_INITIALIZER; 538 LAZY_INSTANCE_INITIALIZER;
511 539
512 } // namespace base 540 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698