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