[metrics] Enable periodic reporting for system server
This enables reporting from system server once an hour.
The reason is that system server is long-running, so startup metrics,
which are all that are enabled by default otherwise, are not as
meaningful. Note that the reporting period can still be overridden by
a command line argument.
Testing instructions:
adb shell setprop dalvik.vm.extra-opts -Xwrite-metrics-to-log
adb logcat -e "ART internal metrics"
Observe periodic system server reports.
Bug: 170149255
Test: manual (see above)
Test: ./test.py --run-test --host -t 911
Change-Id: I71775e454c6fd07c4312e3df9ae8082fa497ea93
diff --git a/libartbase/base/time_utils.h b/libartbase/base/time_utils.h
index e1273a3..fbf3e94 100644
--- a/libartbase/base/time_utils.h
+++ b/libartbase/base/time_utils.h
@@ -35,6 +35,10 @@
kTimeUnitSecond,
};
+// Constants for common time periods.
+constexpr unsigned int kOneMinuteInSeconds = 60;
+constexpr unsigned int kOneHourInSeconds = 60 * kOneMinuteInSeconds;
+
// Returns a human-readable time string which prints every nanosecond while trying to limit the
// number of trailing zeros. Prints using the largest human readable unit up to a second.
// e.g. "1ms", "1.000000001s", "1.001us"
diff --git a/runtime/metrics/reporter.cc b/runtime/metrics/reporter.cc
index 745b9b1..262422e 100644
--- a/runtime/metrics/reporter.cc
+++ b/runtime/metrics/reporter.cc
@@ -37,12 +37,25 @@
MetricsReporter::~MetricsReporter() { MaybeStopBackgroundThread(); }
-void MetricsReporter::MaybeStartBackgroundThread(SessionData session_data) {
+bool MetricsReporter::IsPeriodicReportingEnabled() const {
+ return config_.periodic_report_seconds.has_value();
+}
+
+void MetricsReporter::SetReportingPeriod(unsigned int period_seconds) {
+ DCHECK(!thread_.has_value()) << "The reporting period should not be changed after the background "
+ "reporting thread is started.";
+
+ config_.periodic_report_seconds = period_seconds;
+}
+
+bool MetricsReporter::MaybeStartBackgroundThread(SessionData session_data) {
+ if (!config_.ReportingEnabled()) {
+ return false;
+ }
CHECK(!thread_.has_value());
-
thread_.emplace(&MetricsReporter::BackgroundThreadRun, this);
-
messages_.SendMessage(BeginSessionMessage{session_data});
+ return true;
}
void MetricsReporter::MaybeStopBackgroundThread() {
diff --git a/runtime/metrics/reporter.h b/runtime/metrics/reporter.h
index ee0d13a..ca43163 100644
--- a/runtime/metrics/reporter.h
+++ b/runtime/metrics/reporter.h
@@ -62,7 +62,11 @@
~MetricsReporter();
// Creates and runs the background reporting thread.
- void MaybeStartBackgroundThread(SessionData session_data);
+ //
+ // Does nothing if the reporting config does not have any outputs enabled.
+ //
+ // Returns true if the thread was started, false otherwise.
+ bool MaybeStartBackgroundThread(SessionData session_data);
// Sends a request to the background thread to shutdown.
void MaybeStopBackgroundThread();
@@ -71,6 +75,14 @@
// completes.
void NotifyStartupCompleted();
+ bool IsPeriodicReportingEnabled() const;
+
+ // Changes the reporting period.
+ //
+ // This function is not thread safe and may only be called before the background reporting thread
+ // has been started.
+ void SetReportingPeriod(unsigned int period_seconds);
+
static constexpr const char* kBackgroundThreadName = "Metrics Background Reporting Thread";
private:
@@ -85,7 +97,7 @@
// Outputs the current state of the metrics to the destination set by config_.
void ReportMetrics() const;
- const ReportingConfig config_;
+ ReportingConfig config_;
Runtime* runtime_;
std::vector<std::unique_ptr<MetricsBackend>> backends_;
std::optional<std::thread> thread_;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 3c187d3..7010c17 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1070,6 +1070,14 @@
heap_->ResetGcPerformanceInfo();
if (metrics_reporter_ != nullptr) {
+ if (IsSystemServer() && !metrics_reporter_->IsPeriodicReportingEnabled()) {
+ // For system server, we don't get startup metrics, so make sure we have periodic reporting
+ // enabled.
+ //
+ // Note that this does not override the command line argument if one is given.
+ metrics_reporter_->SetReportingPeriod(kOneHourInSeconds);
+ }
+
metrics::SessionData session_data{metrics::SessionData::CreateDefault()};
session_data.session_id = GetRandomNumber<int64_t>(0, std::numeric_limits<int64_t>::max());
// TODO: set session_data.compilation_reason and session_data.compiler_filter
@@ -1846,9 +1854,7 @@
void Runtime::InitMetrics(const RuntimeArgumentMap& runtime_options) {
auto metrics_config = metrics::ReportingConfig::FromRuntimeArguments(runtime_options);
- if (metrics_config.ReportingEnabled()) {
- metrics_reporter_ = metrics::MetricsReporter::Create(metrics_config, this);
- }
+ metrics_reporter_ = metrics::MetricsReporter::Create(metrics_config, this);
}
bool Runtime::EnsurePluginLoaded(const char* plugin_name, std::string* error_msg) {