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