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 18 namespace base { 19 namespace debug { 20 21 namespace { 22 23 ///////////////////////////////////////////////////////////////////////////// 24 // Holds profiled system stats until the tracing system needs to serialize it. 25 class 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 46 void SystemStatsHolder::GetSystemProfilingStats() { 47 system_stats_ = SystemMetrics::Sample(); 48 } 49 50 } // namespace 51 52 ////////////////////////////////////////////////////////////////////////////// 53 54 TraceEventSystemStatsMonitor::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 65 TraceEventSystemStatsMonitor::~TraceEventSystemStatsMonitor() { 66 if (dump_timer_.IsRunning()) 67 StopProfiling(); 68 TraceLog::GetInstance()->RemoveEnabledStateObserver(this); 69 } 70 71 void 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 85 void TraceEventSystemStatsMonitor::OnTraceLogDisabled() { 86 task_runner_->PostTask( 87 FROM_HERE, 88 base::Bind(&TraceEventSystemStatsMonitor::StopProfiling, 89 weak_factory_.GetWeakPtr())); 90 } 91 92 void 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. 106 void 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 117 void TraceEventSystemStatsMonitor::StopProfiling() { 118 dump_timer_.Stop(); 119 } 120 121 bool TraceEventSystemStatsMonitor::IsTimerRunningForTest() const { 122 return dump_timer_.IsRunning(); 123 } 124 125 void 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