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 <mutex>
23 #include <regex>
24 #include <sstream>
25 #include <sys/epoll.h>
26 #include <sys/inotify.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <unistd.h>
31 #include <vector>
32
33 #include "parameter.h"
34
35 #include "common_utils.h"
36 #include "dfx_json_formatter.h"
37 #include "event_source.h"
38 #include "file_util.h"
39 #include "freeze_json_util.h"
40 #include "parameter_ex.h"
41 #include "plugin_factory.h"
42 #include "string_util.h"
43 #include "sys_event.h"
44 #include "sys_event_dao.h"
45 #include "time_util.h"
46
47 #include "event_log_task.h"
48 #include "event_logger_config.h"
49 #include "freeze_common.h"
50 #include "utility/trace_collector.h"
51 namespace OHOS {
52 namespace HiviewDFX {
53 REGISTER(EventLogger);
54 DEFINE_LOG_LABEL(0xD002D01, "EventLogger");
IsInterestedPipelineEvent(std::shared_ptr<Event> event)55 bool EventLogger::IsInterestedPipelineEvent(std::shared_ptr<Event> event)
56 {
57 if (event == nullptr) {
58 return false;
59 }
60 if (event->eventId_ > EVENT_MAX_ID) {
61 return false;
62 }
63
64 auto sysEvent = Event::DownCastTo<SysEvent>(event);
65 if (eventLoggerConfig_.find(sysEvent->eventName_) == eventLoggerConfig_.end()) {
66 return false;
67 }
68 HIVIEW_LOGD("event time:%{public}" PRIu64 " jsonExtraInfo is %{public}s", TimeUtil::GetMilliseconds(),
69 sysEvent->AsJsonStr().c_str());
70
71 EventLoggerConfig::EventLoggerConfigData& configOut = eventLoggerConfig_[sysEvent->eventName_];
72 sysEvent->eventName_ = configOut.name;
73 sysEvent->SetValue("eventLog_action", configOut.action);
74 sysEvent->SetValue("eventLog_interval", configOut.interval);
75 return true;
76 }
77
OnEvent(std::shared_ptr<Event> & onEvent)78 bool EventLogger::OnEvent(std::shared_ptr<Event> &onEvent)
79 {
80 if (onEvent == nullptr) {
81 HIVIEW_LOGE("event == nullptr");
82 return false;
83 }
84
85 auto sysEvent = Event::DownCastTo<SysEvent>(onEvent);
86 if (!IsHandleAppfreeze(sysEvent)) {
87 return true;
88 }
89
90 long pid = sysEvent->GetEventIntValue("PID");
91 pid = pid ? pid : sysEvent->GetPid();
92 HIVIEW_LOGI("event: domain=%{public}s, eventName=%{public}s, pid=%{public}ld", sysEvent->domain_.c_str(),
93 sysEvent->eventName_.c_str(), pid);
94
95 if (sysEvent->GetValue("eventLog_action").empty()) {
96 HIVIEW_LOGI("eventName=%{public}s, pid=%{public}ld, eventLog_action is empty.",
97 sysEvent->eventName_.c_str(), pid);
98 UpdateDB(sysEvent, "nolog");
99 return true;
100 }
101
102 sysEvent->OnPending();
103
104 auto task = [this, sysEvent]() {
105 HIVIEW_LOGD("event time:%{public}" PRIu64 " jsonExtraInfo is %{public}s", TimeUtil::GetMilliseconds(),
106 sysEvent->AsJsonStr().c_str());
107 if (!JudgmentRateLimiting(sysEvent)) {
108 return;
109 }
110 this->StartLogCollect(sysEvent);
111 };
112 HIVIEW_LOGI("before add task to eventpool, eventName=%{public}s, pid=%{public}ld",
113 sysEvent->eventName_.c_str(), pid);
114 eventPool_->AddTask(task, "eventlogger");
115 HIVIEW_LOGI("after add task to eventpool, eventName=%{public}s, pid=%{public}ld",
116 sysEvent->eventName_.c_str(), pid);
117 return true;
118 }
119
Getfile(std::shared_ptr<SysEvent> event,std::string & logFile)120 int EventLogger::Getfile(std::shared_ptr<SysEvent> event, std::string& logFile)
121 {
122 std::string idStr = event->eventName_.empty() ? std::to_string(event->eventId_) : event->eventName_;
123 uint64_t logTime = event->happenTime_ / TimeUtil::SEC_TO_MILLISEC;
124 int32_t pid = static_cast<int32_t>(event->GetEventIntValue("PID"));
125 pid = pid ? pid : event->GetPid();
126 logFile = idStr + "-" + std::to_string(pid) + "-"
127 + TimeUtil::TimestampFormatToDate(logTime, "%Y%m%d%H%M%S") + ".log";
128 if (FileUtil::FileExists(LOGGER_EVENT_LOG_PATH + "/" + logFile)) {
129 HIVIEW_LOGW("filename: %{public}s is existed, direct use.", logFile.c_str());
130 UpdateDB(event, logFile);
131 return -1;
132 }
133
134 return logStore_->CreateLogFile(logFile);
135 }
136
StartLogCollect(std::shared_ptr<SysEvent> event)137 void EventLogger::StartLogCollect(std::shared_ptr<SysEvent> event)
138 {
139 std::string logFile;
140 int fd = Getfile(event, logFile);
141 if (fd < 0) {
142 HIVIEW_LOGE("create log file %{public}s failed, %{public}d", logFile.c_str(), fd);
143 return;
144 }
145
146 int jsonFd = -1;
147 if (FreezeJsonUtil::IsAppFreeze(event->eventName_)) {
148 std::string jsonFilePath = FreezeJsonUtil::GetFilePath(event->GetEventIntValue("PID"),
149 event->GetEventIntValue("UID"), event->happenTime_);
150 jsonFd = FreezeJsonUtil::GetFd(jsonFilePath);
151 }
152
153 std::unique_ptr<EventLogTask> logTask = std::make_unique<EventLogTask>(fd, jsonFd, event);
154 std::string cmdStr = event->GetValue("eventLog_action");
155 std::vector<std::string> cmdList;
156 StringUtil::SplitStr(cmdStr, ",", cmdList);
157 for (const std::string& cmd : cmdList) {
158 logTask->AddLog(cmd);
159 }
160
161 const uint32_t placeholder = 3;
162 auto start = TimeUtil::GetMilliseconds();
163 uint64_t startTime = start / TimeUtil::SEC_TO_MILLISEC;
164 std::ostringstream startTimeStr;
165 startTimeStr << "start time: " << TimeUtil::TimestampFormatToDate(startTime, "%Y/%m/%d-%H:%M:%S");
166 startTimeStr << ":" << std::setw(placeholder) << std::setfill('0') <<
167 std::to_string(start % TimeUtil::SEC_TO_MILLISEC);
168 startTimeStr << std::endl;
169 FileUtil::SaveStringToFd(fd, startTimeStr.str());
170 WriteCommonHead(fd, event);
171 WriteFreezeJsonInfo(fd, jsonFd, event);
172 auto ret = logTask->StartCompose();
173 if (ret != EventLogTask::TASK_SUCCESS) {
174 HIVIEW_LOGE("capture fail %{public}d", ret);
175 }
176 auto end = TimeUtil::GetMilliseconds();
177 std::string totalTime = "\n\nCatcher log total time is " + std::to_string(end - start) + "ms\n";
178 FileUtil::SaveStringToFd(fd, totalTime);
179 close(fd);
180 if (jsonFd >= 0) {
181 close(jsonFd);
182 }
183 UpdateDB(event, logFile);
184
185 constexpr int waitTime = 1;
186 auto CheckFinishFun = std::bind(&EventLogger::CheckEventOnContinue, this, event);
187 threadLoop_->AddTimerEvent(nullptr, nullptr, CheckFinishFun, waitTime, false);
188 HIVIEW_LOGI("Collect on finish, name: %{public}s", logFile.c_str());
189 }
190
ParseMsgForMessageAndEventHandler(const std::string & msg,std::string & message,std::string & eventHandlerStr)191 bool ParseMsgForMessageAndEventHandler(const std::string& msg, std::string& message, std::string& eventHandlerStr)
192 {
193 std::vector<std::string> lines;
194 StringUtil::SplitStr(msg, "\n", lines, false, true);
195 bool isGetMessage = false;
196 std::string messageStartFlag = "Fault time:";
197 std::string messageEndFlag = "mainHandler dump is:";
198 std::string eventFlag = "Event {";
199 bool isGetEvent = false;
200 std::regex eventStartFlag(".*((Immediate)|(High)|(Low)) priority event queue information:.*");
201 std::regex eventEndFlag(".*Total size of ((Immediate)|(High)|(Low)) events :.*");
202 std::list<std::string> eventHandlerList;
203 for (auto line = lines.begin(); line != lines.end(); line++) {
204 if ((*line).find(messageStartFlag) != std::string::npos) {
205 isGetMessage = true;
206 continue;
207 }
208 if (isGetMessage) {
209 if ((*line).find(messageEndFlag) != std::string::npos) {
210 isGetMessage = false;
211 HIVIEW_LOGI("Get FreezeJson message jsonStr: %{public}s", message.c_str());
212 continue;
213 }
214 message += StringUtil::TrimStr(*line);
215 continue;
216 }
217 if (regex_match(*line, eventStartFlag)) {
218 isGetEvent = true;
219 continue;
220 }
221 if (isGetEvent) {
222 if (regex_match(*line, eventEndFlag)) {
223 isGetEvent = false;
224 continue;
225 }
226 std::string::size_type pos = (*line).find(eventFlag);
227 if (pos == std::string::npos) {
228 continue;
229 }
230 std::string handlerStr = StringUtil::TrimStr(*line).substr(pos);
231 HIVIEW_LOGI("Get EventHandler str: %{public}s.", handlerStr.c_str());
232 eventHandlerList.push_back(handlerStr);
233 }
234 }
235 eventHandlerStr = FreezeJsonUtil::GetStrByList(eventHandlerList);
236 return true;
237 }
238
ParsePeerBinder(const std::string & binderInfo,std::string & binderInfoJsonStr)239 void ParsePeerBinder(const std::string& binderInfo, std::string& binderInfoJsonStr)
240 {
241 std::vector<std::string> lines;
242 StringUtil::SplitStr(binderInfo, "\\n", lines, false, true);
243 std::list<std::string> infoList;
244 std::map<std::string, std::string> processNameMap;
245
246 for (auto lineIt = lines.begin(); lineIt != lines.end(); lineIt++) {
247 std::string line = *lineIt;
248 if (line.empty() || line.find("async") != std::string::npos) {
249 continue;
250 }
251
252 if (line.find("context") != line.npos) {
253 break;
254 }
255
256 std::istringstream lineStream(line);
257 std::vector<std::string> strList;
258 std::string tmpstr;
259 while (lineStream >> tmpstr) {
260 strList.push_back(tmpstr);
261 }
262 if (strList.size() != 7) { // 7: valid array size
263 continue;
264 }
265 // 2: binder peer id
266 std::string pidStr = strList[2].substr(0, strList[2].find(":"));
267 if (pidStr == "") {
268 continue;
269 }
270 if (processNameMap.find(pidStr) == processNameMap.end()) {
271 std::ifstream cmdLineFile("/proc/" + pidStr + "/cmdline");
272 std::string processName;
273 if (cmdLineFile) {
274 std::getline(cmdLineFile, processName);
275 cmdLineFile.close();
276 processName = StringUtil::FormatCmdLine(processName);
277 processNameMap[pidStr] = processName;
278 } else {
279 HIVIEW_LOGE("Fail to open /proc/%{public}s/cmdline", pidStr.c_str());
280 }
281 }
282 std::string lineStr = line + " " + pidStr + FreezeJsonUtil::WrapByParenthesis(processNameMap[pidStr]);
283 infoList.push_back(lineStr);
284 }
285 binderInfoJsonStr = FreezeJsonUtil::GetStrByList(infoList);
286 }
287
WriteCommonHead(int fd,std::shared_ptr<SysEvent> event)288 bool EventLogger::WriteCommonHead(int fd, std::shared_ptr<SysEvent> event)
289 {
290 std::ostringstream headerStream;
291
292 headerStream << "DOMAIN = " << event->domain_ << std::endl;
293 headerStream << "EVENTNAME = " << event->eventName_ << std::endl;
294 uint64_t logTime = event->happenTime_ / TimeUtil::SEC_TO_MILLISEC;
295 uint64_t logTimeMs = event->happenTime_ % TimeUtil::SEC_TO_MILLISEC;
296 std::string happenTime = TimeUtil::TimestampFormatToDate(logTime, "%Y/%m/%d-%H:%M:%S");
297 headerStream << "TIMESTAMP = " << happenTime << ":" << logTimeMs << std::endl;
298 long pid = event->GetEventIntValue("PID");
299 pid = pid ? pid : event->GetPid();
300 headerStream << "PID = " << pid << std::endl;
301 long uid = event->GetEventIntValue("UID");
302 uid = uid ? uid : event->GetUid();
303 headerStream << "UID = " << uid << std::endl;
304 if (event->GetEventValue("MODULE_NAME") != "") {
305 headerStream << "MODULE_NAME = " << event->GetEventValue("MODULE_NAME") << std::endl;
306 } else {
307 headerStream << "PACKAGE_NAME = " << event->GetEventValue("PACKAGE_NAME") << std::endl;
308 }
309 headerStream << "PROCESS_NAME = " << event->GetEventValue("PROCESS_NAME") << std::endl;
310 headerStream << "eventLog_action = " << event->GetValue("eventLog_action") << std::endl;
311 headerStream << "eventLog_interval = " << event->GetValue("eventLog_interval") << std::endl;
312
313 FileUtil::SaveStringToFd(fd, headerStream.str());
314 return true;
315 }
316
WriteFreezeJsonInfo(int fd,int jsonFd,std::shared_ptr<SysEvent> event)317 bool EventLogger::WriteFreezeJsonInfo(int fd, int jsonFd, std::shared_ptr<SysEvent> event)
318 {
319 std::string msg = StringUtil::ReplaceStr(event->GetEventValue("MSG"), "\\n", "\n");
320 std::string stack;
321 std::string binderInfo = event -> GetEventValue("BINDER_INFO");
322 if (FreezeJsonUtil::IsAppFreeze(event -> eventName_)) {
323 std::string message;
324 std::string eventHandlerStr;
325 ParseMsgForMessageAndEventHandler(msg, message, eventHandlerStr);
326
327 std::string jsonStack = event->GetEventValue("STACK");
328 if (!jsonStack.empty() && jsonStack[0] == '[') { // json stack info should start with '['
329 jsonStack = StringUtil::UnescapeJsonStringValue(jsonStack);
330 if (!DfxJsonFormatter::FormatJsonStack(jsonStack, stack)) {
331 stack = jsonStack;
332 }
333 } else {
334 stack = jsonStack;
335 }
336
337 if (jsonFd >= 0) {
338 HIVIEW_LOGI("success to open FreezeJsonFile! jsonFd: %{public}d", jsonFd);
339 FreezeJsonUtil::WriteKeyValue(jsonFd, "message", message);
340 FreezeJsonUtil::WriteKeyValue(jsonFd, "event_handler", eventHandlerStr);
341 FreezeJsonUtil::WriteKeyValue(jsonFd, "stack", jsonStack);
342 } else {
343 HIVIEW_LOGE("fail to open FreezeJsonFile! jsonFd: %{public}d", jsonFd);
344 }
345
346 if (!binderInfo.empty() && jsonFd >= 0) {
347 std::string binderInfoJsonStr;
348 ParsePeerBinder(binderInfo, binderInfoJsonStr);
349 FreezeJsonUtil::WriteKeyValue(jsonFd, "peer_binder", binderInfoJsonStr);
350 }
351 } else {
352 stack = event->GetEventValue("STACK");
353 }
354
355 std::ostringstream oss;
356 oss << "MSG = " << msg << std::endl;
357 if (!stack.empty()) {
358 oss << StringUtil::UnescapeJsonStringValue(stack) << std::endl;
359 }
360 if (!binderInfo.empty()) {
361 oss << StringUtil::UnescapeJsonStringValue(binderInfo) << std::endl;
362 }
363 FileUtil::SaveStringToFd(fd, oss.str());
364 return true;
365 }
366
JudgmentRateLimiting(std::shared_ptr<SysEvent> event)367 bool EventLogger::JudgmentRateLimiting(std::shared_ptr<SysEvent> event)
368 {
369 int32_t interval = event->GetIntValue("eventLog_interval");
370 if (interval == 0) {
371 return true;
372 }
373
374 int64_t pid = event->GetEventIntValue("PID");
375 pid = pid ? pid : event->GetPid();
376 std::string eventName = event->eventName_;
377 std::string eventPid = std::to_string(pid);
378
379 std::unique_lock<std::mutex> lck(intervalMutex_);
380 std::time_t now = std::time(0);
381 for (auto it = eventTagTime_.begin(); it != eventTagTime_.end();) {
382 if (it->first.find(eventName) != it->first.npos) {
383 if ((now - it->second) >= interval) {
384 it = eventTagTime_.erase(it);
385 continue;
386 }
387 }
388 ++it;
389 }
390
391 std::string tagTimeName = eventName + eventPid;
392 auto it = eventTagTime_.find(tagTimeName);
393 if (it != eventTagTime_.end()) {
394 if ((now - it->second) < interval) {
395 HIVIEW_LOGE("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
396 interval:%{public}" PRId32 " There's not enough interval",
397 event->eventId_, eventName.c_str(), eventPid.c_str(), interval);
398 return false;
399 }
400 }
401 eventTagTime_[tagTimeName] = now;
402 HIVIEW_LOGI("event: id:0x%{public}d, eventName:%{public}s pid:%{public}s. \
403 interval:%{public}" PRId32 " normal interval",
404 event->eventId_, eventName.c_str(), eventPid.c_str(), interval);
405 return true;
406 }
407
UpdateDB(std::shared_ptr<SysEvent> event,std::string logFile)408 bool EventLogger::UpdateDB(std::shared_ptr<SysEvent> event, std::string logFile)
409 {
410 if (logFile == "nolog") {
411 HIVIEW_LOGI("set info_ with nolog into db.");
412 event->SetEventValue(EventStore::EventCol::INFO, "nolog", false);
413 } else {
414 auto logPath = R"~(logPath:)~" + LOGGER_EVENT_LOG_PATH + "/" + logFile;
415 event->SetEventValue(EventStore::EventCol::INFO, logPath, true);
416 }
417 return true;
418 }
419
IsHandleAppfreeze(std::shared_ptr<SysEvent> event)420 bool EventLogger::IsHandleAppfreeze(std::shared_ptr<SysEvent> event)
421 {
422 std::string bundleName = event->GetEventValue("PACKAGE_NAME");
423 if (bundleName.empty()) {
424 bundleName = event->GetEventValue("MODULE_NAME");
425 }
426 if (bundleName.empty()) {
427 return true;
428 }
429
430 const int buffSize = 128;
431 char paramOutBuff[buffSize] = {0};
432 GetParameter("hiviewdfx.appfreeze.filter_bundle_name", "", paramOutBuff, buffSize - 1);
433
434 std::string str(paramOutBuff);
435 if (str.find(bundleName) != std::string::npos) {
436 HIVIEW_LOGW("appfreeze filtration %{public}s.", bundleName.c_str());
437 return false;
438 }
439 return true;
440 }
441
CheckEventOnContinue(std::shared_ptr<SysEvent> event)442 void EventLogger::CheckEventOnContinue(std::shared_ptr<SysEvent> event)
443 {
444 event->ResetPendingStatus();
445 event->OnContinue();
446 }
447
OnLoad()448 void EventLogger::OnLoad()
449 {
450 HIVIEW_LOGI("EventLogger OnLoad.");
451 SetName("EventLogger");
452 SetVersion("1.0");
453 logStore_->SetMaxSize(MAX_FOLDER_SIZE);
454 logStore_->SetMinKeepingFileNumber(MAX_FILE_NUM);
455 logStore_->Init();
456 threadLoop_ = GetWorkLoop();
457
458 EventLoggerConfig logConfig;
459 eventLoggerConfig_ = logConfig.GetConfig();
460
461 eventPool_ = std::make_shared<EventThreadPool>(maxEventPoolCount, "EventLog");
462 eventPool_->Start();
463
464 activeKeyEvent_ = std::make_unique<ActiveKeyEvent>();
465 activeKeyEvent_ ->Init(eventPool_, logStore_);
466 FreezeCommon freezeCommon;
467 if (!freezeCommon.Init()) {
468 HIVIEW_LOGE("FreezeCommon filed.");
469 return;
470 }
471
472 std::set<std::string> freezeeventNames = freezeCommon.GetPrincipalStringIds();
473 std::unordered_set<std::string> eventNames;
474 for (auto& i : freezeeventNames) {
475 eventNames.insert(i);
476 }
477 auto context = GetHiviewContext();
478 if (context != nullptr) {
479 auto plugin = context->GetPluginByName("FreezeDetectorPlugin");
480 HIVIEW_LOGE("plugin plugin %{public}s.", plugin->GetName().c_str());
481 context->AddDispatchInfo(plugin, {}, eventNames, {}, {});
482
483 auto ptr = std::static_pointer_cast<EventLogger>(shared_from_this());
484 context->RegisterUnorderedEventListener(ptr);
485 AddListenerInfo(Event::MessageType::PLUGIN_MAINTENANCE);
486 }
487
488 GetCmdlineContent();
489 GetRebootReasonConfig();
490 }
491
OnUnload()492 void EventLogger::OnUnload()
493 {
494 HIVIEW_LOGD("called");
495 eventPool_->Stop();
496 }
497
GetListenerName()498 std::string EventLogger::GetListenerName()
499 {
500 return "EventLogger";
501 }
502
OnUnorderedEvent(const Event & msg)503 void EventLogger::OnUnorderedEvent(const Event& msg)
504 {
505 if (CanProcessRebootEvent(msg)) {
506 auto task = std::bind(&EventLogger::ProcessRebootEvent, this);
507 threadLoop_->AddEvent(nullptr, nullptr, task);
508 }
509 }
510
CanProcessRebootEvent(const Event & event)511 bool EventLogger::CanProcessRebootEvent(const Event& event)
512 {
513 return (event.messageType_ == Event::MessageType::PLUGIN_MAINTENANCE) &&
514 (event.eventId_ == Event::EventId::PLUGIN_LOADED);
515 }
516
ProcessRebootEvent()517 void EventLogger::ProcessRebootEvent()
518 {
519 if (GetRebootReason() != LONG_PRESS) {
520 return;
521 }
522
523 auto event = std::make_shared<SysEvent>("EventLogger", nullptr, "");
524
525 if (event == nullptr) {
526 HIVIEW_LOGW("event is null.");
527 return;
528 }
529
530 event->domain_ = DOMAIN_LONGPRESS;
531 event->eventName_ = STRINGID_LONGPRESS;
532 event->happenTime_ = TimeUtil::GetMilliseconds();
533 event->messageType_ = Event::MessageType::SYS_EVENT;
534 event->SetEventValue(EventStore::EventCol::DOMAIN, DOMAIN_LONGPRESS);
535 event->SetEventValue(EventStore::EventCol::NAME, STRINGID_LONGPRESS);
536 event->SetEventValue(EventStore::EventCol::TYPE, 1);
537 event->SetEventValue(EventStore::EventCol::TS, TimeUtil::GetMilliseconds());
538 event->SetEventValue(EventStore::EventCol::TZ, TimeUtil::GetTimeZone());
539 event->SetEventValue("PID", 0);
540 event->SetEventValue("UID", 0);
541 event->SetEventValue("PACKAGE_NAME", STRINGID_LONGPRESS);
542 event->SetEventValue("PROCESS_NAME", STRINGID_LONGPRESS);
543 event->SetEventValue("MSG", STRINGID_LONGPRESS);
544
545 auto context = GetHiviewContext();
546 if (context != nullptr) {
547 auto seq = context->GetPipelineSequenceByName("EventloggerPipeline");
548 event->SetPipelineInfo("EventloggerPipeline", seq);
549 event->OnContinue();
550 }
551 }
552
GetRebootReason() const553 std::string EventLogger::GetRebootReason() const
554 {
555 std::string reboot = "";
556 std::string reset = "";
557 if (GetMatchString(cmdlineContent_, reboot, REBOOT_REASON + PATTERN_WITHOUT_SPACE) &&
558 GetMatchString(cmdlineContent_, reset, NORMAL_RESET_TYPE + PATTERN_WITHOUT_SPACE)) {
559 if (std::any_of(rebootReasons_.begin(), rebootReasons_.end(), [&reboot, &reset](auto& reason) {
560 return (reason == reboot || reason == reset);
561 })) {
562 HIVIEW_LOGI("get reboot reason: LONG_PRESS.");
563 return LONG_PRESS;
564 }
565 }
566 return "";
567 }
568
GetCmdlineContent()569 void EventLogger::GetCmdlineContent()
570 {
571 if (FileUtil::LoadStringFromFile(cmdlinePath_, cmdlineContent_) == false) {
572 HIVIEW_LOGE("failed to read cmdline:%{public}s.", cmdlinePath_.c_str());
573 }
574 }
575
GetRebootReasonConfig()576 void EventLogger::GetRebootReasonConfig()
577 {
578 rebootReasons_.clear();
579 if (rebootReasons_.size() == 0) {
580 rebootReasons_.push_back(AP_S_PRESS6S);
581 }
582 }
583
GetMatchString(const std::string & src,std::string & dst,const std::string & pattern) const584 bool EventLogger::GetMatchString(const std::string& src, std::string& dst, const std::string& pattern) const
585 {
586 std::regex reg(pattern);
587 std::smatch result;
588 if (std::regex_search(src, result, reg)) {
589 dst = StringUtil::TrimStr(result[1], '\n');
590 return true;
591 }
592 return false;
593 }
594 } // namesapce HiviewDFX
595 } // namespace OHOS
596