1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "statsd.h"
18 
19 #include "arch/instruction_set.h"
20 #include "base/compiler_filter.h"
21 #include "base/metrics/metrics.h"
22 #include "gc/collector/mark_compact.h"
23 #include "gc/heap.h"
24 #include "gc/space/image_space.h"
25 #include "runtime.h"
26 #include "statslog_art.h"
27 
28 #pragma clang diagnostic push
29 #pragma clang diagnostic error "-Wconversion"
30 
31 namespace art HIDDEN {
32 namespace metrics {
33 
34 namespace {
35 
36 // EncodeDatumId returns a std::optional that provides a enum value from atoms.proto if the datum is
37 // one that we support logging to statsd. The list of datums that ART collects is a superset of what
38 // we report to statsd. Therefore, we only have mappings for the DatumIds that statsd recognizes.
39 // Also it must be noted that histograms are not handled yet by statsd yet.
40 //
41 // Other code can use whether the result of this function has a value to decide whether to report
42 // the atom to statsd.
43 //
44 // To report additional measurements to statsd, first add an entry in atoms.proto and then add an
45 // entry to this function as well.
EncodeDatumId(DatumId datum_id)46 constexpr std::optional<int32_t> EncodeDatumId(DatumId datum_id) {
47   switch (datum_id) {
48     case DatumId::kClassVerificationTotalTime:
49       return std::make_optional(
50           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_CLASS_VERIFICATION_TIME_COUNTER_MICROS);
51     case DatumId::kClassVerificationTotalTimeDelta:
52       return std::make_optional(
53           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_CLASS_VERIFICATION_TIME_MICROS);
54     case DatumId::kJitMethodCompileTotalTime:
55       return std::make_optional(
56           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_JIT_METHOD_COMPILE_TIME_MICROS);
57     case DatumId::kJitMethodCompileTotalTimeDelta:
58       return std::make_optional(
59           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_JIT_METHOD_COMPILE_TIME_MICROS);
60     case DatumId::kClassLoadingTotalTime:
61       return std::make_optional(
62           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_CLASS_LOADING_TIME_COUNTER_MICROS);
63     case DatumId::kClassLoadingTotalTimeDelta:
64       return std::make_optional(
65           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_CLASS_LOADING_TIME_MICROS);
66     case DatumId::kClassVerificationCount:
67       return std::make_optional(
68           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_CLASS_VERIFICATION_COUNT);
69     case DatumId::kClassVerificationCountDelta:
70       return std::make_optional(
71           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_CLASS_VERIFICATION_COUNT);
72     case DatumId::kWorldStopTimeDuringGCAvg:
73       return std::make_optional(
74           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_TIME_AVG_MICROS);
75     case DatumId::kYoungGcCount:
76       return std::make_optional(
77           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_COUNT);
78     case DatumId::kYoungGcCountDelta:
79       return std::make_optional(
80           statsd::
81               ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_COUNT);
82     case DatumId::kFullGcCount:
83       return std::make_optional(
84           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_COUNT);
85     case DatumId::kFullGcCountDelta:
86       return std::make_optional(
87           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_COUNT);
88     case DatumId::kTotalBytesAllocated:
89       return std::make_optional(
90           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_TOTAL_BYTES_ALLOCATED);
91     case DatumId::kTotalBytesAllocatedDelta:
92       return std::make_optional(
93           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_TOTAL_BYTES_ALLOCATED);
94     case DatumId::kYoungGcCollectionTime:
95       return std::make_optional(
96           statsd::
97               ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_TIME_HISTO_MILLIS);
98     case DatumId::kFullGcCollectionTime:
99       return std::make_optional(
100           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_TIME_HISTO_MILLIS);
101     case DatumId::kYoungGcThroughput:
102       return std::make_optional(
103           statsd::
104               ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_THROUGHPUT_HISTO_MB_PER_SEC);
105     case DatumId::kFullGcThroughput:
106       return std::make_optional(
107           statsd::
108               ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_THROUGHPUT_HISTO_MB_PER_SEC);
109     case DatumId::kJitMethodCompileCount:
110       return std::make_optional(
111           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_JIT_METHOD_COMPILE_COUNT);
112     case DatumId::kJitMethodCompileCountDelta:
113       return std::make_optional(
114           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_JIT_METHOD_COMPILE_COUNT);
115     case DatumId::kYoungGcTracingThroughput:
116       return std::make_optional(
117           statsd::
118               ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_TRACING_THROUGHPUT_HISTO_MB_PER_SEC);
119     case DatumId::kFullGcTracingThroughput:
120       return std::make_optional(
121           statsd::
122               ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_TRACING_THROUGHPUT_HISTO_MB_PER_SEC);
123     case DatumId::kTotalGcCollectionTime:
124       return std::make_optional(
125           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_TOTAL_COLLECTION_TIME_MS);
126     case DatumId::kTotalGcCollectionTimeDelta:
127       return std::make_optional(
128           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_TOTAL_COLLECTION_TIME_MS);
129     case DatumId::kYoungGcThroughputAvg:
130       return std::make_optional(
131           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_THROUGHPUT_AVG_MB_PER_SEC);
132     case DatumId::kFullGcThroughputAvg:
133       return std::make_optional(
134           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_THROUGHPUT_AVG_MB_PER_SEC);
135     case DatumId::kYoungGcTracingThroughputAvg:
136       return std::make_optional(
137           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_TRACING_THROUGHPUT_AVG_MB_PER_SEC);
138     case DatumId::kFullGcTracingThroughputAvg:
139       return std::make_optional(
140           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_TRACING_THROUGHPUT_AVG_MB_PER_SEC);
141     case DatumId::kGcWorldStopTime:
142       return std::make_optional(
143           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_TIME_US);
144     case DatumId::kGcWorldStopTimeDelta:
145       return std::make_optional(
146           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_WORLD_STOP_TIME_US);
147     case DatumId::kGcWorldStopCount:
148       return std::make_optional(
149           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_WORLD_STOP_COUNT);
150     case DatumId::kGcWorldStopCountDelta:
151       return std::make_optional(
152           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_WORLD_STOP_COUNT);
153     case DatumId::kYoungGcScannedBytes:
154       return std::make_optional(
155           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_SCANNED_BYTES);
156     case DatumId::kYoungGcScannedBytesDelta:
157       return std::make_optional(
158           statsd::
159               ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_SCANNED_BYTES);
160     case DatumId::kYoungGcFreedBytes:
161       return std::make_optional(
162           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_FREED_BYTES);
163     case DatumId::kYoungGcFreedBytesDelta:
164       return std::make_optional(
165           statsd::
166               ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_FREED_BYTES);
167     case DatumId::kYoungGcDuration:
168       return std::make_optional(
169           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_YOUNG_GENERATION_COLLECTION_DURATION_MS);
170     case DatumId::kYoungGcDurationDelta:
171       return std::make_optional(
172           statsd::
173               ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_YOUNG_GENERATION_COLLECTION_DURATION_MS);
174     case DatumId::kFullGcScannedBytes:
175       return std::make_optional(
176           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_SCANNED_BYTES);
177     case DatumId::kFullGcScannedBytesDelta:
178       return std::make_optional(
179           statsd::
180               ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_SCANNED_BYTES);
181     case DatumId::kFullGcFreedBytes:
182       return std::make_optional(
183           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_FREED_BYTES);
184     case DatumId::kFullGcFreedBytesDelta:
185       return std::make_optional(
186           statsd::
187               ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_FREED_BYTES);
188     case DatumId::kFullGcDuration:
189       return std::make_optional(
190           statsd::ART_DATUM_REPORTED__KIND__ART_DATUM_GC_FULL_HEAP_COLLECTION_DURATION_MS);
191     case DatumId::kFullGcDurationDelta:
192       return std::make_optional(
193           statsd::
194               ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_GC_FULL_HEAP_COLLECTION_DURATION_MS);
195     case DatumId::kTimeElapsedDelta:
196       return std::make_optional(
197           statsd::ART_DATUM_DELTA_REPORTED__KIND__ART_DATUM_DELTA_TIME_ELAPSED_MS);
198   }
199 }
200 
EncodeCompileFilter(CompilerFilterReporting filter)201 constexpr int32_t EncodeCompileFilter(CompilerFilterReporting filter) {
202   switch (filter) {
203     case CompilerFilterReporting::kAssumeVerified:
204       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_ASSUMED_VERIFIED;
205     case CompilerFilterReporting::kExtract:
206       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EXTRACT;
207     case CompilerFilterReporting::kVerify:
208       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_VERIFY;
209     case CompilerFilterReporting::kSpaceProfile:
210       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPACE_PROFILE;
211     case CompilerFilterReporting::kSpace:
212       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPACE;
213     case CompilerFilterReporting::kSpeedProfile:
214       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPEED_PROFILE;
215     case CompilerFilterReporting::kSpeed:
216       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPEED;
217     case CompilerFilterReporting::kEverythingProfile:
218       return statsd::
219           ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EVERYTHING_PROFILE;
220     case CompilerFilterReporting::kEverything:
221       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EVERYTHING;
222     case CompilerFilterReporting::kError:
223       return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_ERROR;
224     case CompilerFilterReporting::kUnknown:
225        return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_UNKNOWN;
226     case CompilerFilterReporting::kRunFromApk:
227        return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK;
228     case CompilerFilterReporting::kRunFromApkFallback:
229        return statsd::ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK;
230   }
231 }
232 
EncodeCompilationReason(CompilationReason reason)233 constexpr int32_t EncodeCompilationReason(CompilationReason reason) {
234   switch (reason) {
235     case CompilationReason::kUnknown:
236       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_UNKNOWN;
237     case CompilationReason::kABOTA:
238       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_AB_OTA;
239     case CompilationReason::kBgDexopt:
240       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BG_DEXOPT;
241     case CompilationReason::kError:
242       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_ERROR;
243     case CompilationReason::kFirstBoot:
244       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_FIRST_BOOT;
245     case CompilationReason::kInactive:
246       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INACTIVE;
247     case CompilationReason::kInstall:
248       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL;
249     case CompilationReason::kInstallWithDexMetadata:
250       return statsd::
251           ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA;
252     case CompilationReason::kShared:
253       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_SHARED;
254     case CompilationReason::kPostBoot:
255       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_POST_BOOT;
256     case CompilationReason::kInstallBulk:
257       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK;
258     case CompilationReason::kInstallBulkSecondary:
259       return statsd::
260           ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY;
261     case CompilationReason::kInstallBulkDowngraded:
262       return statsd::
263           ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED;
264     case CompilationReason::kInstallBulkSecondaryDowngraded:
265       return statsd::
266           ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED;
267     case CompilationReason::kBootAfterOTA:
268       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BOOT_AFTER_OTA;
269     case CompilationReason::kInstallFast:
270       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_FAST;
271     case CompilationReason::kPrebuilt:
272       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_PREBUILT;
273     case CompilationReason::kCmdLine:
274       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_CMDLINE;
275     case CompilationReason::kVdex:
276       return statsd::ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_VDEX;
277     case CompilationReason::kBootAfterMainlineUpdate:
278       return statsd::
279           ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BOOT_AFTER_MAINLINE_UPDATE;
280   }
281 }
282 
EncodeInstructionSet(InstructionSet isa)283 constexpr int32_t EncodeInstructionSet(InstructionSet isa) {
284   switch (isa) {
285     case InstructionSet::kArm:
286       // Fall-through.
287     case InstructionSet::kThumb2:
288       return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM;
289     case InstructionSet::kArm64:
290       return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM64;
291     case InstructionSet::kRiscv64:
292       return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_RISCV64;
293     case InstructionSet::kX86:
294       return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_X86;
295     case InstructionSet::kX86_64:
296       return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_X86_64;
297     case InstructionSet::kNone:
298       return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_UNKNOWN;
299   }
300 }
301 
EncodeGcCollectorType(gc::CollectorType collector_type)302 constexpr int32_t EncodeGcCollectorType(gc::CollectorType collector_type) {
303   switch (collector_type) {
304     case gc::CollectorType::kCollectorTypeMS:
305       return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_MARK_SWEEP;
306     case gc::CollectorType::kCollectorTypeCMS:
307       return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_MARK_SWEEP;
308     case gc::CollectorType::kCollectorTypeCMC:
309       return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_MARK_COMPACT;
310     case gc::CollectorType::kCollectorTypeCMCBackground:
311       return statsd::
312           ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_MARK_COMPACT_BACKGROUND;
313     case gc::CollectorType::kCollectorTypeSS:
314       return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_SEMI_SPACE;
315     case gc::kCollectorTypeCC:
316       return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_COPYING;
317     case gc::kCollectorTypeCCBackground:
318       return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_CONCURRENT_COPYING_BACKGROUND;
319     case gc::kCollectorTypeNone:
320     case gc::kCollectorTypeInstrumentation:
321     case gc::kCollectorTypeAddRemoveAppImageSpace:
322     case gc::kCollectorTypeDebugger:
323     case gc::kCollectorTypeHomogeneousSpaceCompact:
324     case gc::kCollectorTypeClassLinker:
325     case gc::kCollectorTypeJitCodeCache:
326     case gc::kCollectorTypeHprof:
327     case gc::kCollectorTypeAddRemoveSystemWeakHolder:
328     case gc::kCollectorTypeGetObjectsAllocated:
329     case gc::kCollectorTypeCriticalSection:
330     case gc::kCollectorTypeHeapTrim:
331       return statsd::ART_DATUM_REPORTED__GC__ART_GC_COLLECTOR_TYPE_UNKNOWN;
332   }
333 }
334 
EncodeUffdMinorFaultSupport()335 int32_t EncodeUffdMinorFaultSupport() {
336   auto [uffd_supported, minor_fault_supported] = gc::collector::MarkCompact::GetUffdAndMinorFault();
337 
338   if (uffd_supported) {
339     if (minor_fault_supported) {
340       return statsd::ART_DATUM_REPORTED__UFFD_SUPPORT__ART_UFFD_SUPPORT_MINOR_FAULT_MODE_SUPPORTED;
341     } else {
342       return statsd::
343           ART_DATUM_REPORTED__UFFD_SUPPORT__ART_UFFD_SUPPORT_MINOR_FAULT_MODE_NOT_SUPPORTED;
344     }
345   } else {
346     return statsd::ART_DATUM_REPORTED__UFFD_SUPPORT__ART_UFFD_SUPPORT_UFFD_NOT_SUPPORTED;
347   }
348 }
349 
350 class StatsdBackend : public MetricsBackend {
351  public:
BeginOrUpdateSession(const SessionData & session_data)352   void BeginOrUpdateSession(const SessionData& session_data) override {
353     session_data_ = session_data;
354   }
355 
356  protected:
BeginReport(uint64_t timestamp_since_start_ms)357   void BeginReport(uint64_t timestamp_since_start_ms) override {
358     current_timestamp_ = static_cast<int64_t>(timestamp_since_start_ms);
359   }
360 
ReportCounter(DatumId counter_type,uint64_t value)361   void ReportCounter(DatumId counter_type, uint64_t value) override {
362     std::optional<int32_t> datum_id = EncodeDatumId(counter_type);
363     if (!datum_id.has_value()) {
364       return;
365     }
366 
367     int32_t atom;
368     switch (counter_type) {
369 #define EVENT_METRIC_CASE(name, ...) case DatumId::k##name:
370       ART_EVENT_METRICS(EVENT_METRIC_CASE)
371 #undef EVENT_METRIC_CASE
372       atom = statsd::ART_DATUM_REPORTED;
373       break;
374 
375 #define VALUE_METRIC_CASE(name, type, ...) case DatumId::k##name:
376       ART_VALUE_METRICS(VALUE_METRIC_CASE)
377 #undef VALUE_METRIC_CASE
378       atom = statsd::ART_DATUM_DELTA_REPORTED;
379       break;
380     }
381 
382     statsd::stats_write(
383         atom,
384         session_data_.session_id,
385         session_data_.uid,
386         EncodeCompileFilter(session_data_.compiler_filter),
387         EncodeCompilationReason(session_data_.compilation_reason),
388         current_timestamp_,
389         0,  // deprecated - was ArtThreadType
390         datum_id.value(),
391         static_cast<int64_t>(value),
392         0,  // deprecated - was ArtDexMetadataType
393         0,  // deprecated - was ArtApkType
394         EncodeInstructionSet(kRuntimeISA),
395         EncodeGcCollectorType(Runtime::Current()->GetHeap()->GetForegroundCollectorType()),
396         EncodeUffdMinorFaultSupport());
397   }
398 
ReportHistogram(DatumId,int64_t,int64_t,const std::vector<uint32_t> &)399   void ReportHistogram(DatumId /*histogram_type*/,
400                        int64_t /*low_value*/,
401                        int64_t /*high_value*/,
402                        const std::vector<uint32_t>& /*buckets*/) override {
403     // TODO: implement this once ArtDatumReported in atoms.proto supports histograms.
404     LOG_STREAM(DEBUG) << "Attempting to write histogram to statsd. This is not supported yet.";
405   }
406 
EndReport()407   void EndReport() override {}
408 
409  private:
410   SessionData session_data_;
411   // The timestamp provided to the last call to BeginReport
412   int64_t current_timestamp_;
413 };
414 
415 }  // namespace
416 
CreateStatsdBackend()417 std::unique_ptr<MetricsBackend> CreateStatsdBackend() { return std::make_unique<StatsdBackend>(); }
418 
DeviceStatusCallback(int32_t atom_tag,AStatsEventList * data,void * cookie)419 AStatsManager_PullAtomCallbackReturn DeviceStatusCallback(int32_t atom_tag,
420                                                           AStatsEventList* data,
421                                                           [[maybe_unused]] void* cookie) {
422   if (atom_tag == statsd::ART_DEVICE_STATUS) {
423     Runtime* runtime = Runtime::Current();
424     int32_t boot_image_status;
425     if (runtime->GetHeap()->HasBootImageSpace() && !runtime->HasImageWithProfile()) {
426       boot_image_status = statsd::ART_DEVICE_DATUM_REPORTED__BOOT_IMAGE_STATUS__STATUS_FULL;
427     } else if (runtime->GetHeap()->HasBootImageSpace() &&
428                runtime->GetHeap()->GetBootImageSpaces()[0]->GetProfileFiles().empty()) {
429       boot_image_status = statsd::ART_DEVICE_DATUM_REPORTED__BOOT_IMAGE_STATUS__STATUS_MINIMAL;
430     } else {
431       boot_image_status = statsd::ART_DEVICE_DATUM_REPORTED__BOOT_IMAGE_STATUS__STATUS_NONE;
432     }
433     statsd::addAStatsEvent(data, atom_tag, boot_image_status);
434     return AStatsManager_PULL_SUCCESS;
435   }
436 
437   return AStatsManager_PULL_SKIP;
438 }
439 
SetupCallbackForDeviceStatus()440 void SetupCallbackForDeviceStatus() {
441   AStatsManager_setPullAtomCallback(
442       statsd::ART_DEVICE_STATUS, /*metadata=*/nullptr, DeviceStatusCallback, /*cookie=*/nullptr);
443 }
444 
445 }  // namespace metrics
446 }  // namespace art
447 
448 #pragma clang diagnostic pop  // -Wconversion
449