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