summaryrefslogtreecommitdiff
path: root/runtime/metrics
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/metrics')
-rw-r--r--runtime/metrics/reporter.cc27
-rw-r--r--runtime/metrics/reporter.h5
-rw-r--r--runtime/metrics/reporter_test.cc43
-rw-r--r--runtime/metrics/statsd.cc199
-rw-r--r--runtime/metrics/statsd.h2
5 files changed, 226 insertions, 50 deletions
diff --git a/runtime/metrics/reporter.cc b/runtime/metrics/reporter.cc
index a44066e487..6fc1a148aa 100644
--- a/runtime/metrics/reporter.cc
+++ b/runtime/metrics/reporter.cc
@@ -16,11 +16,12 @@
#include "reporter.h"
-#include <algorithm>
-
#include <android-base/parseint.h>
+#include <algorithm>
+
#include "base/flags.h"
+#include "base/stl_util.h"
#include "oat_file_manager.h"
#include "runtime.h"
#include "runtime_options.h"
@@ -126,10 +127,17 @@ void MetricsReporter::BackgroundThreadRun() {
// Configure the backends
if (config_.dump_to_logcat) {
- backends_.emplace_back(new LogBackend(LogSeverity::INFO));
+ backends_.emplace_back(new LogBackend(std::make_unique<TextFormatter>(), LogSeverity::INFO));
}
if (config_.dump_to_file.has_value()) {
- backends_.emplace_back(new FileBackend(config_.dump_to_file.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();
@@ -189,12 +197,10 @@ void MetricsReporter::MaybeResetTimeout() {
}
}
-const ArtMetrics* MetricsReporter::GetMetrics() {
- return runtime_->GetMetrics();
-}
+ArtMetrics* MetricsReporter::GetMetrics() { return runtime_->GetMetrics(); }
void MetricsReporter::ReportMetrics() {
- const ArtMetrics* metrics = GetMetrics();
+ ArtMetrics* metrics = GetMetrics();
if (!session_started_) {
for (auto& backend : backends_) {
@@ -203,9 +209,7 @@ void MetricsReporter::ReportMetrics() {
session_started_ = true;
}
- for (auto& backend : backends_) {
- metrics->ReportAllMetrics(backend.get());
- }
+ metrics->ReportAllMetricsAndResetValueMetrics(MakeNonOwningPointerVector(backends_));
}
void MetricsReporter::UpdateSessionInBackends() {
@@ -291,6 +295,7 @@ ReportingConfig ReportingConfig::FromFlags(bool is_system_server) {
.dump_to_logcat = gFlags.MetricsWriteToLogcat(),
.dump_to_file = gFlags.MetricsWriteToFile.GetValueOptional(),
.dump_to_statsd = gFlags.MetricsWriteToStatsd(),
+ .metrics_format = gFlags.MetricsFormat(),
.period_spec = period_spec,
.reporting_num_mods = reporting_num_mods,
.reporting_mods = reporting_mods,
diff --git a/runtime/metrics/reporter.h b/runtime/metrics/reporter.h
index daeaf1fa18..865815e0bf 100644
--- a/runtime/metrics/reporter.h
+++ b/runtime/metrics/reporter.h
@@ -78,6 +78,9 @@ struct ReportingConfig {
// If set, provides a file name to enable metrics logging to a file.
std::optional<std::string> dump_to_file;
+ // Provides the desired output format for metrics written to a file.
+ std::string metrics_format;
+
// The reporting period configuration.
std::optional<ReportingPeriodSpec> period_spec;
@@ -133,7 +136,7 @@ class MetricsReporter {
// Returns the metrics to be reported.
// This exists only for testing purposes so that we can verify reporting with minimum
// runtime interference.
- virtual const ArtMetrics* GetMetrics();
+ virtual ArtMetrics* GetMetrics();
MetricsReporter(const ReportingConfig& config, Runtime* runtime);
diff --git a/runtime/metrics/reporter_test.cc b/runtime/metrics/reporter_test.cc
index 3807c77991..848a74ee61 100644
--- a/runtime/metrics/reporter_test.cc
+++ b/runtime/metrics/reporter_test.cc
@@ -34,13 +34,10 @@ namespace metrics {
// other runtime setup logic.
class MockMetricsReporter : public MetricsReporter {
protected:
- MockMetricsReporter(const ReportingConfig& config, Runtime* runtime) :
- MetricsReporter(config, runtime),
- art_metrics_(new ArtMetrics()) {}
+ MockMetricsReporter(const ReportingConfig& config, Runtime* runtime)
+ : MetricsReporter(config, runtime), art_metrics_(std::make_unique<ArtMetrics>()) {}
- const ArtMetrics* GetMetrics() override {
- return art_metrics_.get();
- }
+ ArtMetrics* GetMetrics() override { return art_metrics_.get(); }
std::unique_ptr<ArtMetrics> art_metrics_;
@@ -174,9 +171,9 @@ class MetricsReporterTest : public CommonRuntimeTest {
CompilationReason reason = CompilationReason::kUnknown) {
// TODO: we should iterate through all the other metrics to make sure they were not
// reported. However, we don't have an easy to use iteration mechanism over metrics yet.
- // We should ads one
+ // We should add one
ASSERT_EQ(backend_->GetReports().size(), size);
- for (auto report : backend_->GetReports()) {
+ for (const TestBackend::Report& report : backend_->GetReports()) {
ASSERT_EQ(report.data.Get(DatumId::kClassVerificationCount), with_metrics ? 2u : 0u);
ASSERT_EQ(report.data.Get(DatumId::kJitMethodCompileCount), with_metrics ? 1u : 0u);
}
@@ -220,7 +217,7 @@ TEST_F(MetricsReporterTest, StartupOnly) {
WaitForReport(/*report_count=*/ 1, /*sleep_period_ms=*/ 50);
VerifyReports(/*size=*/ 1, /*with_metrics*/ true);
- // We still should not report at period.
+ // We should still not report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
@@ -241,11 +238,11 @@ TEST_F(MetricsReporterTest, StartupAndPeriod) {
WaitForReport(/*report_count=*/ 2, /*sleep_period_ms=*/ 500);
VerifyReports(/*size=*/ 2, /*with_metrics*/ true);
- // We should not longer report at period.
+ // We should no longer report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
-// LARGE TEST: This takes take 2s to run.
+// LARGE TEST: This test take 2s to run.
// Verifies startup reporting, followed by continuous reporting.
TEST_F(MetricsReporterTest, StartupAndPeriodContinuous) {
SetupReporter("S,1,*");
@@ -262,7 +259,7 @@ TEST_F(MetricsReporterTest, StartupAndPeriodContinuous) {
WaitForReport(/*report_count=*/ 3, /*sleep_period_ms=*/ 500);
VerifyReports(/*size=*/ 3, /*with_metrics*/ true);
- // We should keep reporting at period.
+ // We should keep reporting continuously.
ASSERT_TRUE(ShouldContinueReporting());
}
@@ -282,11 +279,11 @@ TEST_F(MetricsReporterTest, OneTime) {
WaitForReport(/*report_count=*/ 1, /*sleep_period_ms=*/ 500);
VerifyReports(/*size=*/ 1, /*with_metrics*/ true);
- // We should not longer report at period.
+ // We should no longer report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
-// LARGE TEST: This takes take 5s to run.
+// LARGE TEST: This test takes 5s to run.
// Verifies a sequence of reporting, at different interval of times.
TEST_F(MetricsReporterTest, PeriodContinuous) {
SetupReporter("1,2,*");
@@ -303,7 +300,7 @@ TEST_F(MetricsReporterTest, PeriodContinuous) {
WaitForReport(/*report_count=*/ 3, /*sleep_period_ms=*/ 500);
VerifyReports(/*size=*/ 3, /*with_metrics*/ true);
- // We should keep reporting at period.
+ // We should keep reporting continuously.
ASSERT_TRUE(ShouldContinueReporting());
}
@@ -323,13 +320,13 @@ TEST_F(MetricsReporterTest, NoMetrics) {
WaitForReport(/*report_count=*/ 1, /*sleep_period_ms=*/ 500);
VerifyReports(/*size=*/ 1, /*with_metrics*/ false);
- // We should not longer report at period.
+ // We should no longer report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
// Verify we don't start reporting if the sample rate is set to 0.
TEST_F(MetricsReporterTest, SampleRateDisable) {
- SetupReporter("1", /*session_id=*/ 1, /*reporting_mods=*/ 0);
+ SetupReporter("1,*", /*session_id=*/ 1, /*reporting_mods=*/ 0);
// The background thread should not start.
ASSERT_FALSE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
@@ -341,7 +338,7 @@ TEST_F(MetricsReporterTest, SampleRateDisable) {
// Verify we don't start reporting if the sample rate is low and the session does
// not meet conditions.
TEST_F(MetricsReporterTest, SampleRateDisable24) {
- SetupReporter("1", /*session_id=*/ 125, /*reporting_mods=*/ 24);
+ SetupReporter("1,*", /*session_id=*/ 125, /*reporting_mods=*/ 24);
// The background thread should not start.
ASSERT_FALSE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
@@ -353,9 +350,9 @@ TEST_F(MetricsReporterTest, SampleRateDisable24) {
// Verify we start reporting if the sample rate and the session meet
// reporting conditions
TEST_F(MetricsReporterTest, SampleRateEnable50) {
- SetupReporter("1", /*session_id=*/ 125, /*reporting_mods=*/ 50);
+ SetupReporter("1,*", /*session_id=*/ 125, /*reporting_mods=*/ 50);
- // The background thread should not start.
+ // The background thread should start.
ASSERT_TRUE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
ASSERT_FALSE(ShouldReportAtStartup());
@@ -365,7 +362,7 @@ TEST_F(MetricsReporterTest, SampleRateEnable50) {
// Verify we start reporting if the sample rate and the session meet
// reporting conditions
TEST_F(MetricsReporterTest, SampleRateEnableAll) {
- SetupReporter("1", /*session_id=*/ 1099, /*reporting_mods=*/ 100);
+ SetupReporter("1,*", /*session_id=*/ 1099, /*reporting_mods=*/ 100);
// The background thread should start.
ASSERT_TRUE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
@@ -411,7 +408,7 @@ class ReportingPeriodSpecTest : public testing::Test {
const std::string& spec_str,
bool startup_first,
bool continuous,
- std::vector<uint32_t> periods) {
+ const std::vector<uint32_t>& periods) {
Verify(spec_str, true, startup_first, continuous, periods);
}
@@ -420,7 +417,7 @@ class ReportingPeriodSpecTest : public testing::Test {
bool valid,
bool startup_first,
bool continuous,
- std::vector<uint32_t> periods) {
+ const std::vector<uint32_t>& periods) {
std::string error_msg;
std::optional<ReportingPeriodSpec> spec = ReportingPeriodSpec::Parse(spec_str, &error_msg);
diff --git a/runtime/metrics/statsd.cc b/runtime/metrics/statsd.cc
index f68d50730f..7002f22fae 100644
--- a/runtime/metrics/statsd.cc
+++ b/runtime/metrics/statsd.cc
@@ -19,6 +19,10 @@
#include "arch/instruction_set.h"
#include "base/compiler_filter.h"
#include "base/metrics/metrics.h"
+#include "gc/collector/mark_compact.h"
+#include "gc/heap.h"
+#include "gc/space/image_space.h"
+#include "runtime.h"
#include "statslog_art.h"
#pragma clang diagnostic push
@@ -44,27 +48,49 @@ constexpr std::optional<int32_t> EncodeDatumId(DatumId datum_id) {
case DatumId::kClassVerificationTotalTime:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_CLASS_VERIFICATION_TIME_COUNTER_MICROS);
+ case DatumId::kClassVerificationTotalTimeDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_CLASS_VERIFICATION_TIME_MICROS);
case DatumId::kJitMethodCompileTotalTime:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_JIT_METHOD_COMPILE_TIME_MICROS);
+ case DatumId::kJitMethodCompileTotalTimeDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_JIT_METHOD_COMPILE_TIME_MICROS);
case DatumId::kClassLoadingTotalTime:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_CLASS_LOADING_TIME_COUNTER_MICROS);
+ case DatumId::kClassLoadingTotalTimeDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_CLASS_LOADING_TIME_MICROS);
case DatumId::kClassVerificationCount:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_CLASS_VERIFICATION_COUNT);
+ case DatumId::kClassVerificationCountDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_CLASS_VERIFICATION_COUNT);
case DatumId::kWorldStopTimeDuringGCAvg:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_TIME_AVG_MICROS);
case DatumId::kYoungGcCount:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_COUNT);
+ case DatumId::kYoungGcCountDelta:
+ return std::make_optional(
+ statsd::
+ ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_COUNT);
case DatumId::kFullGcCount:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_COUNT);
+ case DatumId::kFullGcCountDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_COUNT);
case DatumId::kTotalBytesAllocated:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_TOTAL_BYTES_ALLOCATED);
+ case DatumId::kTotalBytesAllocatedDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_TOTAL_BYTES_ALLOCATED);
case DatumId::kYoungGcCollectionTime:
return std::make_optional(
statsd::
@@ -83,6 +109,9 @@ constexpr std::optional<int32_t> EncodeDatumId(DatumId datum_id) {
case DatumId::kJitMethodCompileCount:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_JIT_METHOD_COMPILE_COUNT);
+ case DatumId::kJitMethodCompileCountDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_JIT_METHOD_COMPILE_COUNT);
case DatumId::kYoungGcTracingThroughput:
return std::make_optional(
statsd::
@@ -94,6 +123,9 @@ constexpr std::optional<int32_t> EncodeDatumId(DatumId datum_id) {
case DatumId::kTotalGcCollectionTime:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_TOTAL_COLLECTION_TIME_MS);
+ case DatumId::kTotalGcCollectionTimeDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_TOTAL_COLLECTION_TIME_MS);
case DatumId::kYoungGcThroughputAvg:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_THROUGHPUT_AVG_MB_PER_SEC);
@@ -106,6 +138,60 @@ constexpr std::optional<int32_t> EncodeDatumId(DatumId datum_id) {
case DatumId::kFullGcTracingThroughputAvg:
return std::make_optional(
statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_TRACING_THROUGHPUT_AVG_MB_PER_SEC);
+ case DatumId::kGcWorldStopTime:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_TIME_US);
+ case DatumId::kGcWorldStopTimeDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_WORLD_STOP_TIME_US);
+ case DatumId::kGcWorldStopCount:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_COUNT);
+ case DatumId::kGcWorldStopCountDelta:
+ return std::make_optional(
+ statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_WORLD_STOP_COUNT);
+ case DatumId::kYoungGcScannedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_SCANNED_BYTES);
+ case DatumId::kYoungGcScannedBytesDelta:
+ return std::make_optional(
+ statsd::
+ ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_SCANNED_BYTES);
+ case DatumId::kYoungGcFreedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_FREED_BYTES);
+ case DatumId::kYoungGcFreedBytesDelta:
+ return std::make_optional(
+ statsd::
+ ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_FREED_BYTES);
+ case DatumId::kYoungGcDuration:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_DURATION_MS);
+ case DatumId::kYoungGcDurationDelta:
+ return std::make_optional(
+ statsd::
+ ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_DURATION_MS);
+ case DatumId::kFullGcScannedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_SCANNED_BYTES);
+ case DatumId::kFullGcScannedBytesDelta:
+ return std::make_optional(
+ statsd::
+ ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_SCANNED_BYTES);
+ case DatumId::kFullGcFreedBytes:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_FREED_BYTES);
+ case DatumId::kFullGcFreedBytesDelta:
+ return std::make_optional(
+ statsd::
+ ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_FREED_BYTES);
+ case DatumId::kFullGcDuration:
+ return std::make_optional(
+ statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_DURATION_MS);
+ case DatumId::kFullGcDurationDelta:
+ return std::make_optional(
+ statsd::
+ ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_DURATION_MS);
}
}
@@ -185,6 +271,9 @@ constexpr int32_t EncodeCompilationReason(CompilationReason reason) {
return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_CMDLINE;
case CompilationReason::kVdex:
return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_VDEX;
+ case CompilationReason::kBootAfterMainlineUpdate:
+ return statsd::
+ ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BOOT_AFTER_MAINLINE_UPDATE;
}
}
@@ -196,6 +285,8 @@ constexpr int32_t EncodeInstructionSet(InstructionSet isa) {
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM;
case InstructionSet::kArm64:
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM64;
+ case InstructionSet::kRiscv64:
+ return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_RISCV64;
case InstructionSet::kX86:
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_X86;
case InstructionSet::kX86_64:
@@ -205,6 +296,51 @@ constexpr int32_t EncodeInstructionSet(InstructionSet isa) {
}
}
+constexpr int32_t EncodeGcCollectorType(gc::CollectorType collector_type) {
+ switch (collector_type) {
+ case gc::CollectorType::kCollectorTypeMS:
+ return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_MARK_SWEEP;
+ case gc::CollectorType::kCollectorTypeCMS:
+ return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_MARK_SWEEP;
+ case gc::CollectorType::kCollectorTypeCMC:
+ return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_MARK_COMPACT;
+ case gc::CollectorType::kCollectorTypeSS:
+ return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_SEMI_SPACE;
+ case gc::kCollectorTypeCC:
+ return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_COPYING;
+ case gc::kCollectorTypeCCBackground:
+ return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_COPYING_BACKGROUND;
+ case gc::kCollectorTypeNone:
+ case gc::kCollectorTypeInstrumentation:
+ case gc::kCollectorTypeAddRemoveAppImageSpace:
+ case gc::kCollectorTypeDebugger:
+ case gc::kCollectorTypeHomogeneousSpaceCompact:
+ case gc::kCollectorTypeClassLinker:
+ case gc::kCollectorTypeJitCodeCache:
+ case gc::kCollectorTypeHprof:
+ case gc::kCollectorTypeAddRemoveSystemWeakHolder:
+ case gc::kCollectorTypeGetObjectsAllocated:
+ case gc::kCollectorTypeCriticalSection:
+ case gc::kCollectorTypeHeapTrim:
+ return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_UNKNOWN;
+ }
+}
+
+int32_t EncodeUffdMinorFaultSupport() {
+ auto [uffd_supported, minor_fault_supported] = gc::collector::MarkCompact::GetUffdAndMinorFault();
+
+ if (uffd_supported) {
+ if (minor_fault_supported) {
+ return statsd::ART_DATUM_REPORTED__UFFD_SUPPORT__ART_UFFD_SUPPORT_MINOR_FAULT_MODE_SUPPORTED;
+ } else {
+ return statsd::
+ ART_DATUM_REPORTED__UFFD_SUPPORT__ART_UFFD_SUPPORT_MINOR_FAULT_MODE_NOT_SUPPORTED;
+ }
+ } else {
+ return statsd::ART_DATUM_REPORTED__UFFD_SUPPORT__ART_UFFD_SUPPORT_UFFD_NOT_SUPPORTED;
+ }
+}
+
class StatsdBackend : public MetricsBackend {
public:
void BeginOrUpdateSession(const SessionData& session_data) override {
@@ -218,22 +354,41 @@ class StatsdBackend : public MetricsBackend {
void ReportCounter(DatumId counter_type, uint64_t value) override {
std::optional<int32_t> datum_id = EncodeDatumId(counter_type);
- if (datum_id.has_value()) {
- statsd::stats_write(
- statsd::ART_DATUM_REPORTED,
- session_data_.session_id,
- session_data_.uid,
- EncodeCompileFilter(session_data_.compiler_filter),
- EncodeCompilationReason(session_data_.compilation_reason),
- current_timestamp_,
- /*thread_type=*/0, // TODO: collect and report thread type (0 means UNKNOWN, but that
- // constant is not present in all branches)
- datum_id.value(),
- static_cast<int64_t>(value),
- statsd::ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_UNKNOWN,
- statsd::ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_UNKNOWN,
- EncodeInstructionSet(kRuntimeISA));
+ if (!datum_id.has_value()) {
+ return;
+ }
+
+ int32_t atom;
+ switch (counter_type) {
+#define EVENT_METRIC_CASE(name, ...) case DatumId::k##name:
+ ART_EVENT_METRICS(EVENT_METRIC_CASE)
+#undef EVENT_METRIC_CASE
+ atom = statsd::ART_DATUM_REPORTED;
+ break;
+
+#define VALUE_METRIC_CASE(name, type, ...) case DatumId::k##name:
+ ART_VALUE_METRICS(VALUE_METRIC_CASE)
+#undef VALUE_METRIC_CASE
+ atom = statsd::ART_DATUM_DELTA_REPORTED;
+ break;
}
+
+ statsd::stats_write(
+ atom,
+ session_data_.session_id,
+ session_data_.uid,
+ EncodeCompileFilter(session_data_.compiler_filter),
+ EncodeCompilationReason(session_data_.compilation_reason),
+ current_timestamp_,
+ 0, // TODO: collect and report thread type (0 means UNKNOWN, but that
+ // constant is not present in all branches)
+ datum_id.value(),
+ static_cast<int64_t>(value),
+ statsd::ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_UNKNOWN,
+ statsd::ART_DATUM_REPORTED__APK_TYPE__ART_APK_TYPE_UNKNOWN,
+ EncodeInstructionSet(kRuntimeISA),
+ EncodeGcCollectorType(Runtime::Current()->GetHeap()->GetForegroundCollectorType()),
+ EncodeUffdMinorFaultSupport());
}
void ReportHistogram(DatumId /*histogram_type*/,
@@ -256,6 +411,20 @@ class StatsdBackend : public MetricsBackend {
std::unique_ptr<MetricsBackend> CreateStatsdBackend() { return std::make_unique<StatsdBackend>(); }
+void ReportDeviceMetrics() {
+ Runtime* runtime = Runtime::Current();
+ int32_t boot_image_status;
+ if (runtime->GetHeap()->HasBootImageSpace() && !runtime->HasImageWithProfile()) {
+ boot_image_status = statsd::ART_DEVICE_DATUM_REPORTED__BOOT_IMAGE_STATUS__STATUS_FULL;
+ } else if (runtime->GetHeap()->HasBootImageSpace() &&
+ runtime->GetHeap()->GetBootImageSpaces()[0]->GetProfileFiles().empty()) {
+ boot_image_status = statsd::ART_DEVICE_DATUM_REPORTED__BOOT_IMAGE_STATUS__STATUS_MINIMAL;
+ } else {
+ boot_image_status = statsd::ART_DEVICE_DATUM_REPORTED__BOOT_IMAGE_STATUS__STATUS_NONE;
+ }
+ statsd::stats_write(statsd::ART_DEVICE_DATUM_REPORTED, boot_image_status);
+}
+
} // namespace metrics
} // namespace art
diff --git a/runtime/metrics/statsd.h b/runtime/metrics/statsd.h
index a99d510088..cb84825301 100644
--- a/runtime/metrics/statsd.h
+++ b/runtime/metrics/statsd.h
@@ -27,8 +27,10 @@ class MetricsBackend;
// Statsd is only supported on Android
#ifdef __ANDROID__
std::unique_ptr<MetricsBackend> CreateStatsdBackend();
+void ReportDeviceMetrics();
#else
inline std::unique_ptr<MetricsBackend> CreateStatsdBackend() { return nullptr; }
+inline void ReportDeviceMetrics() {}
#endif
} // namespace metrics