blob: 9c9012a51b76f4542544edc19cb95cbdf5ec583e [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/tracing/common/background_tracing_metrics_provider.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/bind_post_task.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "components/metrics/content/gpu_metrics_provider.h"
#include "components/metrics/cpu_metrics_provider.h"
#include "components/metrics/metrics_features.h"
#include "components/metrics/metrics_log.h"
#include "content/public/browser/background_tracing_manager.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
#include "third_party/metrics_proto/trace_log.pb.h"
namespace tracing {
BackgroundTracingMetricsProvider::BackgroundTracingMetricsProvider() = default;
BackgroundTracingMetricsProvider::~BackgroundTracingMetricsProvider() = default;
void BackgroundTracingMetricsProvider::Init() {
system_profile_providers_.emplace_back(
std::make_unique<metrics::CPUMetricsProvider>());
system_profile_providers_.emplace_back(
std::make_unique<metrics::GPUMetricsProvider>());
content::BackgroundTracingManager::GetInstance().SetSystemProfileRecorder(
base::BindRepeating(
[](base::WeakPtr<BackgroundTracingMetricsProvider> self) {
if (self) {
return self->RecordSystemProfileMetrics();
}
return std::string();
},
weak_factory_.GetWeakPtr()));
DoInit();
}
std::string BackgroundTracingMetricsProvider::RecordSystemProfileMetrics() {
metrics::SystemProfileProto system_profile_proto;
RecordCoreSystemProfileMetrics(&system_profile_proto);
// RecordCoreSystemProfileMetrics is overridden by subclasses in
// Chrome/WebView to provide core system profile metrics.
// BackgroundTracingManager stores the returned system profile together with
// the trace in the trace database at trace recording time.
// ProvideIndependentMetrics() later overrides the system_profile in the log
// proto with these stored metrics, to ensure that the uploaded system profile
// matches the system profile at trace recording time.
for (auto& provider : system_profile_providers_) {
provider->ProvideSystemProfileMetricsWithLogCreationTime(
base::TimeTicks::Now(), &system_profile_proto);
}
std::string serialized_system_profile;
system_profile_proto.SerializeToString(&serialized_system_profile);
return serialized_system_profile;
}
bool BackgroundTracingMetricsProvider::HasIndependentMetrics() {
return content::BackgroundTracingManager::GetInstance().HasTraceToUpload();
}
void BackgroundTracingMetricsProvider::ProvideIndependentMetrics(
base::OnceClosure serialize_log_callback,
base::OnceCallback<void(bool)> done_callback,
metrics::ChromeUserMetricsExtension* uma_proto,
base::HistogramSnapshotManager* snapshot_manager) {
auto task_runner = base::SequencedTaskRunner::GetCurrentDefault();
auto provide_embedder_metrics = GetEmbedderMetricsProvider();
content::BackgroundTracingManager::GetInstance().GetTraceToUpload(
base::BindOnce(
[](base::OnceCallback<bool(metrics::ChromeUserMetricsExtension*,
std::string&&)> provide_embedder_metrics,
base::OnceClosure serialize_log_callback,
base::OnceCallback<void(bool)> done_callback,
metrics::ChromeUserMetricsExtension* uma_proto,
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::optional<std::string> compressed_trace,
std::optional<std::string> serialized_system_profile) {
if (!compressed_trace ||
!std::move(provide_embedder_metrics)
.Run(uma_proto, std::move(*compressed_trace))) {
task_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(done_callback), false));
return;
}
if (serialized_system_profile) {
metrics::SystemProfileProto system_profile;
system_profile.ParsePartialFromString(*serialized_system_profile);
uma_proto->mutable_system_profile()->MergeFrom(system_profile);
}
// Serialize the log on the background instead of on the main
// thread.
base::ThreadPool::PostTask(
FROM_HERE,
{base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
std::move(serialize_log_callback)
.Then(base::BindPostTask(
task_runner,
base::BindOnce(std::move(done_callback), true))));
},
std::move(provide_embedder_metrics),
std::move(serialize_log_callback), std::move(done_callback),
uma_proto, task_runner));
}
base::OnceCallback<bool(metrics::ChromeUserMetricsExtension*, std::string&&)>
BackgroundTracingMetricsProvider::GetEmbedderMetricsProvider() {
return base::BindOnce([](metrics::ChromeUserMetricsExtension* uma_proto,
std::string&& compressed_trace) {
SetTrace(uma_proto->add_trace_log(), std::move(compressed_trace));
return true;
});
}
// static
void BackgroundTracingMetricsProvider::SetTrace(
metrics::TraceLog* log,
std::string&& compressed_trace) {
base::UmaHistogramCounts100000("Tracing.Background.UploadingTraceSizeInKB",
compressed_trace.size() / 1024);
log->set_raw_data(std::move(compressed_trace));
log->set_compression_type(metrics::TraceLog::COMPRESSION_TYPE_ZLIB);
}
} // namespace tracing