1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/debug/trace_event_system_stats_monitor.h" 6 7#include "base/debug/leak_annotations.h" 8#include "base/debug/trace_event.h" 9#include "base/json/json_writer.h" 10#include "base/lazy_instance.h" 11#include "base/logging.h" 12#include "base/memory/scoped_ptr.h" 13#include "base/strings/string_number_conversions.h" 14#include "base/strings/string_util.h" 15#include "base/thread_task_runner_handle.h" 16#include "base/threading/thread_local_storage.h" 17 18namespace base { 19namespace debug { 20 21namespace { 22 23///////////////////////////////////////////////////////////////////////////// 24// Holds profiled system stats until the tracing system needs to serialize it. 25class SystemStatsHolder : public base::debug::ConvertableToTraceFormat { 26 public: 27 SystemStatsHolder() { } 28 29 // Fills system_metrics_ with profiled system memory and disk stats. 30 // Uses the previous stats to compute rates if this is not the first profile. 31 void GetSystemProfilingStats(); 32 33 // base::debug::ConvertableToTraceFormat overrides: 34 virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE { 35 AppendSystemProfileAsTraceFormat(system_stats_, out); 36 } 37 38 private: 39 virtual ~SystemStatsHolder() { } 40 41 SystemMetrics system_stats_; 42 43 DISALLOW_COPY_AND_ASSIGN(SystemStatsHolder); 44}; 45 46void SystemStatsHolder::GetSystemProfilingStats() { 47 system_stats_ = SystemMetrics::Sample(); 48} 49 50} // namespace 51 52////////////////////////////////////////////////////////////////////////////// 53 54TraceEventSystemStatsMonitor::TraceEventSystemStatsMonitor( 55 scoped_refptr<SingleThreadTaskRunner> task_runner) 56 : task_runner_(task_runner), 57 weak_factory_(this) { 58 // Force the "system_stats" category to show up in the trace viewer. 59 TraceLog::GetCategoryGroupEnabled(TRACE_DISABLED_BY_DEFAULT("system_stats")); 60 61 // Allow this to be instantiated on unsupported platforms, but don't run. 62 TraceLog::GetInstance()->AddEnabledStateObserver(this); 63} 64 65TraceEventSystemStatsMonitor::~TraceEventSystemStatsMonitor() { 66 if (dump_timer_.IsRunning()) 67 StopProfiling(); 68 TraceLog::GetInstance()->RemoveEnabledStateObserver(this); 69} 70 71void TraceEventSystemStatsMonitor::OnTraceLogEnabled() { 72 // Check to see if system tracing is enabled. 73 bool enabled; 74 75 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT( 76 "system_stats"), &enabled); 77 if (!enabled) 78 return; 79 task_runner_->PostTask( 80 FROM_HERE, 81 base::Bind(&TraceEventSystemStatsMonitor::StartProfiling, 82 weak_factory_.GetWeakPtr())); 83} 84 85void TraceEventSystemStatsMonitor::OnTraceLogDisabled() { 86 task_runner_->PostTask( 87 FROM_HERE, 88 base::Bind(&TraceEventSystemStatsMonitor::StopProfiling, 89 weak_factory_.GetWeakPtr())); 90} 91 92void TraceEventSystemStatsMonitor::StartProfiling() { 93 // Watch for the tracing framework sending enabling more than once. 94 if (dump_timer_.IsRunning()) 95 return; 96 97 dump_timer_.Start(FROM_HERE, 98 TimeDelta::FromMilliseconds(TraceEventSystemStatsMonitor:: 99 kSamplingIntervalMilliseconds), 100 base::Bind(&TraceEventSystemStatsMonitor:: 101 DumpSystemStats, 102 weak_factory_.GetWeakPtr())); 103} 104 105// If system tracing is enabled, dumps a profile to the tracing system. 106void TraceEventSystemStatsMonitor::DumpSystemStats() { 107 scoped_refptr<SystemStatsHolder> dump_holder = new SystemStatsHolder(); 108 dump_holder->GetSystemProfilingStats(); 109 110 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 111 TRACE_DISABLED_BY_DEFAULT("system_stats"), 112 "base::TraceEventSystemStatsMonitor::SystemStats", 113 this, 114 scoped_refptr<ConvertableToTraceFormat>(dump_holder)); 115} 116 117void TraceEventSystemStatsMonitor::StopProfiling() { 118 dump_timer_.Stop(); 119} 120 121bool TraceEventSystemStatsMonitor::IsTimerRunningForTest() const { 122 return dump_timer_.IsRunning(); 123} 124 125void AppendSystemProfileAsTraceFormat(const SystemMetrics& system_metrics, 126 std::string* output) { 127 std::string tmp; 128 base::JSONWriter::Write(system_metrics.ToValue().get(), &tmp); 129 *output += tmp; 130} 131 132} // namespace debug 133} // namespace base 134