• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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_TRACED_PROBES_ANDROID_LOG_ANDROID_LOG_DATA_SOURCE_H_
18 #define SRC_TRACED_PROBES_ANDROID_LOG_ANDROID_LOG_DATA_SOURCE_H_
19 
20 #include <unordered_map>
21 #include <unordered_set>
22 #include <vector>
23 
24 #include "perfetto/base/paged_memory.h"
25 #include "perfetto/base/scoped_file.h"
26 #include "perfetto/base/string_view.h"
27 #include "perfetto/base/unix_socket.h"
28 #include "perfetto/base/weak_ptr.h"
29 #include "src/traced/probes/probes_data_source.h"
30 
31 namespace perfetto {
32 
33 class DataSourceConfig;
34 class TraceWriter;
35 namespace base {
36 class TaskRunner;
37 }
38 
39 namespace protos {
40 namespace pbzero {
41 class AndroidLogPacket;
42 class AndroidLogPacket_LogEvent;
43 }  // namespace pbzero
44 }  // namespace protos
45 
46 class AndroidLogDataSource : public ProbesDataSource {
47  public:
48   struct Stats {
49     uint64_t num_total = 0;    // Total number of log entries received.
50     uint64_t num_failed = 0;   // Parser failures.
51     uint64_t num_skipped = 0;  // Messages skipped due to filters.
52   };
53 
54   // One EventFormat == one line of /system/etc/event-log-tags.
55   struct EventFormat {
56     std::string name;
57     std::vector<std::string> fields;
58   };
59   static constexpr int kTypeId = 6;
60 
61   AndroidLogDataSource(DataSourceConfig,
62                        base::TaskRunner*,
63                        TracingSessionID,
64                        std::unique_ptr<TraceWriter> writer);
65 
66   ~AndroidLogDataSource() override;
67 
68   // ProbesDataSource implementation.
69   void Start() override;
70   void Flush(FlushRequestID, std::function<void()> callback) override;
71 
72   // Reads the contents of /system/etc/event-log-tags. Virtual for testing.
73   virtual std::string ReadEventLogDefinitions();
74 
75   // Connects to the /dev/socket/logdr socket. Virtual for testing.
76   virtual base::UnixSocketRaw ConnectLogdrSocket();
77 
78   // Parses the contents of ReadEventLogDefinitions().
79   void ParseEventLogDefinitions();
80 
81   const EventFormat* GetEventFormat(int id) const;
stats()82   const Stats& stats() const { return stats_; }
83   base::WeakPtr<AndroidLogDataSource> GetWeakPtr() const;
84 
85  private:
86   void EnableSocketWatchTask(bool);
87   void OnSocketDataAvailable();
88   void ReadLogSocket();
89 
90   // Parses one line of /system/etc/event-log-tags.
91   bool ParseEventLogDefinitionLine(char* line, size_t len);
92 
93   // Parses a textual (i.e. tag + message) event, which is the majority of
94   // log events. All buffers but the LID_EVENTS contain text events.
95   // If parsing fails returns false and leaves the |out_evt| field unset.
96   // If parsing succeeds returns true and:
97   // - If the event is skipped due to filters, |out_evt| is left unset.
98   // - If a new event is aded to the packet, |out_evt| is set to that.
99   bool ParseTextEvent(const char* start,
100                       const char* end,
101                       protos::pbzero::AndroidLogPacket* packet,
102                       protos::pbzero::AndroidLogPacket_LogEvent** out_evt);
103 
104   // Parses a binary event from the "events" buffer.
105   // If parsing fails returns false and leaves the |out_evt| field unset.
106   // If parsing succeeds returns true and:
107   // - If the event is skipped due to filters, |out_evt| is left unset.
108   // - If a new event is aded to the packet, |out_evt| is set to that.
109   bool ParseBinaryEvent(const char* start,
110                         const char* end,
111                         protos::pbzero::AndroidLogPacket* packet,
112                         protos::pbzero::AndroidLogPacket_LogEvent** out_evt);
113 
114   base::TaskRunner* const task_runner_;
115   std::unique_ptr<TraceWriter> writer_;
116   base::UnixSocketRaw logdr_sock_;
117 
118   // Config parameters coming from the data source section in the trace config.
119   int min_prio_ = 0;
120   std::string mode_;
121 
122   // For filtering events based on tags.
123   std::unordered_set<base::StringView> filter_tags_;
124   std::vector<char> filter_tags_strbuf_;
125 
126   // Lookup map for binary events (log_id=EVENTS). Translates a numeric id into
127   // a corresponding field descriptor. This is generated by parsing
128   // /system/etc/event-log-tags when starting.
129   std::unordered_map<int, EventFormat> event_formats_;
130 
131   // Buffer used for parsing. It's safer (read: fails sooner) than using the
132   // stack, due to red zones around the boundaries.
133   base::PagedMemory buf_;
134   Stats stats_;
135   bool fd_watch_task_enabled_ = false;
136 
137   base::WeakPtrFactory<AndroidLogDataSource> weak_factory_;  // Keep last.
138 };
139 
140 }  // namespace perfetto
141 
142 #endif  // SRC_TRACED_PROBES_ANDROID_LOG_ANDROID_LOG_DATA_SOURCE_H_
143