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