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