summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzhenw <zhenw@chromium.org>2015-12-15 10:07:27 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-15 18:09:10 +0000
commitb0b2a7f0fd7f6ec4a43f735e643a1f2f90351dc8 (patch)
tree83231e1910f5fbec30b9306a98f13083e5cae6c2
parenta3b91bd3cff4e98ec20bfbf79d37438c6f561e45 (diff)
downloadchromium_src-b0b2a7f0fd7f6ec4a43f735e643a1f2f90351dc8.zip
chromium_src-b0b2a7f0fd7f6ec4a43f735e643a1f2f90351dc8.tar.gz
chromium_src-b0b2a7f0fd7f6ec4a43f735e643a1f2f90351dc8.tar.bz2
[Tracing Clock Sync] Add TracingAgent interface in Chrome
This CL adds TracingAgent interface in Chrome and hooks up corresponding subclasses. Design doc: https://goo.gl/8Vy6qX BUG=542390 Review URL: https://codereview.chromium.org/1468173003 Cr-Commit-Position: refs/heads/master@{#365284}
-rw-r--r--base/trace_event/BUILD.gn2
-rw-r--r--base/trace_event/trace_event.gypi2
-rw-r--r--base/trace_event/tracing_agent.cc24
-rw-r--r--base/trace_event/tracing_agent.h92
-rw-r--r--chromeos/dbus/debug_daemon_client.cc71
-rw-r--r--chromeos/dbus/debug_daemon_client.h23
-rw-r--r--chromeos/dbus/fake_debug_daemon_client.cc33
-rw-r--r--chromeos/dbus/fake_debug_daemon_client.h11
-rw-r--r--content/browser/tracing/etw_system_event_consumer_win.cc38
-rw-r--r--content/browser/tracing/etw_system_event_consumer_win.h23
-rw-r--r--content/browser/tracing/power_tracing_agent.cc65
-rw-r--r--content/browser/tracing/power_tracing_agent.h28
-rw-r--r--content/browser/tracing/tracing_controller_impl.cc236
-rw-r--r--content/browser/tracing/tracing_controller_impl.h36
-rw-r--r--content/browser/tracing/tracing_controller_impl_data_sinks.cc71
-rw-r--r--content/public/browser/tracing_controller.h16
-rwxr-xr-xtools/gn/bootstrap/bootstrap.py1
17 files changed, 501 insertions, 271 deletions
diff --git a/base/trace_event/BUILD.gn b/base/trace_event/BUILD.gn
index 91838b6..9a85be8 100644
--- a/base/trace_event/BUILD.gn
+++ b/base/trace_event/BUILD.gn
@@ -64,6 +64,8 @@ source_set("trace_event") {
"trace_log_constants.cc",
"trace_sampling_thread.cc",
"trace_sampling_thread.h",
+ "tracing_agent.cc",
+ "tracing_agent.h",
"winheap_dump_provider_win.cc",
"winheap_dump_provider_win.h",
]
diff --git a/base/trace_event/trace_event.gypi b/base/trace_event/trace_event.gypi
index 8656c6e..6948d7c 100644
--- a/base/trace_event/trace_event.gypi
+++ b/base/trace_event/trace_event.gypi
@@ -64,6 +64,8 @@
'trace_event/trace_log_constants.cc',
'trace_event/trace_sampling_thread.cc',
'trace_event/trace_sampling_thread.h',
+ 'trace_event/tracing_agent.cc',
+ 'trace_event/tracing_agent.h',
'trace_event/winheap_dump_provider_win.cc',
'trace_event/winheap_dump_provider_win.h',
],
diff --git a/base/trace_event/tracing_agent.cc b/base/trace_event/tracing_agent.cc
new file mode 100644
index 0000000..3c95a3d
--- /dev/null
+++ b/base/trace_event/tracing_agent.cc
@@ -0,0 +1,24 @@
+// Copyright 2015 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/tracing_agent.h"
+
+namespace base {
+namespace trace_event {
+
+TracingAgent::~TracingAgent() {}
+
+bool TracingAgent::SupportsExplicitClockSync() {
+ return false;
+}
+
+void TracingAgent::RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) {
+ DCHECK(SupportsExplicitClockSync());
+}
+
+
+} // namespace trace_event
+} // namespace base
diff --git a/base/trace_event/tracing_agent.h b/base/trace_event/tracing_agent.h
new file mode 100644
index 0000000..05f44a6
--- /dev/null
+++ b/base/trace_event/tracing_agent.h
@@ -0,0 +1,92 @@
+// Copyright 2015 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.
+
+#ifndef BASE_TRACE_EVENT_TRACING_AGENT_H_
+#define BASE_TRACE_EVENT_TRACING_AGENT_H_
+
+#include "base/base_export.h"
+#include "base/callback.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/values.h"
+
+namespace base {
+
+class TimeTicks;
+
+namespace trace_event {
+
+class TraceConfig;
+
+// A tracing agent is an entity that records its own sort of trace. Each
+// tracing method that produces its own trace log should implement this
+// interface. All tracing agents must only be controlled by TracingController.
+// Some existing examples include TracingControllerImpl for Chrome trace events,
+// DebugDaemonClient for CrOs system trace, EtwSystemEventConsumer for Windows
+// system trace and PowerTracingAgent for BattOr power trace.
+class BASE_EXPORT TracingAgent {
+ public:
+ using StopAgentTracingCallback = base::Callback<void(
+ const std::string& agent_name,
+ const std::string& events_label,
+ const scoped_refptr<base::RefCountedString>& events_str_ptr)>;
+ using RecordClockSyncMarkerCallback = base::Callback<void(
+ int sync_id,
+ const TimeTicks& sync_ts,
+ const TimeTicks& sync_end_ts)>;
+
+ virtual ~TracingAgent();
+
+ // Gets the name of the tracing agent. Each tracing agent's name should be
+ // unique.
+ virtual std::string GetTracingAgentName() = 0;
+
+ // Gets the trace event label of this tracing agent. The label will be used to
+ // label this agent's trace when all traces from different tracing agents are
+ // combined. Multiple tracing agents could have the same label. The tracing
+ // agents using the same label should not be able to run at the same time. For
+ // example, ETW on Windows and CrOS system tracing both use
+ // "systemTraceEvents" as the label. Those two agents never run at the same
+ // time because they are for different platforms.
+ virtual std::string GetTraceEventLabel() = 0;
+
+ // Starts tracing on the tracing agent with the trace configuration.
+ virtual bool StartAgentTracing(const TraceConfig& trace_config) = 0;
+
+ // Stops tracing on the tracing agent. The trace data will be passed back to
+ // the TracingController via the callback.
+ virtual void StopAgentTracing(const StopAgentTracingCallback& callback) = 0;
+
+ // Checks if the tracing agent supports explicit clock synchronization.
+ virtual bool SupportsExplicitClockSync();
+
+ // Records a clock sync marker issued by another tracing agent. This is only
+ // used if the tracing agent supports explicit clock synchronization.
+ //
+ // Two things need to be done:
+ // 1. The issuer asks the receiver to record the clock sync marker.
+ // 2. The issuer records how long the receiver takes to do the recording.
+ //
+ // In Chrome, the receiver thread also runs in Chrome and it will talk to the
+ // real receiver entity, e.g., power monitor or Android device system, via
+ // different communication methods, e.g., through USB or file reading/writing.
+ // The 2nd task measures that communication latency.
+ //
+ // Having a reliable timing measurement for the 2nd task requires synchronous
+ // function call without any cross-thread or cross-process activity. However,
+ // tracing agents in Chrome run in their own threads. Therefore, the issuer
+ // needs to dedicate the 2nd task to the receiver to take time measurements
+ // in the receiver thread, and the receiver thread needs to pass them back to
+ // the issuer in the callback.
+ //
+ // The assumption is that the receiver thread knows the issuer's clock, which
+ // is true in Chrome because all agent threads' clocks are Chrome clock.
+ virtual void RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback);
+};
+
+} // namespace trace_event
+} // namespace base
+
+#endif // BASE_TRACE_EVENT_TRACING_AGENT_H_
diff --git a/chromeos/dbus/debug_daemon_client.cc b/chromeos/dbus/debug_daemon_client.cc
index 125dcb3..b2f4acc 100644
--- a/chromeos/dbus/debug_daemon_client.cc
+++ b/chromeos/dbus/debug_daemon_client.cc
@@ -25,10 +25,14 @@
namespace {
-// Used in DebugDaemonClient::EmptySystemStopTracingCallback().
-void EmptyStopSystemTracingCallbackBody(
- const scoped_refptr<base::RefCountedString>& unused_result) {
-}
+const char kCrOSTracingAgentName[] = "cros";
+const char kCrOSTraceLabel[] = "systemTraceEvents";
+
+// Used in DebugDaemonClient::EmptyStopAgentTracingCallback().
+void EmptyStopAgentTracingCallbackBody(
+ const std::string& agent_name,
+ const std::string& events_label,
+ const scoped_refptr<base::RefCountedString>& unused_result) {}
} // namespace
@@ -194,7 +198,13 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
callback));
}
- void StartSystemTracing() override {
+ // base::trace_event::TracingAgent implementation.
+ std::string GetTracingAgentName() override { return kCrOSTracingAgentName; }
+
+ std::string GetTraceEventLabel() override { return kCrOSTraceLabel; }
+
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override {
dbus::MethodCall method_call(
debugd::kDebugdInterface,
debugd::kSystraceStart);
@@ -207,35 +217,37 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnStartMethod,
weak_ptr_factory_.GetWeakPtr()));
+ return true;
}
- bool RequestStopSystemTracing(
- scoped_refptr<base::TaskRunner> task_runner,
- const StopSystemTracingCallback& callback) override {
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override {
+ DCHECK(stop_agent_tracing_task_runner_);
if (pipe_reader_ != NULL) {
LOG(ERROR) << "Busy doing StopSystemTracing";
- return false;
+ return;
}
- pipe_reader_.reset(new PipeReaderForString(
- task_runner,
- base::Bind(&DebugDaemonClientImpl::OnIOComplete,
- weak_ptr_factory_.GetWeakPtr())));
+ pipe_reader_.reset(
+ new PipeReaderForString(stop_agent_tracing_task_runner_,
+ base::Bind(&DebugDaemonClientImpl::OnIOComplete,
+ weak_ptr_factory_.GetWeakPtr())));
base::File pipe_write_end = pipe_reader_->StartIO();
// Create dbus::FileDescriptor on the worker thread; on return we'll
// issue the D-Bus request to stop tracing and collect results.
base::PostTaskAndReplyWithResult(
- task_runner.get(),
- FROM_HERE,
+ stop_agent_tracing_task_runner_.get(), FROM_HERE,
base::Bind(
&DebugDaemonClientImpl::CreateFileDescriptorToStopSystemTracing,
base::Passed(&pipe_write_end)),
base::Bind(
&DebugDaemonClientImpl::OnCreateFileDescriptorRequestStopSystem,
- weak_ptr_factory_.GetWeakPtr(),
- callback));
- return true;
+ weak_ptr_factory_.GetWeakPtr(), callback));
+ }
+
+ void SetStopAgentTracingTaskRunner(
+ scoped_refptr<base::TaskRunner> task_runner) override {
+ stop_agent_tracing_task_runner_ = task_runner;
}
void TestICMP(const std::string& ip_address,
@@ -557,7 +569,7 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
// Called when a CheckValidity response is received.
void OnCreateFileDescriptorRequestStopSystem(
- const StopSystemTracingCallback& callback,
+ const StopAgentTracingCallback& callback,
scoped_ptr<dbus::FileDescriptor> file_descriptor) {
DCHECK(file_descriptor);
@@ -572,14 +584,13 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
DVLOG(1) << "Requesting a systrace stop";
debugdaemon_proxy_->CallMethod(
- &method_call,
- dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
- base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&DebugDaemonClientImpl::OnStopAgentTracing,
weak_ptr_factory_.GetWeakPtr()));
}
- // Called when a response for RequestStopSystemTracing() is received.
- void OnRequestStopSystemTracing(dbus::Response* response) {
+ // Called when a response for StopAgentTracing() is received.
+ void OnStopAgentTracing(dbus::Response* response) {
if (!response) {
LOG(ERROR) << "Failed to request systrace stop";
// If debugd crashes or completes I/O before this message is processed
@@ -602,13 +613,15 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
void OnIOComplete() {
std::string pipe_data;
pipe_reader_->GetData(&pipe_data);
- callback_.Run(base::RefCountedString::TakeString(&pipe_data));
+ callback_.Run(GetTracingAgentName(), GetTraceEventLabel(),
+ base::RefCountedString::TakeString(&pipe_data));
pipe_reader_.reset();
}
dbus::ObjectProxy* debugdaemon_proxy_;
scoped_ptr<PipeReaderForString> pipe_reader_;
- StopSystemTracingCallback callback_;
+ StopAgentTracingCallback callback_;
+ scoped_refptr<base::TaskRunner> stop_agent_tracing_task_runner_;
base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
@@ -621,9 +634,9 @@ DebugDaemonClient::~DebugDaemonClient() {
}
// static
-DebugDaemonClient::StopSystemTracingCallback
-DebugDaemonClient::EmptyStopSystemTracingCallback() {
- return base::Bind(&EmptyStopSystemTracingCallbackBody);
+DebugDaemonClient::StopAgentTracingCallback
+DebugDaemonClient::EmptyStopAgentTracingCallback() {
+ return base::Bind(&EmptyStopAgentTracingCallbackBody);
}
// static
diff --git a/chromeos/dbus/debug_daemon_client.h b/chromeos/dbus/debug_daemon_client.h
index 86427a2..a11d6ec 100644
--- a/chromeos/dbus/debug_daemon_client.h
+++ b/chromeos/dbus/debug_daemon_client.h
@@ -11,6 +11,7 @@
#include "base/files/file.h"
#include "base/memory/ref_counted_memory.h"
#include "base/task_runner.h"
+#include "base/trace_event/tracing_agent.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
@@ -18,7 +19,9 @@
namespace chromeos {
// DebugDaemonClient is used to communicate with the debug daemon.
-class CHROMEOS_EXPORT DebugDaemonClient : public DBusClient {
+class CHROMEOS_EXPORT DebugDaemonClient
+ : public DBusClient,
+ public base::trace_event::TracingAgent {
public:
~DebugDaemonClient() override;
@@ -113,21 +116,11 @@ class CHROMEOS_EXPORT DebugDaemonClient : public DBusClient {
// Gets list of user log files that must be read by Chrome.
virtual void GetUserLogFiles(const GetLogsCallback& callback) = 0;
- // Requests to start system/kernel tracing.
- virtual void StartSystemTracing() = 0;
+ virtual void SetStopAgentTracingTaskRunner(
+ scoped_refptr<base::TaskRunner> task_runner) = 0;
- // Called once RequestStopSystemTracing() is complete. Takes one parameter:
- // - result: the data collected while tracing was active
- typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&
- result)> StopSystemTracingCallback;
-
- // Requests to stop system tracing and calls |callback| when completed.
- virtual bool RequestStopSystemTracing(
- scoped_refptr<base::TaskRunner> task_runner,
- const StopSystemTracingCallback& callback) = 0;
-
- // Returns an empty SystemTracingCallback that does nothing.
- static StopSystemTracingCallback EmptyStopSystemTracingCallback();
+ // Returns an empty StopAgentTracingCallback that does nothing.
+ static StopAgentTracingCallback EmptyStopAgentTracingCallback();
// Called once TestICMP() is complete. Takes two parameters:
// - succeeded: information was obtained successfully.
diff --git a/chromeos/dbus/fake_debug_daemon_client.cc b/chromeos/dbus/fake_debug_daemon_client.cc
index 8dd391c..bdfa7aa 100644
--- a/chromeos/dbus/fake_debug_daemon_client.cc
+++ b/chromeos/dbus/fake_debug_daemon_client.cc
@@ -15,6 +15,13 @@
#include "base/thread_task_runner_handle.h"
#include "chromeos/chromeos_switches.h"
+namespace {
+
+const char kCrOSTracingAgentName[] = "cros";
+const char kCrOSTraceLabel[] = "systemTraceEvents";
+
+} // namespace
+
namespace chromeos {
FakeDebugDaemonClient::FakeDebugDaemonClient()
@@ -38,16 +45,30 @@ void FakeDebugDaemonClient::SetDebugMode(const std::string& subsystem,
const SetDebugModeCallback& callback) {
callback.Run(false);
}
-void FakeDebugDaemonClient::StartSystemTracing() {}
-bool FakeDebugDaemonClient::RequestStopSystemTracing(
- scoped_refptr<base::TaskRunner> task_runner,
- const StopSystemTracingCallback& callback) {
- std::string no_data;
- callback.Run(base::RefCountedString::TakeString(&no_data));
+std::string FakeDebugDaemonClient::GetTracingAgentName() {
+ return kCrOSTracingAgentName;
+}
+
+std::string FakeDebugDaemonClient::GetTraceEventLabel() {
+ return kCrOSTraceLabel;
+}
+
+bool FakeDebugDaemonClient::StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) {
return true;
}
+void FakeDebugDaemonClient::StopAgentTracing(
+ const StopAgentTracingCallback& callback) {
+ std::string no_data;
+ callback.Run(GetTracingAgentName(), GetTraceEventLabel(),
+ base::RefCountedString::TakeString(&no_data));
+}
+
+void FakeDebugDaemonClient::SetStopAgentTracingTaskRunner(
+ scoped_refptr<base::TaskRunner> task_runner) {}
+
void FakeDebugDaemonClient::GetRoutes(bool numeric,
bool ipv6,
const GetRoutesCallback& callback) {
diff --git a/chromeos/dbus/fake_debug_daemon_client.h b/chromeos/dbus/fake_debug_daemon_client.h
index 6f75e59..9c02fe2 100644
--- a/chromeos/dbus/fake_debug_daemon_client.h
+++ b/chromeos/dbus/fake_debug_daemon_client.h
@@ -27,10 +27,13 @@ class CHROMEOS_EXPORT FakeDebugDaemonClient : public DebugDaemonClient {
const GetDebugLogsCallback& callback) override;
void SetDebugMode(const std::string& subsystem,
const SetDebugModeCallback& callback) override;
- void StartSystemTracing() override;
- bool RequestStopSystemTracing(
- scoped_refptr<base::TaskRunner> task_runner,
- const StopSystemTracingCallback& callback) override;
+ std::string GetTracingAgentName() override;
+ std::string GetTraceEventLabel() override;
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override;
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override;
+ void SetStopAgentTracingTaskRunner(
+ scoped_refptr<base::TaskRunner> task_runner) override;
void GetRoutes(bool numeric,
bool ipv6,
const GetRoutesCallback& callback) override;
diff --git a/content/browser/tracing/etw_system_event_consumer_win.cc b/content/browser/tracing/etw_system_event_consumer_win.cc
index 529800f..d1a12cc 100644
--- a/content/browser/tracing/etw_system_event_consumer_win.cc
+++ b/content/browser/tracing/etw_system_event_consumer_win.cc
@@ -17,6 +17,9 @@ namespace content {
namespace {
+const char kETWTracingAgentName[] = "etw";
+const char kETWTraceLabel[] = "systemTraceEvents";
+
const int kEtwBufferSizeInKBytes = 16;
const int kEtwBufferFlushTimeoutInSeconds = 1;
@@ -36,8 +39,16 @@ EtwSystemEventConsumer::EtwSystemEventConsumer()
EtwSystemEventConsumer::~EtwSystemEventConsumer() {
}
-bool EtwSystemEventConsumer::StartSystemTracing() {
+std::string EtwSystemEventConsumer::GetTracingAgentName() {
+ return kETWTracingAgentName;
+}
+std::string EtwSystemEventConsumer::GetTraceEventLabel() {
+ return kETWTraceLabel;
+}
+
+bool EtwSystemEventConsumer::StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) {
// Activate kernel tracing.
if (!StartKernelSessionTracing())
return false;
@@ -52,31 +63,29 @@ bool EtwSystemEventConsumer::StartSystemTracing() {
return true;
}
-void EtwSystemEventConsumer::StopSystemTracing(const OutputCallback& callback) {
+void EtwSystemEventConsumer::StopAgentTracing(
+ const StopAgentTracingCallback& callback) {
// Deactivate kernel tracing.
if (!StopKernelSessionTracing()) {
LOG(FATAL) << "Could not stop system tracing.";
}
// Stop consuming and flush events.
- OutputCallback on_stop_system_tracing_done_callback =
- base::Bind(&EtwSystemEventConsumer::OnStopSystemTracingDone,
- base::Unretained(this),
- callback);
thread_.message_loop()->PostTask(FROM_HERE,
base::Bind(&EtwSystemEventConsumer::FlushOnThread,
- base::Unretained(this), on_stop_system_tracing_done_callback));
+ base::Unretained(this),
+ callback));
}
void EtwSystemEventConsumer::OnStopSystemTracingDone(
- const OutputCallback& callback,
+ const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result) {
// Stop the consumer thread.
thread_.Stop();
// Pass the serialized events.
- callback.Run(result);
+ callback.Run(GetTracingAgentName(), GetTraceEventLabel(), result);
}
bool EtwSystemEventConsumer::StartKernelSessionTracing() {
@@ -209,7 +218,8 @@ void EtwSystemEventConsumer::TraceAndConsumeOnThread() {
Close();
}
-void EtwSystemEventConsumer::FlushOnThread(const OutputCallback& callback) {
+void EtwSystemEventConsumer::FlushOnThread(
+ const StopAgentTracingCallback& callback) {
// Add the header information to the stream.
scoped_ptr<base::DictionaryValue> header(new base::DictionaryValue());
header->Set("name", new base::StringValue("ETW"));
@@ -225,8 +235,12 @@ void EtwSystemEventConsumer::FlushOnThread(const OutputCallback& callback) {
// Pass the result to the UI Thread.
scoped_refptr<base::RefCountedString> result =
base::RefCountedString::TakeString(&output);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(callback, result));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&EtwSystemEventConsumer::OnStopSystemTracingDone,
+ base::Unretained(this),
+ callback,
+ result));
}
} // namespace content
diff --git a/content/browser/tracing/etw_system_event_consumer_win.h b/content/browser/tracing/etw_system_event_consumer_win.h
index 25f4656..8ab7c8a 100644
--- a/content/browser/tracing/etw_system_event_consumer_win.h
+++ b/content/browser/tracing/etw_system_event_consumer_win.h
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/memory/ref_counted_memory.h"
#include "base/threading/thread.h"
+#include "base/trace_event/tracing_agent.h"
#include "base/values.h"
#include "base/win/event_trace_consumer.h"
#include "base/win/event_trace_controller.h"
@@ -19,14 +20,16 @@ struct DefaultSingletonTraits;
namespace content {
-class EtwSystemEventConsumer :
- public base::win::EtwTraceConsumerBase<EtwSystemEventConsumer> {
+class EtwSystemEventConsumer
+ : public base::win::EtwTraceConsumerBase<EtwSystemEventConsumer>,
+ public base::trace_event::TracingAgent {
public:
- typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
- OutputCallback;
-
- bool StartSystemTracing();
- void StopSystemTracing(const OutputCallback& callback);
+ // base::trace_event::TracingAgent implementation.
+ std::string GetTracingAgentName() override;
+ std::string GetTraceEventLabel() override;
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override;
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override;
// Retrieve the ETW consumer instance.
static EtwSystemEventConsumer* GetInstance();
@@ -38,7 +41,7 @@ class EtwSystemEventConsumer :
// Constructor.
EtwSystemEventConsumer();
- virtual ~EtwSystemEventConsumer();
+ ~EtwSystemEventConsumer() override;
void AddSyncEventToBuffer();
void AppendEventToBuffer(EVENT_TRACE* event);
@@ -58,11 +61,11 @@ class EtwSystemEventConsumer :
bool StopKernelSessionTracing();
void OnStopSystemTracingDone(
- const OutputCallback& callback,
+ const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result);
void TraceAndConsumeOnThread();
- void FlushOnThread(const OutputCallback& callback);
+ void FlushOnThread(const StopAgentTracingCallback& callback);
scoped_ptr<base::ListValue> events_;
base::Thread thread_;
diff --git a/content/browser/tracing/power_tracing_agent.cc b/content/browser/tracing/power_tracing_agent.cc
index 409240c..6be153a 100644
--- a/content/browser/tracing/power_tracing_agent.cc
+++ b/content/browser/tracing/power_tracing_agent.cc
@@ -11,13 +11,34 @@
namespace content {
+namespace {
+
+const char kPowerTracingAgentName[] = "battor";
+const char kPowerTraceLabel[] = "powerTraceAsString";
+
+} // namespace
+
+// static
+PowerTracingAgent* PowerTracingAgent::GetInstance() {
+ return base::Singleton<PowerTracingAgent>::get();
+}
+
PowerTracingAgent::PowerTracingAgent() : is_tracing_(false) {
battor_trace_provider_.reset(new BattorPowerTraceProvider());
}
PowerTracingAgent::~PowerTracingAgent() {}
-bool PowerTracingAgent::StartTracing() {
+std::string PowerTracingAgent::GetTracingAgentName() {
+ return kPowerTracingAgentName;
+}
+
+std::string PowerTracingAgent::GetTraceEventLabel() {
+ return kPowerTraceLabel;
+}
+
+bool PowerTracingAgent::StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) {
// Tracing session already in progress.
if (is_tracing_)
return false;
@@ -29,34 +50,30 @@ bool PowerTracingAgent::StartTracing() {
return is_tracing_;
}
-void PowerTracingAgent::StopTracing(const OutputCallback& callback) {
+void PowerTracingAgent::StopAgentTracing(
+ const StopAgentTracingCallback& callback) {
// No tracing session in progress.
if (!is_tracing_)
return;
// Stop tracing & collect logs.
- OutputCallback on_stop_power_tracing_done_callback = base::Bind(
- &PowerTracingAgent::OnStopTracingDone, base::Unretained(this), callback);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&PowerTracingAgent::FlushOnThread, base::Unretained(this),
- on_stop_power_tracing_done_callback));
+ base::Bind(&PowerTracingAgent::FlushOnThread,
+ base::Unretained(this),
+ callback));
}
void PowerTracingAgent::OnStopTracingDone(
- const OutputCallback& callback,
+ const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result) {
is_tracing_ = false;
// Pass the serialized events.
- callback.Run(result);
+ callback.Run(GetTracingAgentName(), GetTraceEventLabel(), result);
}
-// static
-PowerTracingAgent* PowerTracingAgent::GetInstance() {
- return base::Singleton<PowerTracingAgent>::get();
-}
-
-void PowerTracingAgent::FlushOnThread(const OutputCallback& callback) {
+void PowerTracingAgent::FlushOnThread(
+ const StopAgentTracingCallback& callback) {
// Pass the result to the UI Thread.
// TODO(prabhur) StopTracing & GetLog need to be called on a
@@ -66,8 +83,24 @@ void PowerTracingAgent::FlushOnThread(const OutputCallback& callback) {
battor_trace_provider_->GetLog(&battor_logs);
scoped_refptr<base::RefCountedString> result =
base::RefCountedString::TakeString(&battor_logs);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(callback, result));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PowerTracingAgent::OnStopTracingDone,
+ base::Unretained(this),
+ callback,
+ result));
+}
+
+bool PowerTracingAgent::SupportsExplicitClockSync() {
+ // TODO(zhenw): return true after implementing explicit clock sync.
+ return false;
+}
+
+void PowerTracingAgent::RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) {
+ DCHECK(SupportsExplicitClockSync());
+ // TODO(zhenw): implement explicit clock sync.
}
} // namespace content
diff --git a/content/browser/tracing/power_tracing_agent.h b/content/browser/tracing/power_tracing_agent.h
index 3c897d6..d72b1cb 100644
--- a/content/browser/tracing/power_tracing_agent.h
+++ b/content/browser/tracing/power_tracing_agent.h
@@ -7,6 +7,7 @@
#include "base/memory/ref_counted_memory.h"
#include "base/threading/thread.h"
+#include "base/trace_event/tracing_agent.h"
namespace base {
template <typename Type>
@@ -17,17 +18,24 @@ namespace content {
class BattorPowerTraceProvider;
-class PowerTracingAgent {
+class PowerTracingAgent : public base::trace_event::TracingAgent {
public:
- typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
- OutputCallback;
-
- bool StartTracing();
- void StopTracing(const OutputCallback& callback);
-
// Retrieve the singleton instance.
static PowerTracingAgent* GetInstance();
+ // base::trace_event::TracingAgent implementation.
+ std::string GetTracingAgentName() override;
+ std::string GetTraceEventLabel() override;
+
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override;
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override;
+
+ bool SupportsExplicitClockSync() override;
+ void RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) override;
+
private:
// This allows constructor and destructor to be private and usable only
// by the Singleton class.
@@ -35,12 +43,12 @@ class PowerTracingAgent {
// Constructor.
PowerTracingAgent();
- virtual ~PowerTracingAgent();
+ ~PowerTracingAgent() override;
- void OnStopTracingDone(const OutputCallback& callback,
+ void OnStopTracingDone(const StopAgentTracingCallback& callback,
const scoped_refptr<base::RefCountedString>& result);
- void FlushOnThread(const OutputCallback& callback);
+ void FlushOnThread(const StopAgentTracingCallback& callback);
scoped_ptr<BattorPowerTraceProvider> battor_trace_provider_;
bool is_tracing_;
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index bc2eb6e..33c2361 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -45,6 +45,9 @@ namespace {
base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
LAZY_INSTANCE_INITIALIZER;
+const char kChromeTracingAgentName[] = "chrome";
+const char kETWTracingAgentName[] = "etw";
+const char kChromeTraceLabel[] = "traceEvents";
std::string GetNetworkTypeString() {
switch (net::NetworkChangeNotifier::GetConnectionType()) {
@@ -145,14 +148,8 @@ TracingControllerImpl::TracingControllerImpl()
approximate_event_count_(0),
pending_memory_dump_ack_count_(0),
failed_memory_dump_count_(0),
- // Tracing may have been enabled by ContentMainRunner if kTraceStartup
- // is specified in command line.
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- is_system_tracing_(false),
-#endif
is_tracing_(false),
- is_monitoring_(false),
- is_power_tracing_(false) {
+ is_monitoring_(false) {
base::trace_event::MemoryDumpManager::GetInstance()->Initialize(
this /* delegate */, true /* is_coordinator */);
@@ -210,10 +207,12 @@ bool TracingControllerImpl::StartTracing(
const TraceConfig& trace_config,
const StartTracingDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(additional_tracing_agents_.empty());
if (!can_start_tracing())
return false;
is_tracing_ = true;
+ start_tracing_done_callback_ = callback;
#if defined(OS_ANDROID)
if (pending_get_categories_done_callback_.is_null())
@@ -221,46 +220,33 @@ bool TracingControllerImpl::StartTracing(
#endif
if (trace_config.IsSystraceEnabled()) {
- DCHECK(!is_power_tracing_);
- is_power_tracing_ = PowerTracingAgent::GetInstance()->StartTracing();
+ if (PowerTracingAgent::GetInstance()->StartAgentTracing(trace_config))
+ additional_tracing_agents_.push_back(PowerTracingAgent::GetInstance());
#if defined(OS_CHROMEOS)
- DCHECK(!is_system_tracing_);
- chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
- StartSystemTracing();
- is_system_tracing_ = true;
+ chromeos::DebugDaemonClient* debug_daemon =
+ chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
+ if (debug_daemon && debug_daemon->StartAgentTracing(trace_config)) {
+ debug_daemon->SetStopAgentTracingTaskRunner(
+ BrowserThread::GetBlockingPool());
+ additional_tracing_agents_.push_back(
+ chromeos::DBusThreadManager::Get()->GetDebugDaemonClient());
+ }
#elif defined(OS_WIN)
- DCHECK(!is_system_tracing_);
- is_system_tracing_ =
- EtwSystemEventConsumer::GetInstance()->StartSystemTracing();
+ if (EtwSystemEventConsumer::GetInstance()->StartAgentTracing(
+ trace_config)) {
+ additional_tracing_agents_.push_back(
+ EtwSystemEventConsumer::GetInstance());
+ }
#endif
}
// TraceLog may have been enabled in startup tracing before threads are ready.
if (TraceLog::GetInstance()->IsEnabled())
return true;
-
- base::Closure on_start_tracing_done_callback =
- base::Bind(&TracingControllerImpl::OnStartTracingDone,
- base::Unretained(this),
- trace_config, callback);
- if (!BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
- base::Unretained(this), trace_config,
- base::trace_event::TraceLog::RECORDING_MODE,
- on_start_tracing_done_callback))) {
- // BrowserThread::PostTask fails if the threads haven't been created yet,
- // so it should be safe to just use TraceLog::SetEnabled directly.
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- trace_config, base::trace_event::TraceLog::RECORDING_MODE);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- on_start_tracing_done_callback);
- }
-
- return true;
+ return StartAgentTracing(trace_config);
}
-void TracingControllerImpl::OnStartTracingDone(
+void TracingControllerImpl::OnStartAgentTracingDone(
const TraceConfig& trace_config,
const StartTracingDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -325,63 +311,15 @@ void TracingControllerImpl::OnStopTracingDone() {
pending_stop_tracing_ack_count_ = trace_message_filters_.size() + 1;
pending_stop_tracing_filters_ = trace_message_filters_;
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- if (is_system_tracing_) {
- // Disable system tracing.
- is_system_tracing_ = false;
- ++pending_stop_tracing_ack_count_;
-
-#if defined(OS_CHROMEOS)
- scoped_refptr<base::TaskRunner> task_runner =
- BrowserThread::GetBlockingPool();
- chromeos::DBusThreadManager::Get()
- ->GetDebugDaemonClient()
- ->RequestStopSystemTracing(
- task_runner,
- base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
- base::Unretained(this)));
-#elif defined(OS_WIN)
- EtwSystemEventConsumer::GetInstance()->StopSystemTracing(
- base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
+ pending_stop_tracing_ack_count_ += additional_tracing_agents_.size();
+ for (auto it : additional_tracing_agents_) {
+ it->StopAgentTracing(
+ base::Bind(&TracingControllerImpl::OnEndAgentTracingAcked,
base::Unretained(this)));
-#endif
- }
-#endif // defined(OS_CHROMEOS) || defined(OS_WIN)
-
- if (is_power_tracing_) {
- is_power_tracing_ = false;
- ++pending_stop_tracing_ack_count_;
- PowerTracingAgent::GetInstance()->StopTracing(
- base::Bind(&TracingControllerImpl::OnEndPowerTracingAcked,
- base::Unretained(this)));
- }
-
- // Handle special case of zero child processes by immediately flushing the
- // trace log. Once the flush has completed the caller will be notified that
- // tracing has ended.
- if (pending_stop_tracing_ack_count_ == 1) {
- // Flush/cancel asynchronously now, because we don't have any children to
- // wait for.
- if (trace_data_sink_) {
- TraceLog::GetInstance()->Flush(
- base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
- base::Unretained(this)),
- true);
- } else {
- TraceLog::GetInstance()->CancelTracing(
- base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
- base::Unretained(this)));
- }
}
+ additional_tracing_agents_.clear();
- // Notify all child processes.
- for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
- it != trace_message_filters_.end(); ++it) {
- if (trace_data_sink_)
- it->get()->SendEndTracing();
- else
- it->get()->SendCancelTracing();
- }
+ StopAgentTracing(StopAgentTracingCallback());
}
bool TracingControllerImpl::StartMonitoring(
@@ -738,39 +676,26 @@ void TracingControllerImpl::OnStopTracingAcked(
}
}
-void TracingControllerImpl::OnEndPowerTracingAcked(
- const scoped_refptr<base::RefCountedString>& events_str_ptr) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- if (trace_data_sink_.get()) {
- std::string json_string = base::GetQuotedJSONString(events_str_ptr->data());
- trace_data_sink_->SetPowerTrace(json_string);
- }
- std::vector<std::string> category_groups;
- OnStopTracingAcked(NULL, category_groups);
-}
-
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
-void TracingControllerImpl::OnEndSystemTracingAcked(
+void TracingControllerImpl::OnEndAgentTracingAcked(
+ const std::string& agent_name,
+ const std::string& events_label,
const scoped_refptr<base::RefCountedString>& events_str_ptr) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (trace_data_sink_.get()) {
-#if defined(OS_WIN)
- // The Windows kernel events are kept into a JSon format stored as string
- // and must not be escaped.
- std::string json_string = events_str_ptr->data();
-#else
- std::string json_string =
- base::GetQuotedJSONString(events_str_ptr->data());
-#endif
- trace_data_sink_->SetSystemTrace(json_string);
+ std::string json_string;
+ if (agent_name == kETWTracingAgentName) {
+ // The Windows kernel events are kept into a JSON format stored as string
+ // and must not be escaped.
+ json_string = events_str_ptr->data();
+ } else {
+ json_string = base::GetQuotedJSONString(events_str_ptr->data());
+ }
+ trace_data_sink_->AddAgentTrace(events_label, json_string);
}
- DCHECK(!is_system_tracing_);
std::vector<std::string> category_groups;
OnStopTracingAcked(NULL, category_groups);
}
-#endif
void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked(
TraceMessageFilter* trace_message_filter) {
@@ -924,6 +849,85 @@ void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
tracing_uis_.erase(it);
}
+std::string TracingControllerImpl::GetTracingAgentName() {
+ return kChromeTracingAgentName;
+}
+
+std::string TracingControllerImpl::GetTraceEventLabel() {
+ return kChromeTraceLabel;
+}
+
+bool TracingControllerImpl::StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ base::Closure on_start_tracing_done_callback =
+ base::Bind(&TracingControllerImpl::OnStartAgentTracingDone,
+ base::Unretained(this),
+ trace_config, start_tracing_done_callback_);
+ if (!BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
+ base::Unretained(this), trace_config,
+ base::trace_event::TraceLog::RECORDING_MODE,
+ on_start_tracing_done_callback))) {
+ // BrowserThread::PostTask fails if the threads haven't been created yet,
+ // so it should be safe to just use TraceLog::SetEnabled directly.
+ base::trace_event::TraceLog::GetInstance()->SetEnabled(
+ trace_config, base::trace_event::TraceLog::RECORDING_MODE);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ on_start_tracing_done_callback);
+ }
+
+ return true;
+}
+
+void TracingControllerImpl::StopAgentTracing(
+ const StopAgentTracingCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Handle special case of zero child processes by immediately flushing the
+ // trace log. Once the flush has completed the caller will be notified that
+ // tracing has ended.
+ if (pending_stop_tracing_ack_count_ == 1) {
+ // Flush/cancel asynchronously now, because we don't have any children to
+ // wait for.
+ if (trace_data_sink_) {
+ TraceLog::GetInstance()->Flush(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)),
+ true);
+ } else {
+ TraceLog::GetInstance()->CancelTracing(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)));
+ }
+ }
+
+ // Notify all child processes.
+ for (auto it : trace_message_filters_) {
+ if (trace_data_sink_)
+ it->SendEndTracing();
+ else
+ it->SendCancelTracing();
+ }
+}
+
+bool TracingControllerImpl::SupportsExplicitClockSync() {
+ // TODO(zhenw): return true after implementing explicit clock sync.
+ return false;
+}
+
+void TracingControllerImpl::RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) {
+ DCHECK(SupportsExplicitClockSync());
+ // TODO(zhenw): implement explicit clock sync.
+}
+
+void TracingControllerImpl::IssueClockSyncMarker() {
+ // TODO(zhenw): implement explicit clock sync.
+}
+
void TracingControllerImpl::RequestGlobalMemoryDump(
const base::trace_event::MemoryDumpRequestArgs& args,
const base::trace_event::MemoryDumpCallback& callback) {
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h
index 0d2e4d8..5d1479a 100644
--- a/content/browser/tracing/tracing_controller_impl.h
+++ b/content/browser/tracing/tracing_controller_impl.h
@@ -11,6 +11,7 @@
#include "base/lazy_instance.h"
#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/tracing_agent.h"
#include "content/public/browser/tracing_controller.h"
namespace base {
@@ -25,7 +26,8 @@ class TracingUI;
class TracingControllerImpl
: public TracingController,
- public base::trace_event::MemoryDumpManagerDelegate {
+ public base::trace_event::MemoryDumpManagerDelegate,
+ public base::trace_event::TracingAgent {
public:
static TracingControllerImpl* GetInstance();
@@ -55,6 +57,17 @@ class TracingControllerImpl
void RegisterTracingUI(TracingUI* tracing_ui);
void UnregisterTracingUI(TracingUI* tracing_ui);
+ // base::trace_event::TracingAgent implementation.
+ std::string GetTracingAgentName() override;
+ std::string GetTraceEventLabel() override;
+ bool StartAgentTracing(
+ const base::trace_event::TraceConfig& trace_config) override;
+ void StopAgentTracing(const StopAgentTracingCallback& callback) override;
+ bool SupportsExplicitClockSync() override;
+ void RecordClockSyncMarker(
+ int sync_id,
+ const RecordClockSyncMarkerCallback& callback) override;
+
// base::trace_event::MemoryDumpManagerDelegate implementation.
void RequestGlobalMemoryDump(
const base::trace_event::MemoryDumpRequestArgs& args,
@@ -122,12 +135,9 @@ class TracingControllerImpl
TraceMessageFilter* trace_message_filter,
const std::vector<std::string>& known_category_groups);
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- void OnEndSystemTracingAcked(
- const scoped_refptr<base::RefCountedString>& events_str_ptr);
-#endif
-
- void OnEndPowerTracingAcked(
+ void OnEndAgentTracingAcked(
+ const std::string& agent_name,
+ const std::string& events_label,
const scoped_refptr<base::RefCountedString>& events_str_ptr);
void OnCaptureMonitoringSnapshotAcked(
@@ -151,7 +161,7 @@ class TracingControllerImpl
int mode,
const base::Closure& callback);
void SetDisabledOnFileThread(const base::Closure& callback);
- void OnStartTracingDone(
+ void OnStartAgentTracingDone(
const base::trace_event::TraceConfig& trace_config,
const StartTracingDoneCallback& callback);
void OnStopTracingDone();
@@ -162,6 +172,9 @@ class TracingControllerImpl
void OnMonitoringStateChanged(bool is_monitoring);
+ // Issue clock sync markers to the tracing agents.
+ void IssueClockSyncMarker();
+
typedef std::set<scoped_refptr<TraceMessageFilter>> TraceMessageFilterSet;
TraceMessageFilterSet trace_message_filters_;
@@ -186,12 +199,11 @@ class TracingControllerImpl
uint64 pending_memory_dump_guid_;
base::trace_event::MemoryDumpCallback pending_memory_dump_callback_;
-#if defined(OS_CHROMEOS) || defined(OS_WIN)
- bool is_system_tracing_;
-#endif
+ StartTracingDoneCallback start_tracing_done_callback_;
+ std::vector<base::trace_event::TracingAgent*> additional_tracing_agents_;
+
bool is_tracing_;
bool is_monitoring_;
- bool is_power_tracing_;
GetCategoriesDoneCallback pending_get_categories_done_callback_;
GetTraceBufferUsageCallback pending_trace_buffer_usage_callback_;
diff --git a/content/browser/tracing/tracing_controller_impl_data_sinks.cc b/content/browser/tracing/tracing_controller_impl_data_sinks.cc
index 1f71774..e5215ce6 100644
--- a/content/browser/tracing/tracing_controller_impl_data_sinks.cc
+++ b/content/browser/tracing/tracing_controller_impl_data_sinks.cc
@@ -14,6 +14,9 @@ namespace content {
namespace {
+const char kChromeTraceLabel[] = "traceEvents";
+const char kMetadataTraceLabel[] = "metadata";
+
class StringTraceDataEndpoint : public TracingController::TraceDataEndpoint {
public:
typedef base::Callback<void(scoped_ptr<const base::DictionaryValue>,
@@ -118,7 +121,7 @@ class StringTraceDataSink : public TracingController::TraceDataSink {
void AddTraceChunk(const std::string& chunk) override {
std::string trace_string;
if (trace_.empty())
- trace_string = "{\"traceEvents\":[";
+ trace_string = "{\"" + std::string(kChromeTraceLabel) + "\":[";
else
trace_string = ",";
trace_string += chunk;
@@ -132,24 +135,17 @@ class StringTraceDataSink : public TracingController::TraceDataSink {
endpoint_->ReceiveTraceChunk(chunk);
}
- void SetSystemTrace(const std::string& data) override {
- system_trace_ = data;
- }
-
- void SetPowerTrace(const std::string& data) override { power_trace_ = data; }
-
void Close() override {
AddTraceChunkAndPassToEndpoint("]");
- if (!system_trace_.empty())
- AddTraceChunkAndPassToEndpoint(",\"systemTraceEvents\": " +
- system_trace_);
+
+ for (auto const &it : GetAgentTrace())
+ AddTraceChunkAndPassToEndpoint(",\"" + it.first + "\": " + it.second);
+
std::string metadataJSON;
if (base::JSONWriter::Write(*GetMetadataCopy(), &metadataJSON) &&
- !metadataJSON.empty())
- AddTraceChunkAndPassToEndpoint(",\"metadata\": " + metadataJSON);
- if (!power_trace_.empty()) {
- AddTraceChunkAndPassToEndpoint(",\"powerTraceAsString\": " +
- power_trace_);
+ !metadataJSON.empty()) {
+ AddTraceChunkAndPassToEndpoint(
+ ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON);
}
AddTraceChunkAndPassToEndpoint("}");
@@ -162,8 +158,6 @@ class StringTraceDataSink : public TracingController::TraceDataSink {
scoped_refptr<TracingController::TraceDataEndpoint> endpoint_;
std::string trace_;
- std::string system_trace_;
- std::string power_trace_;
DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink);
};
@@ -184,12 +178,6 @@ class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
this, chunk_ptr));
}
- void SetSystemTrace(const std::string& data) override {
- system_trace_ = data;
- }
-
- void SetPowerTrace(const std::string& data) override { power_trace_ = data; }
-
void Close() override {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
@@ -227,7 +215,7 @@ class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
std::string trace;
if (compressed_trace_data_.empty())
- trace = "{\"traceEvents\":[";
+ trace = "{\"" + std::string(kChromeTraceLabel) + "\":[";
else
trace = ",";
trace += chunk_ptr->data();
@@ -269,23 +257,23 @@ class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
if (!OpenZStreamOnFileThread())
return;
- if (compressed_trace_data_.empty())
- AddTraceChunkAndCompressOnFileThread("{\"traceEvents\":[", false);
-
+ if (compressed_trace_data_.empty()) {
+ AddTraceChunkAndCompressOnFileThread(
+ "{\"" + std::string(kChromeTraceLabel) + "\":[", false);
+ }
AddTraceChunkAndCompressOnFileThread("]", false);
- if (!system_trace_.empty()) {
+
+ for (auto const &it : GetAgentTrace()) {
AddTraceChunkAndCompressOnFileThread(
- ",\"systemTraceEvents\": " + system_trace_, false);
+ ",\"" + it.first + "\": " + it.second, false);
}
+
std::string metadataJSON;
if (base::JSONWriter::Write(*GetMetadataCopy(), &metadataJSON) &&
!metadataJSON.empty()) {
- AddTraceChunkAndCompressOnFileThread(",\"metadata\": " + metadataJSON,
- false);
- }
- if (!power_trace_.empty()) {
AddTraceChunkAndCompressOnFileThread(
- ",\"powerTraceAsString\": " + power_trace_, false);
+ ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON,
+ false);
}
AddTraceChunkAndCompressOnFileThread("}", true);
@@ -300,8 +288,6 @@ class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
scoped_ptr<z_stream> stream_;
bool already_tried_open_;
std::string compressed_trace_data_;
- std::string system_trace_;
- std::string power_trace_;
DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink);
};
@@ -312,6 +298,19 @@ TracingController::TraceDataSink::TraceDataSink() {}
TracingController::TraceDataSink::~TraceDataSink() {}
+void TracingController::TraceDataSink::AddAgentTrace(
+ const std::string& trace_label,
+ const std::string& trace_data) {
+ DCHECK(additional_tracing_agent_trace_.find(trace_label) ==
+ additional_tracing_agent_trace_.end());
+ additional_tracing_agent_trace_[trace_label] = trace_data;
+}
+
+const std::map<std::string, std::string>&
+ TracingController::TraceDataSink::GetAgentTrace() const {
+ return additional_tracing_agent_trace_;
+}
+
void TracingController::TraceDataSink::AddMetadata(
const base::DictionaryValue& data) {
metadata_.MergeDictionary(&data);
diff --git a/content/public/browser/tracing_controller.h b/content/public/browser/tracing_controller.h
index 5525355..bfd3c42 100644
--- a/content/public/browser/tracing_controller.h
+++ b/content/public/browser/tracing_controller.h
@@ -41,7 +41,10 @@ class TracingController {
TraceDataSink();
virtual void AddTraceChunk(const std::string& chunk) {}
- virtual void SetSystemTrace(const std::string& data) {}
+
+ // Add a TracingAgent's trace to the data sink.
+ virtual void AddAgentTrace(const std::string& trace_label,
+ const std::string& trace_data);
// Notice that TracingController adds some default metadata when
// StopTracing is called, which may override metadata that you would
@@ -50,17 +53,20 @@ class TracingController {
virtual scoped_ptr<const base::DictionaryValue> GetMetadataCopy() const;
virtual void SetMetadataFilterPredicate(
const MetadataFilterPredicate& metadata_filter_predicate);
- // TODO(prabhur) Replace all the Set* functions with a generic function:
- // TraceDataSink::AppendAdditionalData(const std::string& name,
- // const std::string& trace_data)
- virtual void SetPowerTrace(const std::string& data) {}
virtual void Close() {}
protected:
friend class base::RefCountedThreadSafe<TraceDataSink>;
+
+ // Get a map of TracingAgent's data, which is previously added by
+ // AddAgentTrace(). The map's key is the trace label and the map's value is
+ // the trace data.
+ virtual const std::map<std::string, std::string>& GetAgentTrace() const;
+
virtual ~TraceDataSink();
private:
+ std::map<std::string, std::string> additional_tracing_agent_trace_;
MetadataFilterPredicate metadata_filter_predicate_;
base::DictionaryValue metadata_;
};
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py
index 5296ff3..6a6d12d 100755
--- a/tools/gn/bootstrap/bootstrap.py
+++ b/tools/gn/bootstrap/bootstrap.py
@@ -267,6 +267,7 @@ def write_ninja(path, options):
'base/trace_event/trace_log.cc',
'base/trace_event/trace_log_constants.cc',
'base/trace_event/trace_sampling_thread.cc',
+ 'base/trace_event/tracing_agent.cc',
'base/tracked_objects.cc',
'base/tracking_info.cc',
'base/values.cc',