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