• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "audit_log_parser.h"
17 #include "audit.h"
18 #include "string_util.h"
19 
20 namespace OHOS {
21 namespace HiviewDFX {
22 namespace {
23 constexpr int LOG_ELEMENT_MIN_COUNT = 3;
24 constexpr int LOG_ELEMENT_TIMESTAMP_POS = 0;
25 constexpr int LOG_ELEMENT_SERIAL_ID_POS = 1;
26 constexpr int LOG_ELEMENT_EVENT_TYPE_POS = 2;
27 constexpr int LOG_ELEMENT_NORMAL_EVENT_SENDER_POS = 3;
28 constexpr int LOG_ELEMENT_NORMAL_EVENT_PROCESSOR_POS = 4;
29 constexpr int LOG_ELEMENT_NORMAL_EVENT_THREAD_POS = 5;
30 constexpr int LOG_ELEMENT_NORMAL_EVENT_DIGEST_POS = 6;
31 constexpr int LOG_ELEMENT_PIPE_EVENT_CREATOR_POS = 3;
32 constexpr int LOG_ELEMENT_PIPE_EVENT_DIGEST_POS = 4;
33 constexpr int LOG_ELEMENT_PIPE_EVENT_PROCESSOR_POS = 3;
34 constexpr int LOG_ELEMENT_PIPE_EVENT_THREAD_POS = 3;
35 constexpr int LOG_ELEMENT_PIPE_EVENT_PIPELINE_POS = 3;
36 constexpr int QUEUE_EVENT_IN_ELEMENT_SIZE = 7;
37 constexpr int QUEUE_EVENT_OUT_ELEMENT_SIZE = 3;
38 constexpr int PIPELINE_EVENT_CREATE_ELEMENT_SIZE = 5;
39 constexpr int PIPELINE_EVENT_HANDLE_IN_ELEMENT_SIZE = 4;
40 constexpr int PIPELINE_EVENT_HANDLE_OUT_ELEMENT_SIZE = 4;
41 constexpr int PIPELINE_EVENT_DONE_ELEMENT_SIZE = 4;
42 
CreateEventInfo(uint64_t serialId,const std::string & digest,const std::vector<std::string> & eventElements)43 AuditLogParser::EventInfo CreateEventInfo(uint64_t serialId, const std::string& digest,
44                                           const std::vector<std::string>& eventElements)
45 {
46     AuditLogParser::EventInfo info;
47     info.isPipelineEvent = true;
48     info.eventSerialId = serialId;
49     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.inTime);
50     info.processor = eventElements[LOG_ELEMENT_PIPE_EVENT_PROCESSOR_POS];
51     info.digest = digest;
52     return info;
53 }
54 
SplitStr(const std::string & log)55 std::vector<std::string> SplitStr(const std::string& log)
56 {
57     std::vector<std::string> elements;
58     std::string sep(1, Audit::DOMAIN_DELIMITER);
59     StringUtil::SplitStr(log, sep, elements);
60     return elements;
61 }
62 } // namespace
63 
StartParse()64 void AuditLogParser::StartParse()
65 {
66     std::list<std::string> logList;
67     if (!Audit::GetAuditLog(true, logList)) {
68         return;
69     }
70 
71     ParseTimeScope(logList);
72     for (auto& log : logList) {
73         auto elements = SplitStr(log);
74         if (elements.size() < LOG_ELEMENT_MIN_COUNT) {
75             continue;
76         }
77 
78         int eventType = -1;
79         StringUtil::ConvertStringTo<int>(elements[LOG_ELEMENT_EVENT_TYPE_POS], eventType);
80         if (std::to_string(eventType) != elements[LOG_ELEMENT_EVENT_TYPE_POS]) {
81             eventType = -1;
82         }
83         if (eventType < Audit::StatsEvent::QUEUE_EVENT_IN) {
84             continue;
85         }
86 
87         if (eventType <= Audit::StatsEvent::QUEUE_EVENT_OUT) {
88             ParseNormalAuditEvent(eventType, elements);
89         } else if (eventType <= Audit::StatsEvent::PIPELINE_EVENT_DONE) {
90             ParsePipelineAuditEvent(eventType, elements);
91         }
92     }
93 }
94 
GetThreadSummary(const std::string & name)95 std::list<std::string> AuditLogParser::GetThreadSummary(const std::string& name)
96 {
97     std::list<std::string> ret;
98     std::string pid = name;
99     auto pos = pid.find("@");
100     if (pos != std::string::npos) {
101         pid = pid.substr(pos + 1);
102     }
103 
104     for (auto& event : eventList_) {
105         if (event.threadNameOrTid.find(pid) != std::string::npos) {
106             ret.push_back(event.ToString());
107         }
108     }
109 
110     for (auto& pipeEvent : pipelineEventList_) {
111         for (auto& chainEvent : pipeEvent.processChain) {
112             if (chainEvent.threadNameOrTid.find(pid) != std::string::npos) {
113                 ret.push_back(chainEvent.ToString());
114             }
115         }
116     }
117     return ret;
118 }
119 
GetPluginSummary(const std::string & name)120 std::list<std::string> AuditLogParser::GetPluginSummary(const std::string& name)
121 {
122     std::list<std::string> ret;
123     for (auto& event : eventList_) {
124         if (event.processor.find(name) != std::string::npos) {
125             ret.push_back(event.ToString());
126         }
127     }
128 
129     for (auto& pipeEvent : pipelineEventList_) {
130         for (auto& chainEvent : pipeEvent.processChain) {
131             if (chainEvent.processor.find(name) != std::string::npos) {
132                 ret.push_back(chainEvent.ToString());
133             }
134         }
135     }
136     return ret;
137 }
138 
GetPipelineSummary(const std::string & name)139 std::list<std::string> AuditLogParser::GetPipelineSummary(const std::string& name)
140 {
141     std::list<std::string> ret;
142     for (auto& pipeEvent : pipelineEventList_) {
143         if (pipeEvent.pipeline.find(name) != std::string::npos) {
144             ret.push_back(pipeEvent.ToString());
145         }
146     }
147     return ret;
148 }
149 
GetAuditLogTimeScope()150 std::string AuditLogParser::GetAuditLogTimeScope()
151 {
152     return "Audit Logs From " + std::to_string(logStartTime_) + " to " + std::to_string(logEndTime_);
153 }
154 
ParseTimeScope(const std::list<std::string> & logList)155 void AuditLogParser::ParseTimeScope(const std::list<std::string>& logList)
156 {
157     if (logList.empty()) {
158         return;
159     }
160 
161     auto beginLog = SplitStr(*(logList.begin()));
162     StringUtil::ConvertStringTo<uint64_t>(beginLog[LOG_ELEMENT_TIMESTAMP_POS], logStartTime_);
163     auto endLog = SplitStr(*(logList.rbegin()));
164     StringUtil::ConvertStringTo<uint64_t>(endLog[LOG_ELEMENT_TIMESTAMP_POS], logEndTime_);
165 }
166 
ParseNormalAuditEvent(int eventType,const std::vector<std::string> & eventElements)167 void AuditLogParser::ParseNormalAuditEvent(int eventType, const std::vector<std::string>& eventElements)
168 {
169     if (eventType == Audit::StatsEvent::QUEUE_EVENT_IN && eventElements.size() >= QUEUE_EVENT_IN_ELEMENT_SIZE) {
170         ParseNormalEnqueueEvent(eventElements);
171         return;
172     }
173 
174     if (eventType == Audit::StatsEvent::QUEUE_EVENT_OUT && eventElements.size() >= QUEUE_EVENT_OUT_ELEMENT_SIZE) {
175         ParseNormalDequeueEvent(eventElements);
176     }
177 }
178 
ParseNormalEnqueueEvent(const std::vector<std::string> & eventElements)179 void AuditLogParser::ParseNormalEnqueueEvent(const std::vector<std::string>& eventElements)
180 {
181     EventInfo info;
182     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.inTime);
183     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], info.eventSerialId);
184     info.sender = eventElements[LOG_ELEMENT_NORMAL_EVENT_SENDER_POS];
185     info.processor = eventElements[LOG_ELEMENT_NORMAL_EVENT_PROCESSOR_POS];
186     info.threadNameOrTid = eventElements[LOG_ELEMENT_NORMAL_EVENT_THREAD_POS];
187     info.digest = eventElements[LOG_ELEMENT_NORMAL_EVENT_DIGEST_POS];
188     eventList_.push_back(std::move(info));
189 }
190 
ParseNormalDequeueEvent(const std::vector<std::string> & eventElements)191 void AuditLogParser::ParseNormalDequeueEvent(const std::vector<std::string>& eventElements)
192 {
193     uint64_t eventSerialId = 0;
194     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
195     for (auto rit = eventList_.rbegin(); rit != eventList_.rend(); ++rit) {
196         if (rit->eventSerialId == eventSerialId) {
197             StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], rit->outTime);
198             return;
199         }
200     }
201 }
202 
ParsePipelineAuditEvent(int eventType,const std::vector<std::string> & eventElements)203 void AuditLogParser::ParsePipelineAuditEvent(int eventType, const std::vector<std::string>& eventElements)
204 {
205     if (eventType == Audit::StatsEvent::PIPELINE_EVENT_CREATE &&
206         eventElements.size() >= PIPELINE_EVENT_CREATE_ELEMENT_SIZE) {
207         ParsePipelineCreateEvent(eventElements);
208         return;
209     }
210 
211     if (eventType == Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN &&
212         eventElements.size() >= PIPELINE_EVENT_HANDLE_IN_ELEMENT_SIZE) {
213         ParsePipelineHandleInEvent(eventElements);
214         return;
215     }
216 
217     if (eventType == Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT &&
218         eventElements.size() >= PIPELINE_EVENT_HANDLE_OUT_ELEMENT_SIZE) {
219         ParsePipelineHandleOutEvent(eventElements);
220         return;
221     }
222 
223     if (eventType == Audit::StatsEvent::PIPELINE_EVENT_DONE &&
224         eventElements.size() >= PIPELINE_EVENT_DONE_ELEMENT_SIZE) {
225         ParsePipelineDoneEvent(eventElements);
226         return;
227     }
228 }
229 
ParsePipelineCreateEvent(const std::vector<std::string> & eventElements)230 void AuditLogParser::ParsePipelineCreateEvent(const std::vector<std::string>& eventElements)
231 {
232     PipelineEventInfo info;
233     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.createTime);
234     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], info.eventSerialId);
235     info.creator = eventElements[LOG_ELEMENT_PIPE_EVENT_CREATOR_POS];
236     info.digest = eventElements[LOG_ELEMENT_PIPE_EVENT_DIGEST_POS];
237     pipelineEventList_.push_back(std::move(info));
238 }
239 
ParsePipelineHandleInEvent(const std::vector<std::string> & eventElements)240 void AuditLogParser::ParsePipelineHandleInEvent(const std::vector<std::string>& eventElements)
241 {
242     uint64_t eventSerialId = 0;
243     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
244     for (auto rit = pipelineEventList_.rbegin(); rit != pipelineEventList_.rend(); ++rit) {
245         if (rit->eventSerialId == eventSerialId) {
246             rit->processChain.push_back(CreateEventInfo(eventSerialId, rit->digest, eventElements));
247             return;
248         }
249     }
250 
251     for (auto rit = eventList_.rbegin(); rit != eventList_.rend(); ++rit) {
252         if (rit->eventSerialId == eventSerialId) {
253             PipelineEventInfo info(*rit);
254             info.processChain.push_back(CreateEventInfo(eventSerialId, info.digest, eventElements));
255             pipelineEventList_.push_back(std::move(info));
256             return;
257         }
258     }
259 }
260 
ParsePipelineHandleOutEvent(const std::vector<std::string> & eventElements)261 void AuditLogParser::ParsePipelineHandleOutEvent(const std::vector<std::string>& eventElements)
262 {
263     uint64_t eventSerialId = 0;
264     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
265     for (auto rit = pipelineEventList_.rbegin(); rit != pipelineEventList_.rend(); ++rit) {
266         if (rit->eventSerialId == eventSerialId) {
267             auto& info = rit->processChain.back();
268             StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.outTime);
269             info.threadNameOrTid = eventElements[LOG_ELEMENT_PIPE_EVENT_THREAD_POS];
270             return;
271         }
272     }
273 }
274 
ParsePipelineDoneEvent(const std::vector<std::string> & eventElements)275 void AuditLogParser::ParsePipelineDoneEvent(const std::vector<std::string>& eventElements)
276 {
277     uint64_t eventSerialId = 0;
278     StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
279     for (auto rit = pipelineEventList_.rbegin(); rit != pipelineEventList_.rend(); ++rit) {
280         if (rit->eventSerialId == eventSerialId) {
281             StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], rit->destroyTime);
282             rit->pipeline = eventElements[LOG_ELEMENT_PIPE_EVENT_PIPELINE_POS];
283             return;
284         }
285     }
286 }
287 } // namespace HiviewDFX
288 } // namespace OHOS
289