• 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 #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