1 // Copyright (C) 2021 The Android Open Source Project 2 // Copyright (C) 2021 Google Inc. 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 #pragma once 16 17 #include <inttypes.h> 18 19 #include <memory> 20 #include <optional> 21 #include <string> 22 #include <thread> 23 #include <unordered_map> 24 #include <variant> 25 26 #include "aemu/base/threads/Thread.h" 27 28 // Library to log metrics. 29 namespace android { 30 namespace base { 31 32 // Struct for hanging events 33 struct EventHangMetadata { 34 const char* file; 35 const char* function; 36 const char* msg; 37 const int line; 38 const unsigned long threadId; 39 // Field for adding custom key value annotations 40 using HangAnnotations = std::unordered_map<std::string, std::string>; 41 // Field for adding custom key value annotations 42 std::unique_ptr<HangAnnotations> data; 43 44 enum class HangType { kRenderThread, kSyncThread, kOther }; 45 HangType hangType; 46 EventHangMetadataEventHangMetadata47 EventHangMetadata(const char* file, const char* function, const char* msg, int line, 48 HangType hangType, std::unique_ptr<HangAnnotations> data) 49 : file(file), 50 function(function), 51 msg(msg), 52 line(line), 53 threadId(getCurrentThreadId()), 54 data(std::move(data)), 55 hangType(hangType) {} 56 EventHangMetadataEventHangMetadata57 EventHangMetadata() 58 : EventHangMetadata(nullptr, nullptr, nullptr, 0, HangType::kRenderThread, nullptr) {} 59 mergeAnnotationsEventHangMetadata60 void mergeAnnotations(std::unique_ptr<HangAnnotations> annotations) { 61 if (!data) { 62 data = std::make_unique<HangAnnotations>(); 63 } 64 data->merge(*annotations); 65 } 66 }; 67 68 // Events that can be logged. 69 struct MetricEventBadPacketLength { 70 int64_t len; 71 }; 72 struct MetricEventDuplicateSequenceNum { 73 int64_t opcode; 74 }; 75 struct MetricEventFreeze {}; 76 struct MetricEventUnFreeze { int64_t frozen_ms; }; 77 struct MetricEventHang { 78 uint64_t taskId; /* From HealthMonitor */ 79 EventHangMetadata* metadata; 80 int64_t otherHungTasks; 81 }; 82 struct MetricEventUnHang { 83 uint64_t taskId; /* From HealthMonitor */ 84 EventHangMetadata* metadata; 85 int64_t hung_ms; 86 int64_t otherHungTasks; 87 }; 88 struct GfxstreamVkAbort { 89 const char* file; 90 const char* function; 91 const char* msg; 92 int line; 93 int64_t abort_reason; 94 }; 95 struct MetricEventVulkanOutOfMemory { 96 int64_t vkResultCode; 97 std::optional<uint32_t> opCode = std::nullopt; 98 const char* function = nullptr; 99 std::optional<int> line = std::nullopt; 100 std::optional<uint64_t> allocationSize = std::nullopt; 101 }; 102 103 using MetricEventType = 104 std::variant<std::monostate, MetricEventBadPacketLength, MetricEventDuplicateSequenceNum, 105 MetricEventFreeze, MetricEventUnFreeze, MetricEventHang, MetricEventUnHang, 106 MetricEventVulkanOutOfMemory, GfxstreamVkAbort>; 107 108 class MetricsLogger { 109 public: 110 // Log a MetricEventType. 111 virtual void logMetricEvent(MetricEventType eventType) = 0; 112 // Set a crash annotation. 113 virtual void setCrashAnnotation(const char* key, const char* value) = 0; 114 // Virtual destructor. 115 virtual ~MetricsLogger() = default; 116 117 // Callbacks to log events 118 static void (*add_instant_event_callback)(int64_t event_code); 119 static void (*add_instant_event_with_descriptor_callback)(int64_t event_code, 120 int64_t descriptor); 121 static void (*add_instant_event_with_metric_callback)(int64_t event_code, int64_t metric_value); 122 static void (*add_vulkan_out_of_memory_event)(int64_t result_code, uint32_t op_code, 123 const char* function, uint32_t line, 124 uint64_t allocation_size, 125 bool is_host_side_result, bool is_allocation); 126 // Crashpad will copy the strings, so these need only persist for the function call 127 static void (*set_crash_annotation_callback)(const char* key, const char* value); 128 }; 129 130 std::unique_ptr<MetricsLogger> CreateMetricsLogger(); 131 132 } // namespace base 133 } // namespace android