Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "base/at_exit.h" | 7 #include "base/at_exit.h" |
| 8 #include "base/debug/leak_annotations.h" | 8 #include "base/debug/leak_annotations.h" |
| 9 #include "base/json/string_escape.h" | 9 #include "base/json/string_escape.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/metrics/metrics_hashes.h" | 13 #include "base/metrics/metrics_hashes.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 17 #include "base/values.h" | 17 #include "base/values.h" |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // Initialize histogram statistics gathering system. | 21 // Initialize histogram statistics gathering system. |
| 22 base::LazyInstance<base::StatisticsRecorder>::Leaky g_statistics_recorder_ = | 22 base::LazyInstance<base::StatisticsRecorder>::Leaky g_statistics_recorder_ = |
| 23 LAZY_INSTANCE_INITIALIZER; | 23 LAZY_INSTANCE_INITIALIZER; |
| 24 | 24 |
| 25 bool g_vlog_initialized = false; | |
|
Alexei Svitkine (slow)
2016/04/14 20:47:39
Can this just be a member of the StatisticsRecorde
| |
| 26 | |
| 25 bool HistogramNameLesser(const base::HistogramBase* a, | 27 bool HistogramNameLesser(const base::HistogramBase* a, |
| 26 const base::HistogramBase* b) { | 28 const base::HistogramBase* b) { |
| 27 return a->histogram_name() < b->histogram_name(); | 29 return a->histogram_name() < b->histogram_name(); |
| 28 } | 30 } |
| 29 | 31 |
| 30 } // namespace | 32 } // namespace |
| 31 | 33 |
| 32 namespace base { | 34 namespace base { |
| 33 | 35 |
| 34 StatisticsRecorder::HistogramIterator::HistogramIterator( | 36 StatisticsRecorder::HistogramIterator::HistogramIterator( |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 bool include_persistent) { | 293 bool include_persistent) { |
| 292 return HistogramIterator(histograms_->begin(), include_persistent); | 294 return HistogramIterator(histograms_->begin(), include_persistent); |
| 293 } | 295 } |
| 294 | 296 |
| 295 // static | 297 // static |
| 296 StatisticsRecorder::HistogramIterator StatisticsRecorder::end() { | 298 StatisticsRecorder::HistogramIterator StatisticsRecorder::end() { |
| 297 return HistogramIterator(histograms_->end(), true); | 299 return HistogramIterator(histograms_->end(), true); |
| 298 } | 300 } |
| 299 | 301 |
| 300 // static | 302 // static |
| 303 void StatisticsRecorder::InitLogOnShutdown() { | |
| 304 if (lock_ == nullptr) | |
| 305 return; | |
| 306 base::AutoLock auto_lock(*lock_); | |
| 307 g_statistics_recorder_.Get().InitLogOnShutdownWithoutLock(); | |
| 308 } | |
| 309 | |
| 310 // static | |
| 311 bool StatisticsRecorder::VLogInitializedForTesting() { | |
| 312 return g_vlog_initialized; | |
| 313 } | |
| 314 | |
| 315 // static | |
| 301 void StatisticsRecorder::GetSnapshot(const std::string& query, | 316 void StatisticsRecorder::GetSnapshot(const std::string& query, |
| 302 Histograms* snapshot) { | 317 Histograms* snapshot) { |
| 303 if (lock_ == NULL) | 318 if (lock_ == NULL) |
| 304 return; | 319 return; |
| 305 base::AutoLock auto_lock(*lock_); | 320 base::AutoLock auto_lock(*lock_); |
| 306 if (histograms_ == NULL) | 321 if (histograms_ == NULL) |
| 307 return; | 322 return; |
| 308 | 323 |
| 309 for (const auto& entry : *histograms_) { | 324 for (const auto& entry : *histograms_) { |
| 310 if (entry.second->histogram_name().find(query) != std::string::npos) | 325 if (entry.second->histogram_name().find(query) != std::string::npos) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 // during the termination phase. Since it's a static data member, we will | 407 // during the termination phase. Since it's a static data member, we will |
| 393 // leak one per process, which would be similar to the instance allocated | 408 // leak one per process, which would be similar to the instance allocated |
| 394 // during static initialization and released only on process termination. | 409 // during static initialization and released only on process termination. |
| 395 lock_ = new base::Lock; | 410 lock_ = new base::Lock; |
| 396 } | 411 } |
| 397 base::AutoLock auto_lock(*lock_); | 412 base::AutoLock auto_lock(*lock_); |
| 398 histograms_ = new HistogramMap; | 413 histograms_ = new HistogramMap; |
| 399 callbacks_ = new CallbackMap; | 414 callbacks_ = new CallbackMap; |
| 400 ranges_ = new RangesMap; | 415 ranges_ = new RangesMap; |
| 401 | 416 |
| 402 if (VLOG_IS_ON(1)) | 417 InitLogOnShutdownWithoutLock(); |
| 403 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); | |
| 404 } | 418 } |
| 405 | 419 |
| 406 StatisticsRecorder::~StatisticsRecorder() { | 420 StatisticsRecorder::~StatisticsRecorder() { |
| 407 DCHECK(histograms_ && ranges_ && lock_); | 421 DCHECK(histograms_ && ranges_ && lock_); |
| 408 | 422 |
| 409 // Global clean up. | 423 // Global clean up. |
| 410 Reset(); | 424 Reset(); |
| 411 } | 425 } |
| 412 | 426 |
| 427 void StatisticsRecorder::InitLogOnShutdownWithoutLock() { | |
| 428 if (!g_vlog_initialized && VLOG_IS_ON(1)) { | |
| 429 g_vlog_initialized = true; | |
| 430 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); | |
| 431 } | |
| 432 } | |
| 433 | |
| 413 // static | 434 // static |
| 414 void StatisticsRecorder::Reset() { | 435 void StatisticsRecorder::Reset() { |
| 415 // If there's no lock then there is nothing to reset. | 436 // If there's no lock then there is nothing to reset. |
| 416 if (!lock_) | 437 if (!lock_) |
| 417 return; | 438 return; |
| 418 | 439 |
| 419 scoped_ptr<HistogramMap> histograms_deleter; | 440 scoped_ptr<HistogramMap> histograms_deleter; |
| 420 scoped_ptr<CallbackMap> callbacks_deleter; | 441 scoped_ptr<CallbackMap> callbacks_deleter; |
| 421 scoped_ptr<RangesMap> ranges_deleter; | 442 scoped_ptr<RangesMap> ranges_deleter; |
| 422 // We don't delete lock_ on purpose to avoid having to properly protect | 443 // We don't delete lock_ on purpose to avoid having to properly protect |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 444 // static | 465 // static |
| 445 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 466 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
| 446 // static | 467 // static |
| 447 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; | 468 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; |
| 448 // static | 469 // static |
| 449 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; | 470 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; |
| 450 // static | 471 // static |
| 451 base::Lock* StatisticsRecorder::lock_ = NULL; | 472 base::Lock* StatisticsRecorder::lock_ = NULL; |
| 452 | 473 |
| 453 } // namespace base | 474 } // namespace base |
| OLD | NEW |