1 /* 2 * Copyright (C) 2022 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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_ANDROID_BUGREPORT_ANDROID_LOG_READER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_ANDROID_BUGREPORT_ANDROID_LOG_READER_H_ 19 20 #include <chrono> 21 #include <cstdint> 22 #include <optional> 23 24 #include "perfetto/base/status.h" 25 #include "perfetto/ext/base/string_view.h" 26 #include "src/trace_processor/importers/android_bugreport/android_log_event.h" 27 #include "src/trace_processor/importers/android_bugreport/chunked_line_reader.h" 28 29 namespace perfetto ::trace_processor { 30 31 class TraceProcessorContext; 32 33 // Helper struct to deduplicate events. 34 // When reading bug reports log data will be present in a dumpstate file and in 35 // the log cat files. 36 struct TimestampedAndroidLogEvent { 37 // Log timestamp. We use ms resolution because dumpstate files only write at 38 // this resolution. 39 std::chrono::milliseconds ts; 40 AndroidLogEvent event; 41 // Flag to track whether a given event was already matched by the 42 // deduplication logic. When set to true we will no longer consider this event 43 // as a candidate for deduplication. 44 bool matched; 45 46 // Only sort by time to find duplicates at the same ts. 47 bool operator<(const TimestampedAndroidLogEvent& other) const { 48 return ts < other.ts; 49 } 50 }; 51 52 // Parses log lines coming from persistent logcat (FS/data/misc/logd), interns 53 // string in the TP string pools and populates a vector of AndroidLogEvent 54 // structs. Does NOT insert log events into any table (for testing isolation), 55 // the caller is in charge to do that. 56 // It supports the following formats (auto-detected): 57 // 1) 12-31 23:59:00.123456 <pid> <tid> I tag: message 58 // This is typically found in persistent logcat (FS/data/misc/logd/) 59 // 2) 06-24 15:57:11.346 <uid> <pid> <tid> D Tag: Message 60 // This is typically found in the recent logcat dump in bugreport-xxx.txt 61 class AndroidLogReader : public ChunkedLineReader { 62 public: 63 // Log cat will not write year into the trace so the caller needs to figure it 64 // out. If not provided the reader will make a best guess. 65 explicit AndroidLogReader(TraceProcessorContext* context); 66 AndroidLogReader(TraceProcessorContext* context, 67 int32_t year, 68 bool wait_for_tz = false); 69 70 ~AndroidLogReader() override; 71 72 base::Status ParseLine(base::StringView line) override; 73 void EndOfStream(base::StringView leftovers) override; 74 75 // Called for each event parsed from the stream. 76 // `event_ts_ns` is the ts of the event as read from the log. 77 // Default implementation just calls `SendToSorter`. 78 virtual base::Status ProcessEvent(std::chrono::nanoseconds event_ts, 79 AndroidLogEvent event); 80 81 protected: 82 // Sends the given event to the sorting stage. 83 // `event_ts` is the ts of the event as read from the log and will be 84 // converted to a trace_ts (with necessary clock conversions applied) 85 base::Status SendToSorter(std::chrono::nanoseconds event_ts, 86 AndroidLogEvent event); 87 88 // Send any events to the sorter that have not already had their timestamp 89 // adjusted based on the timezone. This is meant to be called once the TZ 90 // offset becomes known, or we reach the end of the input without any TZ info. 91 base::Status FlushNonTzAdjustedEvents(); 92 93 private: 94 TraceProcessorContext* const context_; 95 std::optional<AndroidLogEvent::Format> format_; 96 int32_t year_; 97 bool wait_for_tz_; 98 std::vector<TimestampedAndroidLogEvent> non_tz_adjusted_events_; 99 }; 100 101 // Same as AndroidLogReader (sends events to sorter), but also stores them in a 102 // vector that can later be feed to a `DedupingAndroidLogReader` instance. 103 class BufferingAndroidLogReader : public AndroidLogReader { 104 public: 105 BufferingAndroidLogReader(TraceProcessorContext* context, 106 int32_t year, 107 bool wait_for_tz = false) AndroidLogReader(context,year,wait_for_tz)108 : AndroidLogReader(context, year, wait_for_tz) {} 109 ~BufferingAndroidLogReader() override; 110 111 base::Status ProcessEvent(std::chrono::nanoseconds event_ts, 112 AndroidLogEvent event) override; 113 ConsumeBufferedEvents()114 std::vector<TimestampedAndroidLogEvent> ConsumeBufferedEvents() && { 115 return std::move(events_); 116 } 117 118 private: 119 std::vector<TimestampedAndroidLogEvent> events_; 120 }; 121 122 // Similar to `AndroidLogReader` but this class will not forward duplicate 123 // events. These are events already present in a given vector of events. 124 class DedupingAndroidLogReader : public AndroidLogReader { 125 public: 126 // Creates a reader that will not forward events already present in the given 127 // vector. Note that entries in the vector will only be matched once. That is 128 // when a match is found in the vector the event is not send to the sorter, 129 // but the event is removed from the vector (seen flag is set to true) so that 130 // subsequent event will not match that entry. 131 DedupingAndroidLogReader(TraceProcessorContext* context, 132 int32_t year, 133 bool wait_for_tz, 134 std::vector<TimestampedAndroidLogEvent> events); DedupingAndroidLogReader(TraceProcessorContext * context,int32_t year,std::vector<TimestampedAndroidLogEvent> events)135 DedupingAndroidLogReader(TraceProcessorContext* context, 136 int32_t year, 137 std::vector<TimestampedAndroidLogEvent> events) 138 : DedupingAndroidLogReader(context, year, false, events) {} 139 ~DedupingAndroidLogReader() override; 140 141 base::Status ProcessEvent(std::chrono::nanoseconds event_ts, 142 AndroidLogEvent event) override; 143 144 private: 145 std::vector<TimestampedAndroidLogEvent> events_; 146 }; 147 148 } // namespace perfetto::trace_processor 149 150 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_ANDROID_BUGREPORT_ANDROID_LOG_READER_H_ 151