• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 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_util.h"
16 
17 #include <vector>
18 
19 #include "hiview_logger.h"
20 #include "file_util.h"
21 #include "time_util.h"
22 #include "string_util.h"
23 #include "log_file.h"
24 
25 namespace OHOS {
26 namespace HiviewDFX {
27 namespace {
28     static const int LOG_MAP_SIZE = 2;
29     static const int  INDEX_OF_TYPE = 0;
30     static const int  INDEX_OF_MOUDLE = 1;
31     static const int  INDEX_OF_UID = 2;
32     static const int  INDEX_OF_TIME = 3;
33     static const uint32_t INDEX_OF_TIMESTAMP = 4;
34     static const uint32_t FREEZE_VECTOR_SIZE = 5;
35     static constexpr time_t FORTYEIGHT_HOURS = 48 * 60 * 60;
36     static const size_t FREEZE_FILE_NAME_SIZE = 6;
37     static const int FREEZE_UID_INDEX = 4;
38     static constexpr const char* const APPFREEZE = "appfreeze";
39     static constexpr const char* const SYSFREEZE = "sysfreeze";
40     static constexpr const char* const SYSWARNING = "syswarning";
41     static constexpr const char* const EVENT_PID = "PID";
42     static constexpr const char* const EVENT_REASON = "STRINGID";
43     static constexpr const char* const EVENT_TIMESTAMP = "TIMESTAMP";
44     static constexpr const char* const FREEZE_PREFIX[] = {
45         APPFREEZE, SYSFREEZE, SYSWARNING
46     };
47     static constexpr const char* const FREEZE_LOG_SEQUENCE[] = {
48         EVENT_PID, EVENT_REASON
49     };
50     static constexpr const char* const FREEZE_DETECTOR_PATH = "/data/log/faultlog/freeze/";
51 } // namespace
52 
53 DEFINE_LOG_LABEL(0xD002D01, "EventLogger-EventLoggerUtil");
54 
GetFileLastAccessTimeStamp(const std::string & fileName)55 time_t GetFileLastAccessTimeStamp(const std::string& fileName)
56 {
57     struct stat fileInfo;
58     if (stat(fileName.c_str(), &fileInfo) != 0) {
59         HIVIEW_LOGI("get log info failed, errno:%{public}d, fileName:%{public}s",
60             errno, fileName.c_str());
61         return 0;
62     }
63     return fileInfo.st_atime;
64 }
65 
ExtractInfoFromFileName(const std::string & fileName)66 FaultLogInfoInner ExtractInfoFromFileName(const std::string& fileName)
67 {
68     FaultLogInfoInner info;
69     std::vector<std::string> splitStr;
70 
71     StringUtil::SplitStr(fileName, "-", splitStr);
72     if (splitStr.size() == FREEZE_VECTOR_SIZE) {
73         std::string type = splitStr[INDEX_OF_TYPE];
74         info.faultLogType = (type == APPFREEZE) ? FaultLogType::APP_FREEZE : ((type == SYSFREEZE) ?
75             FaultLogType::SYS_FREEZE : FaultLogType::SYS_WARNING);
76         info.summary = type + ": ";
77         info.module = splitStr[INDEX_OF_MOUDLE];
78         StringUtil::ConvertStringTo<uint32_t>(splitStr[INDEX_OF_UID], info.id);
79         info.sectionMaps[EVENT_TIMESTAMP] = splitStr[INDEX_OF_TIME];
80         std::string timeStamp = splitStr[INDEX_OF_TIMESTAMP].substr(0, splitStr[INDEX_OF_TIMESTAMP].find(".log"));
81         StringUtil::ConvertStringTo<uint64_t>(timeStamp, info.time);
82     }
83     return info;
84 }
85 
ParseFaultLogInfoFromFile(const std::string & path,const std::string & fileName)86 FaultLogInfoInner ParseFaultLogInfoFromFile(const std::string &path, const std::string &fileName)
87 {
88     FaultLogInfoInner info = ExtractInfoFromFileName(fileName);
89     info.logPath = path;
90     std::ifstream logFile(path);
91     std::string line;
92     while (std::getline(logFile, line)) {
93         if (!logFile.good() || info.sectionMaps.size() == LOG_MAP_SIZE) {
94             break;
95         }
96         if (line.empty()) {
97             continue;
98         }
99         for (auto &item : FREEZE_LOG_SEQUENCE) {
100             std::string sectionHead = std::string(item);
101             if (line.find(sectionHead) == std::string::npos) {
102                 continue;
103             }
104             info.sectionMaps[sectionHead] = line.substr(line.find_first_of(":") + 1);
105         }
106     }
107 
108     info.reason = info.sectionMaps[EVENT_REASON];
109     int32_t pid = 0;
110     StringUtil::ConvertStringTo<int32_t>(info.sectionMaps[EVENT_PID], pid);
111     info.pid = pid;
112     info.summary += info.module + " " + info.reason + " at " + info.sectionMaps[EVENT_TIMESTAMP];
113     HIVIEW_LOGI("log info, pid:%{public}u, id:%{public}u, module:%{public}s, time:%{public}" PRIu64
114         ", summary:%{public}s", info.pid, info.id, info.module.c_str(), info.time, info.summary.c_str());
115     return info;
116 }
117 
StartBootScan()118 void StartBootScan()
119 {
120     std::vector<std::string> files;
121     time_t now = time(nullptr);
122     FileUtil::GetDirFiles(FREEZE_DETECTOR_PATH, files);
123     for (const auto& file : files) {
124         // if file type is not freeze, skip!
125         std::string fileName = FileUtil::ExtractFileName(file);
126         std::string type = fileName.substr(0, fileName.find("-"));
127         if (std::find(std::begin(FREEZE_PREFIX), std::end(FREEZE_PREFIX), type) == std::end(FREEZE_PREFIX)) {
128             HIVIEW_LOGI("Skip this file:%{public}s type:%{public}s that the type is not appfreeze sysfreeze "
129                 "syswarning.", file.c_str(), type.c_str());
130             continue;
131         }
132         time_t lastAccessTime = GetFileLastAccessTimeStamp(file);
133         if (now - lastAccessTime > FORTYEIGHT_HOURS) {
134             HIVIEW_LOGI("Skip this file(%{public}s) that were created 48 hours ago.", file.c_str());
135             continue;
136         }
137         auto info = ParseFaultLogInfoFromFile(file, fileName);
138         HIVIEW_LOGI("Boot scan file: %{public}s.", file.c_str());
139         AddFaultLog(info);
140     }
141 }
142 
GetUidFromFileName(const std::string & fileName)143 int32_t GetUidFromFileName(const std::string& fileName)
144 {
145     std::vector<std::string> splitStr;
146     StringUtil::SplitStr(fileName, "-", splitStr);
147     int32_t id = 0;
148     if (splitStr.size() == FREEZE_FILE_NAME_SIZE) {
149         StringUtil::ConvertStringTo<int32_t>(splitStr[FREEZE_UID_INDEX], id);
150     }
151     return id;
152 }
153 
CreateLogFileFilter(int32_t id,const std::string & filePrefix)154 LogStoreEx::LogFileFilter CreateLogFileFilter(int32_t id, const std::string& filePrefix)
155 {
156     LogStoreEx::LogFileFilter filter = [id, filePrefix](const LogFile &file) {
157         if (file.name_.find(filePrefix) == std::string::npos) {
158             return false;
159         }
160         int fileId = GetUidFromFileName(file.name_);
161         if (fileId != id) {
162             return false;
163         }
164 
165         return true;
166     };
167     return filter;
168 }
169 } // namespace HiviewDFX
170 } // namespace OHOS
171