std::unique_ptr<MetricsReporter> MetricsReporter::Create( const ReportingConfig& config, Runtime* runtime) { // We can't use std::make_unique here because the MetricsReporter constructor is private. return std::unique_ptr<MetricsReporter>{new MetricsReporter{std::move(config), runtime}};
}
void MetricsReporter::ReloadConfig(const ReportingConfig& config) {
DCHECK(!thread_.has_value()) << "The config cannot be reloaded after the background " "reporting thread is started.";
config_ = config;
}
// AttachCurrentThread is needed so we can safely use the ART concurrency primitives within the // messages_ MessageQueue. constbool attached = runtime_->AttachCurrentThread(kBackgroundThreadName, /*as_daemon=*/true,
runtime_->GetSystemThreadGroup(), /*create_peer=*/true);
if (attached) { // Mark it as rutime thread so we won't report it via jvmti.
Thread::Current()->SetIsRuntimeThread(true);
}
bool running = true;
// Configure the backends if (config_.dump_to_logcat) {
backends_.emplace_back(new LogBackend(std::make_unique<TextFormatter>(), LogSeverity::INFO));
} if (config_.dump_to_file.has_value()) {
std::unique_ptr<MetricsFormatter> formatter; if (config_.metrics_format == "xml") {
formatter = std::make_unique<XmlFormatter>();
} else {
formatter = std::make_unique<TextFormatter>();
}
backends_.emplace_back(new FileBackend(std::move(formatter), config_.dump_to_file.value()));
} if (config_.dump_to_statsd) { auto backend = CreateStatsdBackend(); if (backend != nullptr) {
backends_.emplace_back(std::move(backend));
}
}
MaybeResetTimeout();
while (running) {
messages_.SwitchReceive(
[&]([[maybe_unused]] ShutdownRequestedMessage message) {
LOG_STREAM(DEBUG) << "Shutdown request received " << session_data_.session_id;
running = false;
bool MetricsReporter::ShouldContinueReporting() const { bool result = // Only if the reporting is enabled
IsMetricsReportingEnabled(session_data_) && // and if we have period spec
config_.period_spec.has_value() && // and the periods are non empty
!config_.period_spec->periods_seconds.empty() && // and we already reported startup or not required to report startup
(startup_reported_ || !config_.period_spec->report_startup_first) && // and we still have unreported intervals or we are asked to report continuously.
(config_.period_spec->continuous_reporting ||
(report_interval_index_ < config_.period_spec->periods_seconds.size())); return result;
}
// The index is either the current report_interval_index or the last index // if we are in continuous mode and reached the end.
uint32_t index = std::min(
report_interval_index_, static_cast<uint32_t>(config_.period_spec->periods_seconds.size() - 1));
uint32_t result = config_.period_spec->periods_seconds[index];
// Advance the index if we didn't get to the end. if (report_interval_index_ < config_.period_spec->periods_seconds.size()) {
report_interval_index_++;
} return result;
}
// Split the string. Each element is separated by comma.
std::vector<std::string> elems;
Split(spec_str, ',', &elems);
// Check the startup marker (front) and the continuous one (back).
std::optional<ReportingPeriodSpec> spec = std::make_optional(ReportingPeriodSpec());
spec->spec = spec_str;
spec->report_startup_first = elems.front() == "S";
spec->continuous_reporting = elems.back() == "*";
// Compute the indices for the period values.
size_t start_interval_idx = spec->report_startup_first ? 1 : 0;
size_t end_interval_idx = spec->continuous_reporting ? (elems.size() - 1) : elems.size();
// '*' needs a numeric interval before in order to be valid. if (spec->continuous_reporting &&
end_interval_idx == start_interval_idx) {
*error_msg = "Invalid period value in spec: " + spec_str; return std::nullopt;
}
// Parse the periods. for (size_t i = start_interval_idx; i < end_interval_idx; i++) {
uint32_t period; if (!android::base::ParseUint(elems[i], &period)) {
*error_msg = "Invalid period value in spec: " + spec_str; return std::nullopt;
}
spec->periods_seconds.push_back(period);
}
return spec;
}
} // namespace metrics
} // namespace art
#pragma clang diagnostic pop // -Wconversion
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.