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