tracing: support system backend in tracing scenarios
This change allows tracing scenarios to collect system-wide traces using the system tracing backend (traced). To enable this feature: This revision adds the support of system-wide background tracing in tracing scenarios. A tracing scenario switches to the system tracing backend (traced) when the following conditions are all met: 1. EnablePerfettoSystemTracing is enabled: Chrome sends trace data to the system backend. 2. EnablePerfettoSystemBackgroundTracing is enabled: this feature flag controls whether the scenarios are allowed to use the system backend. 3 use_system_backend is set to true in the scenario config. The scenario needs to explicitly specify that it will use the system backend. In cases of mismatched configuration between feature flags and scenario config: * If the scenario requests the system backend but the feature flags are disabled, the scenario will be ignored (considered a server config error). * If the feature flags are enabled but the scenario doesn't request the system backend, the default custom backend will be used. Bug: b:388424720 Test: unit tests TracingScenarioSystemBackendTest.* Change-Id: I33cb2f45e59194e4348a09573e2db3f44df43d60 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5581575 Reviewed-by: Eric Seckler <eseckler@chromium.org> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org> Commit-Queue: Chinglin Yu <chinglinyu@chromium.org> Cr-Commit-Position: refs/heads/main@{#1413380}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
0187c35235
commit
6e02296d22
content
services/tracing
@ -39,12 +39,12 @@ perfetto::TraceConfig GetDefaultTraceConfig(
|
||||
MockProducer::MockProducer() = default;
|
||||
MockProducer::~MockProducer() = default;
|
||||
|
||||
void MockProducer::Connect(PerfettoService* service,
|
||||
void MockProducer::Connect(perfetto::TracingService* service,
|
||||
const std::string& producer_name,
|
||||
uid_t uid,
|
||||
pid_t pid) {
|
||||
producer_name_ = producer_name;
|
||||
service_endpoint_ = service->GetService()->ConnectProducer(
|
||||
service_endpoint_ = service->ConnectProducer(
|
||||
this, perfetto::ClientIdentity(uid, pid), producer_name, 0,
|
||||
/*in_process=*/true,
|
||||
perfetto::TracingService::ProducerSMBScrapingMode::kDefault, 0, nullptr);
|
||||
|
@ -38,7 +38,11 @@ class MockProducer : public perfetto::Producer {
|
||||
MockProducer();
|
||||
~MockProducer() override;
|
||||
|
||||
void Connect(PerfettoService* service,
|
||||
inline void Connect(PerfettoService* service,
|
||||
const std::string& producer_name) {
|
||||
Connect(service->GetService(), producer_name);
|
||||
}
|
||||
void Connect(perfetto::TracingService* service,
|
||||
const std::string& producer_name,
|
||||
uid_t uid = 42,
|
||||
pid_t pid = 1025);
|
||||
|
@ -264,17 +264,26 @@ void AdaptDataSourceConfig(
|
||||
perfetto::DataSourceConfig* config,
|
||||
const std::string& chrome_config_string,
|
||||
bool privacy_filtering_enabled,
|
||||
perfetto::protos::gen::ChromeConfig::ClientPriority client_priority) {
|
||||
perfetto::protos::gen::ChromeConfig::ClientPriority client_priority,
|
||||
bool enable_system_backend = false) {
|
||||
if (!config->has_target_buffer()) {
|
||||
config->set_target_buffer(0);
|
||||
}
|
||||
auto* chrome_config = config->mutable_chrome_config();
|
||||
chrome_config->set_privacy_filtering_enabled(privacy_filtering_enabled);
|
||||
// There are no use case for legacy json, since this is used to adapt
|
||||
// background tracing configs.
|
||||
chrome_config->set_convert_to_legacy_json(false);
|
||||
chrome_config->set_client_priority(client_priority);
|
||||
chrome_config->set_trace_config(chrome_config_string);
|
||||
|
||||
// Adapt data source config if
|
||||
// 1. the scenario uses the default custom backend, or
|
||||
// 2. the scenario uses the system backend. Only Chrome data source should be
|
||||
// adapted. Other data source names are ignored.
|
||||
if (!enable_system_backend || (config->name() == "track_event" ||
|
||||
config->name().starts_with("org.chromium."))) {
|
||||
auto* chrome_config = config->mutable_chrome_config();
|
||||
chrome_config->set_privacy_filtering_enabled(privacy_filtering_enabled);
|
||||
// There are no use case for legacy json, since this is used to adapt
|
||||
// background tracing configs.
|
||||
chrome_config->set_convert_to_legacy_json(false);
|
||||
chrome_config->set_client_priority(client_priority);
|
||||
chrome_config->set_trace_config(chrome_config_string);
|
||||
}
|
||||
|
||||
if (!config->track_event_config_raw().empty()) {
|
||||
config->set_name("track_event");
|
||||
@ -347,7 +356,8 @@ bool AdaptPerfettoConfigForChrome(
|
||||
perfetto::TraceConfig* perfetto_config,
|
||||
bool privacy_filtering_enabled,
|
||||
bool enable_package_name_filter,
|
||||
perfetto::protos::gen::ChromeConfig::ClientPriority client_priority) {
|
||||
perfetto::protos::gen::ChromeConfig::ClientPriority client_priority,
|
||||
bool enable_system_backend) {
|
||||
if (perfetto_config->buffers_size() < 1) {
|
||||
auto* buffer_config = perfetto_config->add_buffers();
|
||||
buffer_config->set_size_kb(GetDefaultTraceBufferSize());
|
||||
|
@ -38,7 +38,8 @@ bool COMPONENT_EXPORT(TRACING_CPP) AdaptPerfettoConfigForChrome(
|
||||
bool privacy_filtering_enabled = false,
|
||||
bool enable_package_name_filter = false,
|
||||
perfetto::protos::gen::ChromeConfig::ClientPriority =
|
||||
perfetto::protos::gen::ChromeConfig::USER_INITIATED);
|
||||
perfetto::protos::gen::ChromeConfig::USER_INITIATED,
|
||||
bool enable_system_backend = false);
|
||||
|
||||
} // namespace tracing
|
||||
|
||||
|
@ -5,9 +5,11 @@
|
||||
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "base/trace_event/trace_config.h"
|
||||
@ -236,12 +238,31 @@ void PerfettoTracedProcess::SetupForTesting(
|
||||
}
|
||||
|
||||
void PerfettoTracedProcess::ResetForTesting() {
|
||||
task_runner_ = nullptr;
|
||||
tracing_backend_.reset();
|
||||
startup_tracing_needed_ = false;
|
||||
// TODO(skyostil): We only uninitialize Perfetto for now, but there may also
|
||||
// be other tracing-related state which should not leak between tests.
|
||||
perfetto::Tracing::ResetForTesting();
|
||||
base::WaitableEvent on_reset_done;
|
||||
// The tracing backend is used internally in Perfetto on the |task_runner_|
|
||||
// sequence. Reset and destroy the backend on the task runner to avoid racing
|
||||
// in resetting Perfetto.
|
||||
auto reset_task = base::BindOnce(
|
||||
[](decltype(tracing_backend_) tracing_backend,
|
||||
base::WaitableEvent* on_reset_done) {
|
||||
tracing_backend.reset();
|
||||
// TODO(skyostil): We only uninitialize Perfetto
|
||||
// for now, but there may also be other
|
||||
// tracing-related state which should not leak
|
||||
// between tests.
|
||||
perfetto::Tracing::ResetForTesting();
|
||||
on_reset_done->Signal();
|
||||
},
|
||||
std::move(tracing_backend_), &on_reset_done);
|
||||
if (task_runner_->RunsTasksInCurrentSequence()) {
|
||||
std::move(reset_task).Run();
|
||||
} else {
|
||||
task_runner_->PostTask(FROM_HERE, std::move(reset_task));
|
||||
|
||||
on_reset_done.Wait();
|
||||
}
|
||||
task_runner_ = nullptr;
|
||||
}
|
||||
|
||||
void PerfettoTracedProcess::RequestStartupTracing(
|
||||
|
@ -719,7 +719,13 @@ PerfettoTracingBackend::ConnectProducer(const ConnectProducerArgs& args) {
|
||||
|
||||
// Return the ProducerEndpoint to the tracing muxer, and then call
|
||||
// BindProducerConnectionIfNecessary().
|
||||
muxer_task_runner_->PostTask([this] { BindProducerConnectionIfNecessary(); });
|
||||
muxer_task_runner_->PostTask([weak_this = weak_factory_.GetWeakPtr()] {
|
||||
if (!weak_this) {
|
||||
// Can be destroyed in testing.
|
||||
return;
|
||||
}
|
||||
weak_this->BindProducerConnectionIfNecessary();
|
||||
});
|
||||
return producer_endpoint;
|
||||
}
|
||||
|
||||
@ -741,7 +747,13 @@ void PerfettoTracingBackend::OnProducerConnected(
|
||||
}
|
||||
|
||||
if (task_runner) {
|
||||
task_runner->PostTask([this] { BindProducerConnectionIfNecessary(); });
|
||||
task_runner->PostTask([weak_this = weak_factory_.GetWeakPtr()] {
|
||||
if (!weak_this) {
|
||||
// Can be destroyed in testing.
|
||||
return;
|
||||
}
|
||||
weak_this->BindProducerConnectionIfNecessary();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PERFETTO_TRACING_BACKEND_H_
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/sequence_checker.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
@ -67,6 +68,8 @@ class PerfettoTracingBackend : public perfetto::TracingBackend {
|
||||
|
||||
scoped_refptr<base::SequencedTaskRunner> consumer_connection_task_runner_;
|
||||
ConsumerConnectionFactory consumer_connection_factory_;
|
||||
|
||||
base::WeakPtrFactory<PerfettoTracingBackend> weak_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace tracing
|
||||
|
@ -40,6 +40,10 @@ BASE_FEATURE(kEnablePerfettoSystemTracing,
|
||||
#endif
|
||||
);
|
||||
|
||||
BASE_FEATURE(kEnablePerfettoSystemBackgroundTracing,
|
||||
"EnablePerfettoSystemBackgroundTracing",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
} // namespace features
|
||||
|
||||
namespace tracing {
|
||||
@ -57,4 +61,10 @@ bool ShouldSetupSystemTracing() {
|
||||
base::FEATURE_ENABLED_BY_DEFAULT;
|
||||
}
|
||||
|
||||
bool SystemBackgroundTracingEnabled() {
|
||||
return ShouldSetupSystemTracing() &&
|
||||
base::FeatureList::IsEnabled(
|
||||
features::kEnablePerfettoSystemBackgroundTracing);
|
||||
}
|
||||
|
||||
} // namespace tracing
|
||||
|
@ -21,6 +21,9 @@ extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature
|
||||
extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature
|
||||
kEnablePerfettoSystemTracing;
|
||||
|
||||
extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature
|
||||
kEnablePerfettoSystemBackgroundTracing;
|
||||
|
||||
} // namespace features
|
||||
|
||||
namespace tracing {
|
||||
@ -30,6 +33,10 @@ namespace tracing {
|
||||
// android builds).
|
||||
bool COMPONENT_EXPORT(TRACING_CPP) ShouldSetupSystemTracing();
|
||||
|
||||
// Returns true if the system tracing backend is available for background
|
||||
// tracing scenarios.
|
||||
bool COMPONENT_EXPORT(TRACING_CPP) SystemBackgroundTracingEnabled();
|
||||
|
||||
} // namespace tracing
|
||||
|
||||
#endif // SERVICES_TRACING_PUBLIC_CPP_TRACING_FEATURES_H_
|
||||
|
Reference in New Issue
Block a user