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 #include "event_logger.h"
16
17 #include "securec.h"
18
19 #include <cinttypes>
20 #include <list>
21 #include <map>
22 #include <regex>
23 #include <sstream>
24 #include <unistd.h>
25 #include <vector>
26 #include <iostream>
27 #include <filesystem>
28 #include <string_ex.h>
29
30 #include "parameter.h"
31
32 #include "common_utils.h"
33 #include "dfx_json_formatter.h"
34 #include "event_source.h"
35 #include "file_util.h"
36 #include "freeze_json_util.h"
37 #include "log_catcher_utils.h"
38 #include "parameter_ex.h"
39 #include "plugin_factory.h"
40 #include "string_util.h"
41 #include "sys_event.h"
42 #include "sys_event_dao.h"
43 #include "time_util.h"
44 #ifdef WINDOW_MANAGER_ENABLE
45 #include "event_focus_listener.h"
46 #include "window_manager_lite.h"
47 #include "wm_common.h"
48 #endif
49
50 #include "event_log_task.h"
51 #include "event_logger_config.h"
52 #include "event_logger_util.h"
53
54 namespace OHOS {
55 namespace HiviewDFX {
56 namespace {
57 static constexpr const char* const LONG_PRESS = "LONG_PRESS";
58 static constexpr const char* const AP_S_PRESS6S = "AP_S_PRESS6S";
59 static constexpr const char* const REBOOT_REASON = "reboot_reason";
60 static constexpr const char* const NORMAL_RESET_TYPE = "normal_reset_type";
61 static constexpr const char* const PATTERN_WITHOUT_SPACE = "\\s*=\\s*([^ \\n]*)";
62 static constexpr const char* const DOMAIN_LONGPRESS = "KERNEL_VENDOR";
63 static constexpr const char* const STRINGID_LONGPRESS = "COM_LONG_PRESS";
64 static constexpr const char* const LONGPRESS_LEVEL = "CRITICAL";
65 static constexpr const char* const EXPECTION_FLAG = "notifyAppFault exception";
66 static constexpr const char* const MONITOR_STACK_FLIE_NAME[] = {
67 "jsstack",
68 };
69 static constexpr const char* const CORE_PROCESSES[] = {
70 "com.ohos.sceneboard", "composer_host", "foundation", "powermgr", "render_service"
71 };
72
73 static constexpr const char* const APPFREEZE_LOG_PREFIX = "/data/app/el2/100/log/";
74 static constexpr const char* const APPFREEZE_LOG_SUFFIX = "/watchdog/freeze/";
75 static constexpr const char* const FREEZE_CPUINFO_PREFIX = "freeze-cpuinfo-ext-";
76 static constexpr const char* const FFRT_PTOCESSES[] = {
77 "com.ohos.sceneboard", "foundation", "hiview"
78 };
79 static constexpr const char* const FFRT_REPORT_EVENT_TYPE[] = {
80 "Trigger_Escape", "Serial_Queue_Timeout", "Task_Sch_Timeout"
81 };
82 static constexpr const char* const TASK_TIMEOUT = "CONGESTION";
83 static constexpr const char* const SENARIO = "SENARIO";
84
85 #ifdef WINDOW_MANAGER_ENABLE
86 static constexpr int BACK_FREEZE_TIME_LIMIT = 2000;
87 static constexpr int BACK_FREEZE_COUNT_LIMIT = 5;
88 static constexpr int CLICK_FREEZE_TIME_LIMIT = 3000;
89 static constexpr int TOP_WINDOW_NUM = 3;
90 static constexpr uint8_t USER_PANIC_WARNING_PRIVACY = 2;
91 #endif
92 static constexpr int DUMP_TIME_RATIO = 2;
93 static constexpr int EVENT_MAX_ID = 1000000;
94 static constexpr int MIN_KEEP_FILE_NUM = 80;
95 static constexpr int MAX_FOLDER_SIZE = 100 * 1024 * 1024;
96 static constexpr int QUERY_PROCESS_KILL_INTERVAL = 10000;
97 static constexpr int HISTORY_EVENT_LIMIT = 500;
98 static constexpr uint8_t LONGPRESS_PRIVACY = 1;
99 static constexpr int OVER_MEM_SIZE = 2 * 1024 * 1024;
100 static constexpr int DECIMEL = 10;
101 static constexpr uint64_t QUERY_KEY_PROCESS_EVENT_INTERVAL = 15000;
102 static constexpr int DFX_TASK_MAX_CONCURRENCY_NUM = 8;
103 static constexpr int BOOT_SCAN_SECONDS = 60;
104 constexpr mode_t DEFAULT_LOG_FILE_MODE = 0644;
105 constexpr size_t FREEZE_SAMPLE_STACK_INDEX = 1;
106 constexpr int32_t MAX_FREEZE_PER_HAP = 10;
107 }
108
109 REGISTER(EventLogger);
110 DEFINE_LOG_LABEL(0xD002D01, "EventLogger");
111
IsInterestedPipelineEvent(std::shared_ptr<Event> event)112 bool EventLogger::IsInterestedPipelineEvent(std::shared_ptr<Event> event)
113 {
114 if (event == nullptr) {
115 return false;
116 }
117 if (event->eventId_ > EVENT_MAX_ID) {
118 return false;
119 }
120
121 auto sysEvent = Event::DownCastTo<SysEvent>(event);
122 if (eventLoggerConfig_.find(sysEvent->eventName_) == eventLoggerConfig_.end()) {
123 return false;
124 }
125 HIVIEW_LOGD("event time:%{public}" PRIu64 " jsonExtraInfo is %{public}s", TimeUtil::GetMilliseconds(),
126 sysEvent->AsJsonStr().c_str());
127
128 EventLoggerConfig::EventLoggerConfigData& configOut = eventLoggerConfig_[sysEvent->eventName_];
129 sysEvent->eventName_ = configOut.name;
130 sysEvent->SetValue("eventLog_action", configOut.action);
131 sysEvent->SetValue("eventLog_interval", configOut.interval);
132 return true;
133 }
134
GetEventPid(std::shared_ptr<SysEvent> & sysEvent)135 long EventLogger::GetEventPid(std::shared_ptr<SysEvent> &sysEvent)
136 {
137 long pid = sysEvent->GetEventIntValue("PID");
138 if (pid <= 0) {
139 pid = CommonUtils::GetPidByName(sysEvent->GetEventValue("PACKAGE_NAME"));
140 pid = (pid > 0) ? pid : sysEvent->GetPid();
141 sysEvent->SetEventValue("PID", pid);
142 }
143 return pid;
144 }
145
CheckFfrtEvent(std::shared_ptr<SysEvent> & sysEvent)146 bool EventLogger::CheckFfrtEvent(std::shared_ptr<SysEvent> &sysEvent)
147 {
148 if (sysEvent->eventName_ != TASK_TIMEOUT) {
149 return true;
150 }
151 return (std::find(std::begin(FFRT_REPORT_EVENT_TYPE), std::end(FFRT_REPORT_EVENT_TYPE),
152 sysEvent->GetEventValue(SENARIO)) != std::end(FFRT_REPORT_EVENT_TYPE)) &&
153 (std::find(std::begin(FFRT_PTOCESSES), std::end(FFRT_PTOCESSES),
154 sysEvent->GetEventValue("PROCESS_NAME")) != std::end(FFRT_PTOCESSES));
155 }
156
CheckContinueReport(std::shared_ptr<SysEvent> & sysEvent,long pid,const std::string & eventName)157 bool EventLogger::CheckContinueReport(std::shared_ptr<SysEvent> &sysEvent, long pid, const std::string &eventName)
158 {
159 #ifdef HITRACE_CATCHER_ENABLE
160 if (eventName == "HIVIEW_HALF_FREEZE_LOG") {
161 FreezeFilterTraceOn(sysEvent, Parameter::IsBetaVersion());
162 return false;
163 }
164 #endif
165
166 #ifdef WINDOW_MANAGER_ENABLE
167 EventFocusListener::RegisterFocusListener();
168 #endif
169
170 if (eventName == "GESTURE_NAVIGATION_BACK" || eventName == "FREQUENT_CLICK_WARNING") {
171 #ifdef WINDOW_MANAGER_ENABLE
172 if (EventFocusListener::registerState_ == EventFocusListener::REGISTERED) {
173 ReportUserPanicWarning(sysEvent, pid);
174 }
175 #endif
176 return false;
177 }
178 HIVIEW_LOGI("domain=%{public}s, eventName=%{public}s, pid=%{public}ld, happenTime=%{public}" PRIu64,
179 sysEvent->domain_.c_str(), eventName.c_str(), pid, sysEvent->happenTime_);
180 return true;
181 }
182
OnEvent(std::shared_ptr<Event> & onEvent)183 bool EventLogger::OnEvent(std::shared_ptr<Event> &onEvent)
184 {
185 if (onEvent == nullptr) {
186 return false;
187 }
188 std::shared_ptr<SysEvent> sysEvent = Event::DownCastTo<SysEvent>(onEvent);
189 if (sysEvent == nullptr) {
190 return false;
191 }
192
193 long pid = GetEventPid(sysEvent);
194 std::string eventName = sysEvent->eventName_;
195
196 if (!CheckContinueReport(sysEvent, pid, eventName) || !CheckFfrtEvent(sysEvent) || !IsHandleAppfreeze(sysEvent) ||
197 CheckProcessRepeatFreeze(eventName, pid) || CheckScreenOnRepeat(sysEvent)) {
198 return true;
199 }
200 if (sysEvent->GetValue("eventLog_action").empty()) {
201 UpdateDB(sysEvent, "nolog");
202 return true;
203 }
204
205 sysEvent->OnPending();
206 auto task = [this, sysEvent, eventName] {
207 HIVIEW_LOGI("time:%{public}" PRIu64 " jsonExtraInfo is %{public}s", TimeUtil::GetMilliseconds(),
208 sysEvent->AsJsonStr().c_str());
209 if (!JudgmentRateLimiting(sysEvent)) {
210 return;
211 }
212 #ifdef WINDOW_MANAGER_ENABLE
213 if (eventName == "GET_DISPLAY_SNAPSHOT" || eventName == "CREATE_VIRTUAL_SCREEN") {
214 queue_->submit([this, sysEvent] { this->StartFfrtDump(sysEvent); }, ffrt::task_attr().name("ffrt_dump"));
215 }
216 #endif
217 this->StartLogCollect(sysEvent);
218 };
219 HIVIEW_LOGI("before submit event task to ffrt, eventName=%{public}s, pid=%{public}ld", eventName.c_str(), pid);
220 queue_->submit(task, ffrt::task_attr().name("eventlogger"));
221 HIVIEW_LOGD("after submit event task to ffrt, eventName=%{public}s, pid=%{public}ld", eventName.c_str(), pid);
222 return true;
223 }
224
GetFile(std::shared_ptr<SysEvent> event,std::string & logFile,bool isFfrt)225 int EventLogger::GetFile(std::shared_ptr<SysEvent> event, std::string& logFile, bool isFfrt)
226 {
227 uint64_t logTime = event->happenTime_ / TimeUtil::SEC_TO_MILLISEC;
228 std::string formatTime = TimeUtil::TimestampFormatToDate(logTime, "%Y%m%d%H%M%S");
229 int32_t pid = static_cast<int32_t>(event->GetEventIntValue("PID"));
230 pid = pid ? pid : event->GetPid();
231 if (!isFfrt) {
232 std::string idStr = event->eventName_.empty() ? std::to_string(event->eventId_) : event->eventName_;
233 logFile = idStr + "-" + std::to_string(pid) + "-" + formatTime + ".log";
234 } else {
235 logFile = "ffrt_" + std::to_string(pid) + "_" + formatTime;
236 }
237
238 if (FileUtil::FileExists(std::string(LOGGER_EVENT_LOG_PATH) + "/" + logFile)) {
239 HIVIEW_LOGW("filename: %{public}s is existed, direct use.", logFile.c_str());
240 if (!isFfrt) {
241 UpdateDB(event, logFile);
242 }
243 return -1;
244 }
245 return logStore_->CreateLogFile(logFile);
246 }
247
248 #ifdef WINDOW_MANAGER_ENABLE
StartFfrtDump(std::shared_ptr<SysEvent> event)249 void EventLogger::StartFfrtDump(std::shared_ptr<SysEvent> event)
250 {
251 std::vector<Rosen::MainWindowInfo> windowInfos;
252 Rosen::WindowManagerLite::GetInstance().GetMainWindowInfos(TOP_WINDOW_NUM, windowInfos);
253 if (windowInfos.size() == 0) {
254 return;
255 }
256
257 std::string ffrtFile;
258 int ffrtFd = GetFile(event, ffrtFile, true);
259 if (ffrtFd < 0) {
260 HIVIEW_LOGE("create ffrt log file %{public}s failed, %{public}d", ffrtFile.c_str(), ffrtFd);
261 return;
262 }
263
264 int count = LogCatcherUtils::WAIT_CHILD_PROCESS_COUNT * DUMP_TIME_RATIO;
265 FileUtil::SaveStringToFd(ffrtFd, "ffrt dump topWindowInfos, process infos:\n");
266 std::string cmdAms = "--ffrt ";
267 std::string cmdSam = "--ffrt ";
268 int size = static_cast<int>(windowInfos.size());
269 for (int i = 0; i < size ; i++) {
270 auto info = windowInfos[i];
271 FileUtil::SaveStringToFd(ffrtFd, " " + std::to_string(info.pid_) + ":" + info.bundleName_ + "\n");
272 cmdAms += std::to_string(info.pid_) + (i < size -1 ? "," : "");
273 cmdSam += std::to_string(info.pid_) + (i < size -1 ? "|" : "");
274 }
275 LogCatcherUtils::ReadShellToFile(ffrtFd, "ApplicationManagerService", cmdAms, count);
276 if (count > LogCatcherUtils::WAIT_CHILD_PROCESS_COUNT / DUMP_TIME_RATIO) {
277 LogCatcherUtils::ReadShellToFile(ffrtFd, "SystemAbilityManager", cmdSam, count);
278 }
279 close(ffrtFd);
280 }
281 #endif
282
SaveDbToFile(const std::shared_ptr<SysEvent> & event)283 void EventLogger::SaveDbToFile(const std::shared_ptr<SysEvent>& event)
284 {
285 std::string historyFile = std::string(LOGGER_EVENT_LOG_PATH) + "/" + "history.log";
286 if (FileUtil::CreateFile(historyFile, DEFAULT_LOG_FILE_MODE) != 0 && !FileUtil::FileExists(historyFile)) {
287 HIVIEW_LOGE("failed to create file=%{public}s, errno=%{public}d", historyFile.c_str(), errno);
288 return;
289 }
290 std::vector<std::string> lines;
291 if (!FileUtil::LoadLinesFromFile(historyFile, lines)) {
292 HIVIEW_LOGE("failed to loadlines from file=%{public}s, errno=%{public}d", historyFile.c_str(), errno);
293 return;
294 }
295 bool truncated = false;
296 if (lines.size() > HISTORY_EVENT_LIMIT) {
297 truncated = true;
298 }
299 auto time = TimeUtil::TimestampFormatToDate(event->happenTime_ / TimeUtil::SEC_TO_MILLISEC,
300 "%Y%m%d%H%M%S");
301 long pid = event->GetEventIntValue("PID") ? event->GetEventIntValue("PID") : event->GetPid();
302 long uid = event->GetEventIntValue("UID") ? event->GetEventIntValue("UID") : event->GetUid();
303 std::string str = "time[" + time + "], domain[" + event->domain_ + "], wpName[" +
304 event->eventName_ + "], pid: " + std::to_string(pid) + ", uid: " + std::to_string(uid) + "\n";
305 FileUtil::SaveStringToFile(historyFile, str, truncated);
306 }
307
SaveFreezeInfoToFile(const std::shared_ptr<SysEvent> & event)308 void EventLogger::SaveFreezeInfoToFile(const std::shared_ptr<SysEvent>& event)
309 {
310 std::string tmp = event->GetEventValue("FREEZE_INFO_PATH");
311 if (tmp.empty()) {
312 HIVIEW_LOGD("failed to save freezeInfo to file, FREEZE_INFO_PATH is empty.");
313 return;
314 }
315
316 std::vector<std::string> tokens;
317 StringUtil::SplitStr(tmp, ",", tokens);
318 if (tokens.size() <= 0) {
319 return;
320 }
321
322 std::string cpuInfo = GetAppFreezeFile(tokens[0]);
323 if (cpuInfo.empty()) {
324 HIVIEW_LOGW("failed to save freezeInfo to file, cpu content is empty.");
325 return;
326 }
327
328 std::string bundleName = event->GetEventValue("PACKAGE_NAME").empty() ?
329 event->GetEventValue("PROCESS_NAME") : event->GetEventValue("PACKAGE_NAME");
330 std::string stackInfo;
331 if (tokens.size() > FREEZE_SAMPLE_STACK_INDEX) {
332 std::string filePath = APPFREEZE_LOG_PREFIX + bundleName + APPFREEZE_LOG_SUFFIX + tokens[1];
333 stackInfo = GetAppFreezeFile(filePath);
334 if (stackInfo.empty()) {
335 HIVIEW_LOGW("freeze sapmle stack content is empty.");
336 }
337 }
338
339 long uid = event->GetEventIntValue("UID") ? event->GetEventIntValue("UID") : event->GetUid();
340 std::string freezeFile = FREEZE_CPUINFO_PREFIX +
341 bundleName + "-" + std::to_string(uid) + "-" + TimeUtil::GetFormattedTimestampEndWithMilli();
342 int fd = logStore_->CreateLogFile(freezeFile);
343 if (fd < 0) {
344 HIVIEW_LOGE("failed to create file=%{public}s, errno=%{public}d", freezeFile.c_str(), errno);
345 return;
346 }
347 FileUtil::SaveStringToFd(fd, cpuInfo + stackInfo);
348 close(fd);
349
350 logStore_->ClearSameLogFilesIfNeeded(CreateLogFileFilter(uid, FREEZE_CPUINFO_PREFIX), MAX_FREEZE_PER_HAP);
351 }
352
WriteInfoToLog(std::shared_ptr<SysEvent> event,int fd,int jsonFd,std::string & threadStack)353 void EventLogger::WriteInfoToLog(std::shared_ptr<SysEvent> event, int fd, int jsonFd, std::string& threadStack)
354 {
355 auto start = TimeUtil::GetMilliseconds();
356 WriteStartTime(fd, start);
357 WriteCommonHead(fd, event);
358 std::vector<std::string> binderPids;
359 WriteFreezeJsonInfo(fd, jsonFd, event, binderPids, threadStack);
360 std::for_each(binderPids.begin(), binderPids.end(), [fd] (const std::string& binderPid) {
361 FileUtil::SaveStringToFd(fd, "PeerBinder catcher ffrt stacktrace for pid : " + binderPid + "\r\n");
362 LogCatcherUtils::DumpStackFfrt(fd, binderPid);
363 });
364
365 std::shared_ptr<EventLogTask> logTask = std::make_shared<EventLogTask>(fd, jsonFd, event);
366 if (event->eventName_ == "GET_DISPLAY_SNAPSHOT" || event->eventName_ == "CREATE_VIRTUAL_SCREEN") {
367 logTask->SetFocusWindowId(DumpWindowInfo(fd));
368 }
369 std::vector<std::string> cmdList;
370 StringUtil::SplitStr(event->GetValue("eventLog_action"), ",", cmdList);
371 if (event->GetEventValue("MSG").find(EXPECTION_FLAG) != std::string::npos) {
372 logTask->AddLog("S");
373 }
374 for (const std::string& cmd : cmdList) {
375 if (cmd == "tr" || cmd == "k:SysRqFile" || cmd == "k:HungTaskFile") {
376 if (cmd == "k:SysRqFile" || cmd == "k:HungTaskFile") {
377 auto logTime = TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC;
378 std::string fileTime = TimeUtil::TimestampFormatToDate(logTime, "%Y%m%d%H%M%S");
379 std::string fileType = (cmd == "k:SysRqFile") ? "sysrq" : "hungtask";
380 std::string catcher = (fileType == "sysrq") ? "\nSysrqCatcher" : "\nHungTaskCatcher";
381 std::string fileInfo = catcher + " -- fullPath:" + std::string(LOGGER_EVENT_LOG_PATH) + "/" +
382 fileType + "-" + fileTime + ".log\n";
383 FileUtil::SaveStringToFd(fd, fileInfo);
384 std::string fileTimeKey = (fileType == "sysrq") ? "SYSRQ_TIME" : "HUNGTASK_TIME";
385 event->SetEventValue(fileTimeKey, fileTime);
386 }
387 queue_->submit([this, logTask, cmd] { logTask->AddLog(cmd); }, ffrt::task_attr().name("async_log"));
388 continue;
389 }
390 logTask->AddLog(cmd);
391 if (cmd == "cmd:m") {
392 queue_->submit([this, logTask, cmd] { logTask->AddLog(cmd); }, ffrt::task_attr().name("async_log"));
393 }
394 }
395
396 auto ret = logTask->StartCompose();
397 if (ret != EventLogTask::TASK_SUCCESS) {
398 HIVIEW_LOGE("capture fail %{public}d", ret);
399 }
400 threadStack = threadStack.empty() ? logTask->terminalThreadStack_ : threadStack;
401 SetEventTerminalBinder(event, threadStack, fd);
402 auto end = TimeUtil::GetMilliseconds();
403 FileUtil::SaveStringToFd(fd, "\n\nCatcher log total time is " + std::to_string(end - start) + "ms\n");
404 }
405
SetEventTerminalBinder(std::shared_ptr<SysEvent> event,const std::string & threadStack,int fd)406 void EventLogger::SetEventTerminalBinder(std::shared_ptr<SysEvent> event, const std::string& threadStack, int fd)
407 {
408 if (threadStack.empty()) {
409 return;
410 }
411 event->SetEventValue("TERMINAL_THREAD_STACK", threadStack);
412 if (std::find(std::begin(FreezeCommon::PB_EVENTS), std::end(FreezeCommon::PB_EVENTS), event->eventName_) !=
413 std::end(FreezeCommon::PB_EVENTS)) {
414 FileUtil::SaveStringToFd(fd, "\nThread stack start:\n" + threadStack + "Thread stack end\n");
415 }
416 }
417
StartLogCollect(std::shared_ptr<SysEvent> event)418 void EventLogger::StartLogCollect(std::shared_ptr<SysEvent> event)
419 {
420 std::string logFile;
421 int fd = GetFile(event, logFile, false);
422 if (fd < 0) {
423 HIVIEW_LOGE("create log file %{public}s failed, %{public}d", logFile.c_str(), fd);
424 return;
425 }
426
427 int jsonFd = -1;
428 if (FreezeJsonUtil::IsAppFreeze(event->eventName_) || FreezeJsonUtil::IsAppHicollie(event->eventName_)) {
429 std::string jsonFilePath = FreezeJsonUtil::GetFilePath(event->GetEventIntValue("PID"),
430 event->GetEventIntValue("UID"), event->happenTime_);
431 jsonFd = FreezeJsonUtil::GetFd(jsonFilePath);
432 }
433
434 std::string terminalBinderThreadStack;
435 WriteInfoToLog(event, fd, jsonFd, terminalBinderThreadStack);
436 close(fd);
437 if (jsonFd >= 0) {
438 close(jsonFd);
439 }
440 UpdateDB(event, logFile);
441 SaveDbToFile(event);
442
443 constexpr int waitTime = 1;
444 auto CheckFinishFun = [this, event] { this->CheckEventOnContinue(event); };
445 threadLoop_->AddTimerEvent(nullptr, nullptr, CheckFinishFun, waitTime, false);
446 SaveFreezeInfoToFile(event);
447 HIVIEW_LOGI("Collect on finish, name: %{public}s", logFile.c_str());
448 }
449
450 #ifdef HITRACE_CATCHER_ENABLE
FreezeFilterTraceOn(std::shared_ptr<SysEvent> event,bool isBetaVersion)451 void EventLogger::FreezeFilterTraceOn(std::shared_ptr<SysEvent> event, bool isBetaVersion)
452 {
453 if (isBetaVersion) {
454 return;
455 }
456
457 std::string bundleName = event->GetEventValue("PACKAGE_NAME");
458 if (bundleName.empty()) {
459 long pid = GetEventPid(event);
460 bundleName = CommonUtils::GetProcFullNameByPid(pid);
461 }
462 LogCatcherUtils::FreezeFilterTraceOn(bundleName);
463 }
464 #endif
465
ParseMsgForMessageAndEventHandler(const std::string & msg,std::string & message,std::string & eventHandlerStr)466 bool ParseMsgForMessageAndEventHandler(const std::string& msg, std::string& message, std::string& eventHandlerStr)
467 {
468 std::vector<std::string> lines;
469 StringUtil::SplitStr(msg, "\n", lines, false, true);
470 bool isGetMessage = false;
471 std::string messageStartFlag = "Fault time:";
472 std::string messageEndFlag = "mainHandler dump is:";
473 std::string eventFlag = "Event {";
474 bool isGetEvent = false;
475 std::regex eventStartFlag(".*((VIP)|(Immediate)|(High)|(Low)|(Idle)) priority event queue information:.*");
476 std::regex eventEndFlag(".*Total size of ((VIP)|(Immediate)|(High)|(Low)|(Idle)) events :.*");
477 std::list<std::string> eventHandlerList;
478 for (auto line = lines.begin(); line != lines.end(); line++) {
479 if ((*line).find(messageStartFlag) != std::string::npos) {
480 isGetMessage = true;
481 continue;
482 }
483 if (isGetMessage) {
484 if ((*line).find(messageEndFlag) != std::string::npos) {
485 isGetMessage = false;
486 HIVIEW_LOGD("Get FreezeJson message jsonStr: %{public}s", message.c_str());
487 continue;
488 }
489 message += StringUtil::TrimStr(*line);
490 continue;
491 }
492 if (regex_match(*line, eventStartFlag)) {
493 isGetEvent = true;
494 continue;
495 }
496 if (isGetEvent) {
497 if (regex_match(*line, eventEndFlag)) {
498 isGetEvent = false;
499 continue;
500 }
501 std::string::size_type pos = (*line).find(eventFlag);
502 if (pos == std::string::npos) {
503 continue;
504 }
505 std::string handlerStr = StringUtil::TrimStr(*line).substr(pos);
506 HIVIEW_LOGD("Get EventHandler str: %{public}s.", handlerStr.c_str());
507 eventHandlerList.push_back(handlerStr);
508 }
509 }
510 eventHandlerStr = FreezeJsonUtil::GetStrByList(eventHandlerList);
511 return true;
512 }
513
ParsePeerBinder(const std::string & binderInfo,std::string & binderInfoJsonStr)514 void ParsePeerBinder(const std::string& binderInfo, std::string& binderInfoJsonStr)
515 {
516 std::vector<std::string> lines;
517 StringUtil::SplitStr(binderInfo, "\\n", lines, false, true);
518 std::list<std::string> infoList;
519 std::map<std::string, std::string> processNameMap;
520
521 for (auto lineIt = lines.begin(); lineIt != lines.end(); lineIt++) {
522 std::string line = *lineIt;
523 if (line.empty() || line.find("async\t") != std::string::npos) {
524 continue;
525 }
526
527 if (line.find("context") != line.npos) {
528 break;
529 }
530
531 std::istringstream lineStream(line);
532 std::vector<std::string> strList;
533 std::string tmpstr;
534 while (lineStream >> tmpstr) {
535 strList.push_back(tmpstr);
536 }
537 if (strList.size() < 7) { // less than 7: valid array size
538 continue;
539 }
540 // 2: binder peer id
541 std::string pidStr = strList[2].substr(0, strList[2].find(":"));
542 if (pidStr == "") {
543 continue;
544 }
545 if (processNameMap.find(pidStr) == processNameMap.end()) {
546 std::string filePath = "/proc/" + pidStr + "/cmdline";
547 std::string realPath;
548 if (!FileUtil::PathToRealPath(filePath, realPath)) {
549 continue;
550 }
551 std::ifstream cmdLineFile(realPath);
552 std::string processName;
553 if (cmdLineFile) {
554 std::getline(cmdLineFile, processName);
555 cmdLineFile.close();
556 StringUtil::FormatProcessName(processName);
557 processNameMap[pidStr] = processName;
558 } else {
559 HIVIEW_LOGE("Fail to open /proc/%{public}s/cmdline", pidStr.c_str());
560 }
561 }
562 std::string lineStr = line + " " + pidStr + FreezeJsonUtil::WrapByParenthesis(processNameMap[pidStr]);
563 infoList.push_back(lineStr);
564 }
565 binderInfoJsonStr = FreezeJsonUtil::GetStrByList(infoList);
566 }
567
DumpWindowInfo(int fd)568 std::string EventLogger::DumpWindowInfo(int fd)
569 {
570 std::string focusWindowId = "";
571 FILE *file = popen("/system/bin/hidumper -s WindowManagerService -a -a", "r");
572 if (file == nullptr) {
573 HIVIEW_LOGE("parse focus window id error");
574 return focusWindowId;
575 }
576 FileUtil::SaveStringToFd(fd, std::string("\ncatcher cmd: hidumper -s WindowManagerService -a -a\n"));
577 std::smatch result;
578 std::string line = "";
579 auto windowIdRegex = std::regex("Focus window: ([0-9]+)");
580 char *buffer = nullptr;
581 size_t length = 0;
582 while (getline(&buffer, &length, file) != -1) {
583 line = buffer;
584 if (regex_search(line, result, windowIdRegex)) {
585 focusWindowId = result[1];
586 }
587 FileUtil::SaveStringToFd(fd, line);
588 }
589 if (buffer != nullptr) {
590 free(buffer);
591 buffer = nullptr;
592 }
593 pclose(file);
594 file = nullptr;
595 return focusWindowId;
596 }
597
WriteStartTime(int fd,uint64_t start)598 bool EventLogger::WriteStartTime(int fd, uint64_t start)
599 {
600 const uint32_t placeholder = 3;
601 uint64_t startTime = start / TimeUtil::SEC_TO_MILLISEC;
602 std::ostringstream startTimeStr;
603 startTimeStr << "start time: " << TimeUtil::TimestampFormatToDate(startTime, "%Y/%m/%d-%H:%M:%S");
604 startTimeStr << ":" << std::setw(placeholder) << std::setfill('0') <<
605 std::to_string(start % TimeUtil::SEC_TO_MILLISEC);
606 startTimeStr << std::endl;
607 FileUtil::SaveStringToFd(fd, startTimeStr.str());
608 return true;
609 }
610
WriteCommonHead(int fd,std::shared_ptr<SysEvent> event)611 bool EventLogger::WriteCommonHead(int fd, std::shared_ptr<SysEvent> event)
612 {
613 std::ostringstream headerStream;
614
615 headerStream << "DOMAIN = " << event->domain_ << std::endl;
616 headerStream << "EVENTNAME = " << event->eventName_ << std::endl;
617 uint64_t logTime = event->happenTime_ / TimeUtil::SEC_TO_MILLISEC;
618 uint64_t logTimeMs = event->happenTime_ % TimeUtil::SEC_TO_MILLISEC;
619 std::string happenTime = TimeUtil::TimestampFormatToDate(logTime, "%Y/%m/%d-%H:%M:%S");
620 headerStream << "TIMESTAMP = " << happenTime << ":" << logTimeMs << std::endl;
621 long pid = event->GetEventIntValue("PID");
622 pid = pid ? pid : event->GetPid();
623 headerStream << "PID = " << pid << std::endl;
624 long uid = event->GetEventIntValue("UID");
625 uid = uid ? uid : event->GetUid();
626 headerStream << "UID = " << uid << std::endl;
627 if (event->GetEventIntValue("TID")) {
628 headerStream << "TID = " << event->GetEventIntValue("TID") << std::endl;
629 } else {
630 headerStream << "TID = " << pid << std::endl;
631 }
632 if (event->GetEventValue("MODULE_NAME") != "") {
633 headerStream << "MODULE_NAME = " << event->GetEventValue("MODULE_NAME") << std::endl;
634 } else {
635 headerStream << "PACKAGE_NAME = " << event->GetEventValue("PACKAGE_NAME") << std::endl;
636 }
637 headerStream << "PROCESS_NAME = " << event->GetEventValue("PROCESS_NAME") << std::endl;
638 headerStream << "eventLog_action = " << event->GetValue("eventLog_action") << std::endl;
639 headerStream << "eventLog_interval = " << event->GetValue("eventLog_interval") << std::endl;
640
641 FileUtil::SaveStringToFd(fd, headerStream.str());
642 return true;
643 }
644
WriteCallStack(std::shared_ptr<SysEvent> event,int fd)645 void EventLogger::WriteCallStack(std::shared_ptr<SysEvent> event, int fd)
646 {
647 if (event->domain_.compare("FORM_MANAGER") == 0 && event->eventName_.compare("FORM_BLOCK_CALLSTACK") == 0) {
648 std::ostringstream stackOss;
649 std::string stackMsg = StringUtil::ReplaceStr(event->GetEventValue("EVENT_KEY_FORM_BLOCK_CALLSTACK"),
650 "\\n", "\n");
651 stackOss << "CallStack = " << stackMsg << std::endl;
652 FileUtil::SaveStringToFd(fd, stackOss.str());
653
654 std::ostringstream appNameOss;
655 std::string appMsg = StringUtil::ReplaceStr(event->GetEventValue("EVENT_KEY_FORM_BLOCK_APPNAME"),
656 "\\n", "\n");
657 appNameOss << "AppName = " << appMsg << std::endl;
658 FileUtil::SaveStringToFd(fd, appNameOss.str());
659 }
660 }
661
GetAppFreezeFile(std::string & stackPath)662 std::string EventLogger::GetAppFreezeFile(std::string& stackPath)
663 {
664 std::string result = "";
665 if (!FileUtil::FileExists(stackPath)) {
666 result = "";
667 HIVIEW_LOGE("File is not exist");
668 return result;
669 }
670 FileUtil::LoadStringFromFile(stackPath, result);
671 bool isRemove = FileUtil::RemoveFile(stackPath.c_str());
672 HIVIEW_LOGI("Remove file? isRemove:%{public}d", isRemove);
673 return result;
674 }
675
IsKernelStack(const std::string & stack)676 bool EventLogger::IsKernelStack(const std::string& stack)
677 {
678 return (!stack.empty() && stack.find("Stack backtrace") != std::string::npos);
679 }
680
GetNoJsonStack(std::string & stack,std::string & contentStack,std::string & kernelStack,bool isFormat)681 void EventLogger::GetNoJsonStack(std::string& stack, std::string& contentStack,
682 std::string& kernelStack, bool isFormat)
683 {
684 if (!IsKernelStack(contentStack)) {
685 stack = contentStack;
686 contentStack = "[]";
687 return;
688 }
689 std::string kernelStackTag = "Kernel stack is:\n";
690 std::string kernelStackStart = "";
691 size_t kernelStackIndex = contentStack.find(kernelStackTag);
692 if (kernelStackIndex != std::string::npos) {
693 kernelStackStart = contentStack.substr(0, kernelStackIndex);
694 contentStack = contentStack.substr(kernelStackIndex + kernelStackTag.size());
695 }
696 kernelStack = contentStack;
697 if (DfxJsonFormatter::FormatKernelStack(contentStack, stack, isFormat)) {
698 contentStack = stack;
699 if (isFormat) {
700 stack = "";
701 stack = DfxJsonFormatter::FormatJsonStack(contentStack, stack) ? stack : contentStack;
702 }
703 } else {
704 stack = "Failed to format kernel stack\n";
705 contentStack = "[]";
706 }
707 stack = kernelStackStart + stack;
708 }
709
GetAppFreezeStack(int jsonFd,std::shared_ptr<SysEvent> event,std::string & stack,const std::string & msg,std::string & kernelStack)710 void EventLogger::GetAppFreezeStack(int jsonFd, std::shared_ptr<SysEvent> event,
711 std::string& stack, const std::string& msg, std::string& kernelStack)
712 {
713 std::string message;
714 std::string eventHandlerStr;
715 ParseMsgForMessageAndEventHandler(msg, message, eventHandlerStr);
716 std::string appRunningUniqueId = event->GetEventValue("APP_RUNNING_UNIQUE_ID");
717
718 std::string jsonStack = event->GetEventValue("STACK");
719 HIVIEW_LOGI("Current jsonStack is? jsonStack:%{public}s", jsonStack.c_str());
720 if (FileUtil::FileExists(jsonStack)) {
721 jsonStack = GetAppFreezeFile(jsonStack);
722 }
723
724 if (!jsonStack.empty() && jsonStack[0] == '[') { // json stack info should start with '['
725 jsonStack = StringUtil::UnescapeJsonStringValue(jsonStack);
726 if (!DfxJsonFormatter::FormatJsonStack(jsonStack, stack)) {
727 stack = jsonStack;
728 }
729 } else {
730 GetNoJsonStack(stack, jsonStack, kernelStack, true);
731 }
732
733 GetFailedDumpStackMsg(stack, event);
734
735 if (jsonFd >= 0) {
736 HIVIEW_LOGI("success to open FreezeJsonFile! jsonFd: %{public}d", jsonFd);
737 FreezeJsonUtil::WriteKeyValue(jsonFd, "message", message);
738 FreezeJsonUtil::WriteKeyValue(jsonFd, "event_handler", eventHandlerStr);
739 FreezeJsonUtil::WriteKeyValue(jsonFd, "appRunningUniqueId", appRunningUniqueId);
740 FreezeJsonUtil::WriteKeyValue(jsonFd, "stack", jsonStack);
741 } else {
742 HIVIEW_LOGE("fail to open FreezeJsonFile! jsonFd: %{public}d", jsonFd);
743 }
744 }
745
WriteKernelStackToFile(std::shared_ptr<SysEvent> event,int originFd,const std::string & kernelStack)746 void EventLogger::WriteKernelStackToFile(std::shared_ptr<SysEvent> event, int originFd,
747 const std::string& kernelStack)
748 {
749 uint64_t logTime = event->happenTime_ / TimeUtil::SEC_TO_MILLISEC;
750 std::string formatTime = TimeUtil::TimestampFormatToDate(logTime, "%Y%m%d%H%M%S");
751 int32_t pid = static_cast<int32_t>(event->GetEventIntValue("PID"));
752 pid = pid ? pid : event->GetPid();
753 std::string idStr = event->eventName_.empty() ? std::to_string(event->eventId_) : event->eventName_;
754 std::string logFile = idStr + "-" + std::to_string(pid) + "-" + formatTime + "-KernelStack-" +
755 std::to_string(originFd) + ".log";
756 std::string path = std::string(LOGGER_EVENT_LOG_PATH) + "/" + logFile;
757 if (FileUtil::FileExists(path)) {
758 HIVIEW_LOGI("Filename: %{public}s is existed.", logFile.c_str());
759 return;
760 }
761 int kernelFd = logStore_->CreateLogFile(logFile);
762 if (kernelFd >= 0) {
763 FileUtil::SaveStringToFd(kernelFd, kernelStack);
764 close(kernelFd);
765 HIVIEW_LOGD("Success WriteKernelStackToFile: %{public}s.", path.c_str());
766 }
767 }
768
ParsePeerStack(std::string & binderInfo,std::string & binderPeerStack)769 void EventLogger::ParsePeerStack(std::string& binderInfo, std::string& binderPeerStack)
770 {
771 if (binderInfo.empty() || !IsKernelStack(binderInfo)) {
772 return;
773 }
774 std::string tags = "Binder catcher stacktrace, ";
775 auto index = binderInfo.find(tags);
776 if (index == std::string::npos) {
777 return;
778 }
779 std::ostringstream oss;
780 oss << binderInfo.substr(0, index);
781 std::string bodys = binderInfo.substr(index, binderInfo.size());
782 std::vector<std::string> lines;
783 StringUtil::SplitStr(bodys, tags, lines, false, true);
784 std::string stack;
785 std::string kernelStack;
786 for (auto lineIt = lines.begin(); lineIt != lines.end(); lineIt++) {
787 std::string line = tags + *lineIt;
788 stack = "";
789 kernelStack = "";
790 GetNoJsonStack(stack, line, kernelStack, false);
791 binderPeerStack += kernelStack;
792 oss << stack << std::endl;
793 }
794 binderInfo = oss.str();
795 }
796
WriteFreezeJsonInfo(int fd,int jsonFd,std::shared_ptr<SysEvent> event,std::vector<std::string> & binderPids,std::string & threadStack)797 bool EventLogger::WriteFreezeJsonInfo(int fd, int jsonFd, std::shared_ptr<SysEvent> event,
798 std::vector<std::string>& binderPids, std::string& threadStack)
799 {
800 std::string msg = StringUtil::ReplaceStr(event->GetEventValue("MSG"), "\\n", "\n");
801 std::string stack;
802 std::string kernelStack;
803 std::string binderInfo = event -> GetEventValue("BINDER_INFO");
804 if (FreezeJsonUtil::IsAppFreeze(event->eventName_)) {
805 GetAppFreezeStack(jsonFd, event, stack, msg, kernelStack);
806 WriteBinderInfo(jsonFd, binderInfo, binderPids, threadStack, kernelStack);
807 } else if (FreezeJsonUtil::IsAppHicollie(event->eventName_)) {
808 GetAppFreezeStack(jsonFd, event, stack, msg, kernelStack);
809 } else {
810 stack = event->GetEventValue("STACK");
811 HIVIEW_LOGI("Current stack is? stack:%{public}s", stack.c_str());
812 if (FileUtil::FileExists(stack)) {
813 stack = GetAppFreezeFile(stack);
814 std::string tempStack = "";
815 GetNoJsonStack(tempStack, stack, kernelStack, false);
816 stack = tempStack;
817 }
818 GetFailedDumpStackMsg(stack, event);
819 if (event->eventName_ == "LIFECYCLE_HALF_TIMEOUT_WARNING") {
820 WriteBinderInfo(jsonFd, binderInfo, binderPids, threadStack, kernelStack);
821 }
822 }
823 if (!kernelStack.empty()) {
824 queue_->submit([this, event, fd, kernelStack] { this->WriteKernelStackToFile(event, fd, kernelStack); },
825 ffrt::task_attr().name("write_kernel_stack"));
826 }
827 std::ostringstream oss;
828 std::string endTimeStamp;
829 size_t endTimeStampIndex = msg.find("Catche stack trace end time: ");
830 if (endTimeStampIndex != std::string::npos) {
831 endTimeStamp = msg.substr(endTimeStampIndex);
832 msg = msg.substr(0, endTimeStampIndex);
833 }
834 oss << "MSG = " << msg << std::endl;
835 if (!stack.empty()) {
836 oss << StringUtil::UnescapeJsonStringValue(stack) << std::endl;
837 }
838 oss << endTimeStamp << std::endl;
839 if (!binderInfo.empty()) {
840 oss << (Parameter::IsOversea() ? "binder info is not saved in oversea version":
841 StringUtil::UnescapeJsonStringValue(binderInfo)) << std::endl;
842 }
843 FileUtil::SaveStringToFd(fd, oss.str());
844 WriteCallStack(event, fd);
845 return true;
846 }
847
WriteBinderInfo(int jsonFd,std::string & binderInfo,std::vector<std::string> & binderPids,std::string & threadStack,std::string & kernelStack)848 void EventLogger::WriteBinderInfo(int jsonFd, std::string& binderInfo, std::vector<std::string>& binderPids,
849 std::string& threadStack, std::string& kernelStack)
850 {
851 size_t indexOne = binderInfo.find(",");
852 size_t indexTwo = binderInfo.rfind(",");
853 if (indexOne != std::string::npos && indexTwo != std::string::npos && indexTwo > indexOne) {
854 HIVIEW_LOGI("Current binderInfo is? binderInfo:%{public}s", binderInfo.c_str());
855 StringUtil::SplitStr(binderInfo.substr(indexOne + 1, indexTwo - indexOne - 1), " ", binderPids);
856 int terminalBinderTid = std::atoi(binderInfo.substr(indexTwo + 1).c_str());
857 std::string binderPath = binderInfo.substr(0, indexOne);
858 if (FileUtil::FileExists(binderPath)) {
859 binderInfo = GetAppFreezeFile(binderPath);
860 }
861 if (jsonFd >= 0) {
862 std::string binderInfoJsonStr;
863 ParsePeerBinder(binderInfo, binderInfoJsonStr);
864 FreezeJsonUtil::WriteKeyValue(jsonFd, "peer_binder", binderInfoJsonStr);
865 }
866 ParsePeerStack(binderInfo, kernelStack);
867 std::string terminalBinderTag = "Binder catcher stacktrace, terminal binder tag\n";
868 size_t tagSize = terminalBinderTag.size();
869 size_t startIndex = binderInfo.find(terminalBinderTag);
870 size_t endIndex = binderInfo.rfind(terminalBinderTag);
871 if (startIndex != std::string::npos && endIndex != std::string::npos && endIndex > startIndex) {
872 LogCatcherUtils::GetThreadStack(binderInfo.substr(startIndex + tagSize,
873 endIndex - startIndex - tagSize), threadStack, terminalBinderTid);
874 binderInfo.erase(startIndex, tagSize);
875 binderInfo.erase(endIndex - tagSize, tagSize);
876 }
877 }
878 }
879
GetFailedDumpStackMsg(std::string & stack,std::shared_ptr<SysEvent> event)880 void EventLogger::GetFailedDumpStackMsg(std::string& stack, std::shared_ptr<SysEvent> event)
881 {
882 std::string failedStackStart = " Failed to dump stacktrace for ";
883 if (dbHelper_ != nullptr && stack.size() >= failedStackStart.size() &&
884 !stack.compare(0, failedStackStart.size(), failedStackStart) &&
885 stack.find("syscall SIGDUMP error") != std::string::npos) {
886 long pid = event->GetEventIntValue("PID") ? event->GetEventIntValue("PID") : event->GetPid();
887 std::string packageName = event->GetEventValue("PACKAGE_NAME").empty() ?
888 event->GetEventValue("PROCESS_NAME") : event->GetEventValue("PACKAGE_NAME");
889
890 std::vector<WatchPoint> list;
891 FreezeResult freezeResult(0, "FRAMEWORK", "PROCESS_KILL");
892 freezeResult.SetSamePackage("true");
893 DBHelper::WatchParams params = {pid, 0, event->happenTime_, packageName};
894 dbHelper_->SelectEventFromDB(event->happenTime_ - QUERY_PROCESS_KILL_INTERVAL, event->happenTime_, list,
895 params, freezeResult);
896 std::string appendStack = "";
897 std::for_each(list.begin(), list.end(), [&appendStack] (const WatchPoint& watchPoint) {
898 appendStack += "\n" + watchPoint.GetMsg();
899 });
900 stack += appendStack.empty() ? "\ncan not get process kill reason" : "\nprocess may be killed by : "
901 + appendStack;
902 }
903 }
904
JudgmentRateLimiting(std::shared_ptr<SysEvent> event)905 bool EventLogger::JudgmentRateLimiting(std::shared_ptr<SysEvent> event)
906 {
907 int32_t interval = event->GetIntValue("eventLog_interval");
908 if (interval == 0) {
909 return true;
910 }
911
912 int64_t pid = event->GetEventIntValue("PID");
913 pid = pid ? pid : event->GetPid();
914 std::string eventName = event->eventName_;
915 std::string eventPid = std::to_string(pid);
916
917 intervalMutex_.lock();
918 std::time_t now = std::time(0);
919 for (auto it = eventTagTime_.begin(); it != eventTagTime_.end();) {
920 if (it->first.find(eventName) != it->first.npos) {
921 if ((now - it->second) >= interval) {
922 it = eventTagTime_.erase(it);
923 continue;
924 }
925 }
926 ++it;
927 }
928
929 std::string tagTimeName = eventName + eventPid;
930 auto it = eventTagTime_.find(tagTimeName);
931 if (it != eventTagTime_.end()) {
932 if ((now - it->second) < interval) {
933 HIVIEW_LOGE("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
934 interval:%{public}" PRId32 " There's not enough interval",
935 event->eventId_, eventName.c_str(), eventPid.c_str(), interval);
936 intervalMutex_.unlock();
937 return false;
938 }
939 }
940 eventTagTime_[tagTimeName] = now;
941 HIVIEW_LOGD("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
942 interval:%{public}" PRId32 " normal interval",
943 event->eventId_, eventName.c_str(), eventPid.c_str(), interval);
944 intervalMutex_.unlock();
945 return true;
946 }
947
UpdateDB(std::shared_ptr<SysEvent> event,std::string logFile)948 bool EventLogger::UpdateDB(std::shared_ptr<SysEvent> event, std::string logFile)
949 {
950 if (logFile == "nolog") {
951 HIVIEW_LOGI("set info_ with nolog into db.");
952 event->SetEventValue(EventStore::EventCol::INFO, "nolog", false);
953 } else {
954 auto logPath = R"~(logPath:)~" + std::string(LOGGER_EVENT_LOG_PATH) + "/" + logFile;
955 event->SetEventValue(EventStore::EventCol::INFO, logPath, true);
956 }
957 return true;
958 }
959
IsHandleAppfreeze(std::shared_ptr<SysEvent> event)960 bool EventLogger::IsHandleAppfreeze(std::shared_ptr<SysEvent> event)
961 {
962 std::string bundleName = event->GetEventValue("PACKAGE_NAME");
963 if (bundleName.empty()) {
964 bundleName = event->GetEventValue("MODULE_NAME");
965 }
966 if (bundleName.empty()) {
967 return true;
968 }
969
970 const int buffSize = 128;
971 char paramOutBuff[buffSize] = {0};
972 GetParameter("hiviewdfx.appfreeze.filter_bundle_name", "", paramOutBuff, buffSize - 1);
973
974 std::string str(paramOutBuff);
975 if (str.find(bundleName) != std::string::npos) {
976 HIVIEW_LOGW("appfreeze filtration %{public}s.", bundleName.c_str());
977 return false;
978 }
979 return true;
980 }
981
982 #ifdef WINDOW_MANAGER_ENABLE
ReportUserPanicWarning(std::shared_ptr<SysEvent> event,long pid)983 void EventLogger::ReportUserPanicWarning(std::shared_ptr<SysEvent> event, long pid)
984 {
985 if (event->eventName_ == "FREQUENT_CLICK_WARNING") {
986 if (event->happenTime_ - EventFocusListener::lastChangedTime_ <= CLICK_FREEZE_TIME_LIMIT) {
987 return;
988 }
989 } else {
990 backTimes_.push_back(event->happenTime_);
991 if (backTimes_.size() < BACK_FREEZE_COUNT_LIMIT) {
992 return;
993 }
994 if ((event->happenTime_ - backTimes_[0] <= BACK_FREEZE_TIME_LIMIT) &&
995 (event->happenTime_ - EventFocusListener::lastChangedTime_ > BACK_FREEZE_TIME_LIMIT)) {
996 backTimes_.clear();
997 } else {
998 backTimes_.erase(backTimes_.begin(), backTimes_.end() - (BACK_FREEZE_COUNT_LIMIT - 1));
999 return;
1000 }
1001 }
1002
1003 auto userPanicEvent = std::make_shared<SysEvent>("EventLogger", nullptr, "");
1004
1005 std::string processName = (event->eventName_ == "FREQUENT_CLICK_WARNING") ? event->GetEventValue("PROCESS_NAME") :
1006 event->GetEventValue("PNAMEID");
1007 std::string msg = (event->eventName_ == "FREQUENT_CLICK_WARNING") ? "frequent click" : "gesture navigation back";
1008
1009 userPanicEvent->domain_ = "FRAMEWORK";
1010 userPanicEvent->eventName_ = "USER_PANIC_WARNING";
1011 userPanicEvent->happenTime_ = TimeUtil::GetMilliseconds();
1012 userPanicEvent->messageType_ = Event::MessageType::SYS_EVENT;
1013 userPanicEvent->SetEventValue(EventStore::EventCol::DOMAIN, "FRAMEWORK");
1014 userPanicEvent->SetEventValue(EventStore::EventCol::NAME, "USER_PANIC_WARNING");
1015 userPanicEvent->SetEventValue(EventStore::EventCol::TYPE, 1);
1016 userPanicEvent->SetEventValue(EventStore::EventCol::TS, TimeUtil::GetMilliseconds());
1017 userPanicEvent->SetEventValue(EventStore::EventCol::TZ, TimeUtil::GetTimeZone());
1018 userPanicEvent->SetEventValue("PID", pid);
1019 userPanicEvent->SetEventValue("UID", 0);
1020 userPanicEvent->SetEventValue("PACKAGE_NAME", processName);
1021 userPanicEvent->SetEventValue("PROCESS_NAME", processName);
1022 userPanicEvent->SetEventValue("MSG", msg);
1023 userPanicEvent->SetPrivacy(USER_PANIC_WARNING_PRIVACY);
1024 userPanicEvent->SetLevel("CRITICAL");
1025 userPanicEvent->SetTag("STABILITY");
1026
1027 auto context = GetHiviewContext();
1028 if (context != nullptr) {
1029 auto seq = context->GetPipelineSequenceByName("EventloggerPipeline");
1030 userPanicEvent->SetPipelineInfo("EventloggerPipeline", seq);
1031 userPanicEvent->OnContinue();
1032 }
1033 }
1034 #endif
1035
CheckProcessRepeatFreeze(const std::string & eventName,long pid)1036 bool EventLogger::CheckProcessRepeatFreeze(const std::string& eventName, long pid)
1037 {
1038 if (eventName == "THREAD_BLOCK_6S" || eventName == "APP_INPUT_BLOCK") {
1039 long lastPid = lastPid_;
1040 std::string lastEventName = lastEventName_;
1041 lastPid_ = pid;
1042 lastEventName_ = eventName;
1043 if (lastPid == pid) {
1044 HIVIEW_LOGW("eventName=%{public}s, pid=%{public}ld has happened", lastEventName.c_str(), pid);
1045 return true;
1046 }
1047 }
1048 return false;
1049 }
1050
CheckScreenOnRepeat(std::shared_ptr<SysEvent> event)1051 bool EventLogger::CheckScreenOnRepeat(std::shared_ptr<SysEvent> event)
1052 {
1053 std::string eventName = event->eventName_;
1054 if (eventName != "SCREEN_ON" || dbHelper_ == nullptr) {
1055 return false;
1056 }
1057 std::map<std::string, std::vector<std::string>> eventMap;
1058 eventMap["AAFWK"] = {"APP_INPUT_BLOCK", "LIFECYCLE_TIMEOUT", "JS_ERROR", "THREAD_BLOCK_6S"};
1059 eventMap["FRAMEWORK"] = {"IPC_FULL", "SERVICE_BLOCK", "SERVICE_TIMEOUT", "SERVICE_TIMEOUT_WARNING"};
1060 eventMap["RELIABILITY"] = {"CPP_CRASH"};
1061
1062 uint64_t endTime = event->happenTime_;
1063 uint64_t startTime = endTime - QUERY_KEY_PROCESS_EVENT_INTERVAL;
1064 for (const auto &pair : eventMap) {
1065 std::vector<std::string> eventNames = pair.second;
1066 std::vector<SysEvent> records = dbHelper_->SelectRecords(startTime, endTime, pair.first, eventNames);
1067 for (auto& record : records) {
1068 std::string processName = record.GetEventValue(FreezeCommon::EVENT_PROCESS_NAME);
1069 processName = processName.empty() ? record.GetEventValue(FreezeCommon::EVENT_PACKAGE_NAME) : processName;
1070 processName = processName.empty() ? record.GetEventValue("MODULE") : processName;
1071 StringUtil::FormatProcessName(processName);
1072 if (pair.first == "AAFWK" && processName != "com.ohos.sceneboard") {
1073 continue;
1074 }
1075 if (std::find(std::begin(CORE_PROCESSES), std::end(CORE_PROCESSES), processName) !=
1076 std::end(CORE_PROCESSES)) {
1077 HIVIEW_LOGW("avoid SCREEN_ON repeated report, previous eventName=%{public}s, processName=%{public}s",
1078 record.eventName_.c_str(), processName.c_str());
1079 return true;
1080 }
1081 }
1082 }
1083 return false;
1084 }
1085
CheckEventOnContinue(std::shared_ptr<SysEvent> event)1086 void EventLogger::CheckEventOnContinue(std::shared_ptr<SysEvent> event)
1087 {
1088 event->ResetPendingStatus();
1089 event->OnContinue();
1090 }
1091
LogStoreSetting()1092 void EventLogger::LogStoreSetting()
1093 {
1094 logStore_->SetMaxSize(MAX_FOLDER_SIZE);
1095 logStore_->SetMinKeepingFileNumber(MIN_KEEP_FILE_NUM);
1096 LogStoreEx::LogFileComparator comparator = [this](const LogFile &lhs, const LogFile &rhs) {
1097 return rhs < lhs;
1098 };
1099 logStore_->SetLogFileComparator(comparator);
1100 logStore_->Init();
1101 }
1102
OnLoad()1103 void EventLogger::OnLoad()
1104 {
1105 HIVIEW_LOGI("EventLogger OnLoad.");
1106 SetName("EventLogger");
1107 SetVersion("1.0");
1108 LogStoreSetting();
1109 queue_ = std::make_unique<ffrt::queue>(ffrt::queue_concurrent,
1110 "EventLogger_queue",
1111 ffrt::queue_attr().qos(ffrt::qos_default).max_concurrency(DFX_TASK_MAX_CONCURRENCY_NUM));
1112 threadLoop_ = GetWorkLoop();
1113
1114 EventLoggerConfig logConfig;
1115 eventLoggerConfig_ = logConfig.GetConfig();
1116 #ifdef MULTIMODALINPUT_INPUT_ENABLE
1117 activeKeyEvent_ = std::make_unique<ActiveKeyEvent>();
1118 activeKeyEvent_ ->Init(logStore_);
1119 #endif
1120 FreezeCommon freezeCommon;
1121 if (!freezeCommon.Init()) {
1122 HIVIEW_LOGE("FreezeCommon filed.");
1123 return;
1124 }
1125
1126 std::set<std::string> freezeeventNames = freezeCommon.GetPrincipalStringIds();
1127 std::unordered_set<std::string> eventNames;
1128 for (auto& i : freezeeventNames) {
1129 eventNames.insert(i);
1130 }
1131 auto context = GetHiviewContext();
1132 if (context != nullptr) {
1133 auto plugin = context->GetPluginByName("FreezeDetectorPlugin");
1134 if (plugin == nullptr) {
1135 HIVIEW_LOGE("freeze_detecotr plugin is null.");
1136 return;
1137 }
1138 HIVIEW_LOGI("plugin: %{public}s.", plugin->GetName().c_str());
1139 context->AddDispatchInfo(plugin, {}, eventNames, {}, {});
1140
1141 auto ptr = std::static_pointer_cast<EventLogger>(shared_from_this());
1142 context->RegisterUnorderedEventListener(ptr);
1143 AddListenerInfo(Event::MessageType::PLUGIN_MAINTENANCE);
1144 }
1145 #ifdef HITRACE_CATCHER_ENABLE
1146 if (!Parameter::IsBetaVersion()) {
1147 AddListenerInfo(Event::MessageType::TELEMETRY_EVENT);
1148 }
1149 #endif
1150 GetCmdlineContent();
1151 GetRebootReasonConfig();
1152
1153 freezeCommon_ = std::make_shared<FreezeCommon>();
1154 if (freezeCommon_->Init() && freezeCommon_ != nullptr && freezeCommon_->GetFreezeRuleCluster() != nullptr) {
1155 dbHelper_ = std::make_unique<DBHelper>(freezeCommon_);
1156 }
1157 }
1158
OnUnload()1159 void EventLogger::OnUnload()
1160 {
1161 HIVIEW_LOGD("called");
1162 #ifdef WINDOW_MANAGER_ENABLE
1163 EventFocusListener::UnRegisterFocusListener();
1164 #endif
1165 }
1166
GetListenerName()1167 std::string EventLogger::GetListenerName()
1168 {
1169 return "EventLogger";
1170 }
1171
OnUnorderedEvent(const Event & msg)1172 void EventLogger::OnUnorderedEvent(const Event& msg)
1173 {
1174 #ifdef HITRACE_CATCHER_ENABLE
1175 if (msg.messageType_ == Event::MessageType::TELEMETRY_EVENT) {
1176 std::map<std::string, std::string> valuePairs = msg.GetKeyValuePairs();
1177 LogCatcherUtils::HandleTelemetryMsg(valuePairs);
1178 return;
1179 }
1180 #endif
1181
1182 if (CanProcessRebootEvent(msg)) {
1183 auto task = [this] { this->ProcessRebootEvent(); };
1184 threadLoop_->AddEvent(nullptr, nullptr, task);
1185 }
1186 AddBootScanEvent();
1187 }
1188
AddBootScanEvent()1189 void EventLogger::AddBootScanEvent()
1190 {
1191 if (workLoop_ == nullptr) {
1192 HIVIEW_LOGW("workLoop_ is null.");
1193 return;
1194 }
1195
1196 auto task = [this]() {
1197 StartBootScan();
1198 };
1199 workLoop_->AddTimerEvent(nullptr, nullptr, task, BOOT_SCAN_SECONDS, false); // delay 60s
1200 }
1201
CanProcessRebootEvent(const Event & event)1202 bool EventLogger::CanProcessRebootEvent(const Event& event)
1203 {
1204 return (event.messageType_ == Event::MessageType::PLUGIN_MAINTENANCE) &&
1205 (event.eventId_ == Event::EventId::PLUGIN_LOADED);
1206 }
1207
ProcessRebootEvent()1208 void EventLogger::ProcessRebootEvent()
1209 {
1210 if (GetRebootReason() != std::string(LONG_PRESS)) {
1211 return;
1212 }
1213
1214 auto event = std::make_shared<SysEvent>("EventLogger", nullptr, "");
1215
1216 if (event == nullptr) {
1217 HIVIEW_LOGW("event is null.");
1218 return;
1219 }
1220
1221 event->domain_ = DOMAIN_LONGPRESS;
1222 event->eventName_ = STRINGID_LONGPRESS;
1223 event->happenTime_ = TimeUtil::GetMilliseconds();
1224 event->messageType_ = Event::MessageType::SYS_EVENT;
1225 event->SetEventValue(EventStore::EventCol::DOMAIN, DOMAIN_LONGPRESS);
1226 event->SetEventValue(EventStore::EventCol::NAME, STRINGID_LONGPRESS);
1227 event->SetEventValue(EventStore::EventCol::TYPE, 1);
1228 event->SetEventValue(EventStore::EventCol::TS, TimeUtil::GetMilliseconds());
1229 event->SetEventValue(EventStore::EventCol::TZ, TimeUtil::GetTimeZone());
1230 event->SetEventValue("PID", 0);
1231 event->SetEventValue("UID", 0);
1232 event->SetEventValue("PACKAGE_NAME", STRINGID_LONGPRESS);
1233 event->SetEventValue("PROCESS_NAME", STRINGID_LONGPRESS);
1234 event->SetEventValue("MSG", STRINGID_LONGPRESS);
1235 event->SetPrivacy(LONGPRESS_PRIVACY);
1236 event->SetLevel(LONGPRESS_LEVEL);
1237
1238 auto context = GetHiviewContext();
1239 if (context != nullptr) {
1240 auto seq = context->GetPipelineSequenceByName("EventloggerPipeline");
1241 event->SetPipelineInfo("EventloggerPipeline", seq);
1242 event->OnContinue();
1243 }
1244 }
1245
GetRebootReason() const1246 std::string EventLogger::GetRebootReason() const
1247 {
1248 std::string reboot = "";
1249 std::string reset = "";
1250 if (GetMatchString(cmdlineContent_, reboot, std::string(REBOOT_REASON) +
1251 std::string(PATTERN_WITHOUT_SPACE)) &&
1252 GetMatchString(cmdlineContent_, reset, std::string(NORMAL_RESET_TYPE) +
1253 std::string(PATTERN_WITHOUT_SPACE))) {
1254 if (std::any_of(rebootReasons_.begin(), rebootReasons_.end(), [&reboot, &reset](auto& reason) {
1255 return (reason == reboot || reason == reset);
1256 })) {
1257 HIVIEW_LOGI("get reboot reason: LONG_PRESS.");
1258 return LONG_PRESS;
1259 }
1260 }
1261 return "";
1262 }
1263
GetCmdlineContent()1264 void EventLogger::GetCmdlineContent()
1265 {
1266 if (FileUtil::LoadStringFromFile(cmdlinePath_, cmdlineContent_) == false) {
1267 HIVIEW_LOGE("failed to read cmdline:%{public}s.", cmdlinePath_.c_str());
1268 }
1269 }
1270
GetRebootReasonConfig()1271 void EventLogger::GetRebootReasonConfig()
1272 {
1273 rebootReasons_.clear();
1274 if (rebootReasons_.size() == 0) {
1275 rebootReasons_.push_back(AP_S_PRESS6S);
1276 }
1277 }
1278
GetMatchString(const std::string & src,std::string & dst,const std::string & pattern) const1279 bool EventLogger::GetMatchString(const std::string& src, std::string& dst, const std::string& pattern) const
1280 {
1281 std::regex reg(pattern);
1282 std::smatch result;
1283 if (std::regex_search(src, result, reg)) {
1284 dst = StringUtil::TrimStr(result[1], '\n');
1285 return true;
1286 }
1287 return false;
1288 }
1289 } // namespace HiviewDFX
1290 } // namespace OHOS
1291