1 /*
2 * Copyright (c) 2023 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
16 #include "freeze_json_util.h"
17
18 #include <list>
19 #include <map>
20 #include <fcntl.h>
21 #include <fstream>
22 #include <sstream>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25
26 #include "file_util.h"
27 #include "string_util.h"
28
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace FreezeJsonUtil {
IncludeWith(std::list<std::string> list,const std::string & target)32 bool IncludeWith(std::list<std::string> list, const std::string& target)
33 {
34 for (auto it = list.begin(); it != list.end(); it++) {
35 if (target == *it) {
36 return true;
37 }
38 }
39 return false;
40 }
41
IsAppFreeze(const std::string & eventName)42 bool IsAppFreeze(const std::string& eventName)
43 {
44 return IncludeWith(APPFREEZE_TYPE_LIST, eventName);
45 }
46
GetFilePath(long pid,long uid,unsigned long long timestamp)47 std::string GetFilePath(long pid, long uid, unsigned long long timestamp)
48 {
49 std::stringstream ss;
50 ss << LOGGER_FREEZEJSON_LOG_PATH << "/" << pid << "-" << uid << "-" << timestamp;
51 return ss.str();
52 }
53
GetFd(const std::string & filePath)54 int GetFd(const std::string& filePath)
55 {
56 if (!FileUtil::FileExists(LOGGER_FREEZEJSON_LOG_PATH)) {
57 FileUtil::ForceCreateDirectory(LOGGER_FREEZEJSON_LOG_PATH);
58 }
59 if (!FileUtil::IsLegalPath(filePath)) {
60 return -1;
61 }
62 return open(filePath.c_str(), O_CREAT | O_RDWR | O_APPEND, DEFAULT_LOG_FILE_MODE);
63 }
64
DelFile(const std::string & filePath)65 bool DelFile(const std::string& filePath)
66 {
67 if (!FileUtil::FileExists(filePath)) {
68 return true;
69 }
70 return FileUtil::RemoveFile(filePath);
71 }
72
CountSubStr(const std::string & str,const std::string & subStr)73 int CountSubStr(const std::string& str, const std::string& subStr)
74 {
75 size_t pos = 0;
76 int count = 0;
77 while ((pos = str.find(subStr, pos)) < str.size()) {
78 count++;
79 pos += subStr.size();
80 }
81 return count;
82 }
83
FormatCollect(std::map<std::string,std::list<std::string>> & collectMap,FreezeJsonCollector & jsonCollector)84 void FormatCollect(std::map<std::string, std::list<std::string>>& collectMap, FreezeJsonCollector& jsonCollector)
85 {
86 if (!collectMap["timestamp"].empty()) {
87 jsonCollector.timestamp = std::stoull(collectMap["timestamp"].front());
88 }
89
90 if (!collectMap["pid"].empty()) {
91 jsonCollector.pid = std::stol(collectMap["pid"].front());
92 }
93
94 if (!collectMap["uid"].empty()) {
95 jsonCollector.uid = std::stol(collectMap["uid"].front());
96 }
97
98 if (!collectMap["domain"].empty()) {
99 jsonCollector.domain = collectMap["domain"].front();
100 }
101
102 if (!collectMap["stringId"].empty()) {
103 jsonCollector.stringId = collectMap["stringId"].front();
104 }
105
106 if (!collectMap["package_name"].empty()) {
107 jsonCollector.package_name = collectMap["package_name"].front();
108 }
109
110 if (!collectMap["process_name"].empty()) {
111 jsonCollector.process_name = collectMap["process_name"].front();
112 }
113
114 if (!collectMap["message"].empty()) {
115 // use the earliest message
116 jsonCollector.message = collectMap["message"].front();
117 }
118
119 if (!collectMap["peer_binder"].empty()) {
120 // use the earliest peer_binder
121 jsonCollector.peer_binder = collectMap["peer_binder"].front();
122 }
123
124 if (!collectMap["event_handler"].empty()) {
125 // use the latest peer_binder
126 jsonCollector.event_handler = *(collectMap["event_handler"].rbegin());
127 if (collectMap["event_handler"].size() != 1) {
128 std::string flag = "Event {";
129 jsonCollector.event_handler_3s_size =
130 std::to_string(CountSubStr(*(collectMap["event_handler"].begin()), flag));
131 jsonCollector.event_handler_6s_size =
132 std::to_string(CountSubStr(*(collectMap["event_handler"].rbegin()), flag));
133 }
134 }
135
136 if (!collectMap["stack"].empty()) {
137 // use the earliest peer_binder
138 jsonCollector.stack = collectMap["stack"].front();
139 }
140
141 if (!collectMap["appRunningUniqueId"].empty()) {
142 jsonCollector.appRunningUniqueId = collectMap["appRunningUniqueId"].front();
143 }
144 }
145
LoadCollectorFromFile(const std::string & filePath,FreezeJsonCollector & jsonCollector)146 void LoadCollectorFromFile(const std::string& filePath, FreezeJsonCollector& jsonCollector)
147 {
148 std::map<std::string, std::list<std::string>> collectMap;
149 std::string lineStr;
150 if (!FileUtil::FileExists(filePath)) {
151 return;
152 }
153 std::ifstream jsonFile(filePath);
154 while (std::getline(jsonFile, lineStr)) {
155 std::string::size_type pos = lineStr.find(COMMON_EQUAL);
156 if (pos == std::string::npos) {
157 continue;
158 }
159 std::string key = lineStr.substr(0, pos);
160 if (!IncludeWith(KEY_IN_LOGFILE, key)) {
161 continue;
162 }
163 std::string value = lineStr.substr(pos + COMMON_EQUAL.size());
164 collectMap[key].push_back(value);
165 }
166 jsonFile.close();
167 FormatCollect(collectMap, jsonCollector);
168 }
169
HasBeenWrapped(const std::string & target)170 bool HasBeenWrapped(const std::string& target)
171 {
172 std::string::size_type minLen = 2;
173 if (target.size() < minLen) {
174 return false;
175 }
176 char head = target[0];
177 char foot = target[target.size() - 1];
178 return (head == COMMON_QUOTE[0] && foot == COMMON_QUOTE[0]) ||
179 (head == COMMON_LEFT_BRACE[0] && foot == COMMON_RIGHT_BRACE[0]) ||
180 (head == COMMON_LEFT_SQUARE_BRACKET[0] && foot == COMMON_RIGHT_SQUARE_BREAKET[0]);
181 }
182
WrapByParenthesis(const std::string & wrapped)183 std::string WrapByParenthesis(const std::string& wrapped)
184 {
185 return COMMON_LEFT_PARENTHESIS + wrapped + COMMON_RIGHT_PARENTHESIS;
186 }
187
WrapBySquareBracket(const std::string & wrapped)188 std::string WrapBySquareBracket(const std::string& wrapped)
189 {
190 return COMMON_LEFT_SQUARE_BRACKET + wrapped + COMMON_RIGHT_SQUARE_BREAKET;
191 }
192
WrapByBrace(const std::string & wrapped)193 std::string WrapByBrace(const std::string& wrapped)
194 {
195 return COMMON_LEFT_BRACE + wrapped + COMMON_RIGHT_BRACE;
196 }
197
MergeKeyValueList(std::list<std::string> & list)198 std::string MergeKeyValueList(std::list<std::string>& list)
199 {
200 std::stringstream jsonSs;
201 if (!list.empty()) {
202 auto it = list.begin();
203 jsonSs << *it;
204 it++;
205 while (it != list.end()) {
206 jsonSs << COMMON_COMMA << *it;
207 it++;
208 }
209 }
210 return WrapByBrace(jsonSs.str());
211 }
212
213 } // namespace FreezeJsonUtil
214 } // namespace HiviewDFX
215 } // namespace OHOS