diff options
author | zhenw <zhenw@chromium.org> | 2015-12-15 10:07:27 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-15 18:09:10 +0000 |
commit | b0b2a7f0fd7f6ec4a43f735e643a1f2f90351dc8 (patch) | |
tree | 83231e1910f5fbec30b9306a98f13083e5cae6c2 | |
parent | a3b91bd3cff4e98ec20bfbf79d37438c6f561e45 (diff) | |
download | chromium_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.gn | 2 | ||||
-rw-r--r-- | base/trace_event/trace_event.gypi | 2 | ||||
-rw-r--r-- | base/trace_event/tracing_agent.cc | 24 | ||||
-rw-r--r-- | base/trace_event/tracing_agent.h | 92 | ||||
-rw-r--r-- | chromeos/dbus/debug_daemon_client.cc | 71 | ||||
-rw-r--r-- | chromeos/dbus/debug_daemon_client.h | 23 | ||||
-rw-r--r-- | chromeos/dbus/fake_debug_daemon_client.cc | 33 | ||||
-rw-r--r-- | chromeos/dbus/fake_debug_daemon_client.h | 11 | ||||
-rw-r--r-- | content/browser/tracing/etw_system_event_consumer_win.cc | 38 | ||||
-rw-r--r-- | content/browser/tracing/etw_system_event_consumer_win.h | 23 | ||||
-rw-r--r-- | content/browser/tracing/power_tracing_agent.cc | 65 | ||||
-rw-r--r-- | content/browser/tracing/power_tracing_agent.h | 28 | ||||
-rw-r--r-- | content/browser/tracing/tracing_controller_impl.cc | 236 | ||||
-rw-r--r-- | content/browser/tracing/tracing_controller_impl.h | 36 | ||||
-rw-r--r-- | content/browser/tracing/tracing_controller_impl_data_sinks.cc | 71 | ||||
-rw-r--r-- | content/public/browser/tracing_controller.h | 16 | ||||
-rwxr-xr-x | tools/gn/bootstrap/bootstrap.py | 1 |
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', |