1 /*
2 * Copyright (c) 2021-2024 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 "fault_logger_config.h"
17
18 #include <algorithm>
19 #include <limits>
20
21 #ifndef is_ohos_lite
22 #include "cJSON.h"
23 #endif
24
25 #include "dfx_log.h"
26 #include "dfx_socket_request.h"
27 #include "file_ex.h"
28
29 namespace OHOS {
30 namespace HiviewDFX {
31
32 namespace {
33 #ifndef is_ohos_lite
34 constexpr const char* FAULTLOGGER_CONFIG_TAG = "FAULT_LOGGER_CONFIG";
35 constexpr const char* const CONFIG_FILE_PATH = "/system/etc/faultloggerd_config.json";
36 constexpr int32_t KB_TO_B = 10;
37 constexpr int32_t MAX_NUM_INT32 = std::numeric_limits<int32_t>::max();
38
39 constexpr const char* const OVER_TIME_FILE_DELETE_ACTIVE = "ACTIVE";
40 constexpr const char* const OVER_SIZE_ACTION_DELETE = "DELETE";
41
GetStringValueFromJson(const cJSON * json,std::string defaultValue="")42 std::string GetStringValueFromJson(const cJSON* json, std::string defaultValue = "")
43 {
44 if (!cJSON_IsString(json)) {
45 return defaultValue;
46 }
47 return json->valuestring;
48 }
49
GetInt32ValueFromJson(const cJSON * json,int32_t defaultValue=0)50 int32_t GetInt32ValueFromJson(const cJSON* json, int32_t defaultValue = 0)
51 {
52 if (!cJSON_IsNumber(json)) {
53 return defaultValue;
54 }
55 return json->valueint;
56 }
57
ParseSingleFileConfig(const cJSON * tempFile,std::vector<SingleFileConfig> & singleFileConfigs)58 void ParseSingleFileConfig(const cJSON* tempFile, std::vector<SingleFileConfig>& singleFileConfigs)
59 {
60 if (tempFile == nullptr) {
61 DFXLOGE("%{public}s :: failed to Parse TempFileConfig", FAULTLOGGER_CONFIG_TAG);
62 return;
63 }
64 auto& tempFileConfig = singleFileConfigs.emplace_back();
65 tempFileConfig.type = GetInt32ValueFromJson(cJSON_GetObjectItem(tempFile, "type"));
66 tempFileConfig.fileNamePrefix = GetStringValueFromJson(cJSON_GetObjectItem(tempFile, "fileNamePrefix"));
67 int32_t maxFileSize = std::clamp(GetInt32ValueFromJson(cJSON_GetObjectItem(tempFile, "maxSingleFileSizeInKB")),
68 0, MAX_NUM_INT32);
69 tempFileConfig.maxSingleFileSize = static_cast<uint64_t>(maxFileSize) << KB_TO_B;
70 int32_t fileExistTime = GetInt32ValueFromJson(cJSON_GetObjectItem(tempFile, "fileExistTimeInSecond"), -1);
71 tempFileConfig.fileExistTime = std::clamp(fileExistTime, -1, MAX_NUM_INT32);
72 int32_t keeFileCount = GetInt32ValueFromJson(cJSON_GetObjectItem(tempFile, "keepFileCount"), -1);
73 tempFileConfig.keepFileCount = std::clamp(keeFileCount, -1, MAX_NUM_INT32);
74 int32_t maxFileCount = GetInt32ValueFromJson(cJSON_GetObjectItem(tempFile, "maxFileCount"), -1);
75 tempFileConfig.maxFileCount = std::clamp(maxFileCount, tempFileConfig.keepFileCount, MAX_NUM_INT32);
76 if (GetStringValueFromJson(cJSON_GetObjectItem(tempFile, "overTimeFileDeleteType")) ==
77 OVER_TIME_FILE_DELETE_ACTIVE) {
78 tempFileConfig.overTimeFileDeleteType = OverTimeFileDeleteType::ACTIVE;
79 }
80 if (GetStringValueFromJson(cJSON_GetObjectItem(tempFile, "overFileSizeAction")) ==
81 OVER_SIZE_ACTION_DELETE) {
82 tempFileConfig.overFileSizeAction = OverFileSizeAction::DELETE;
83 }
84 }
85
ParseDirectoryConfig(const cJSON * json,DirectoryConfig & directoryConfig)86 void ParseDirectoryConfig(const cJSON* json, DirectoryConfig& directoryConfig)
87 {
88 if (json == nullptr) {
89 DFXLOGE("%{public}s :: failed to Parse directoryConfig", FAULTLOGGER_CONFIG_TAG);
90 return;
91 }
92 directoryConfig.tempFilePath = GetStringValueFromJson(cJSON_GetObjectItem(json, "tempFilePath"));
93 int32_t maxFileSize = std::clamp(GetInt32ValueFromJson(cJSON_GetObjectItem(json, "maxTempFilesSizeInKB")),
94 0, MAX_NUM_INT32);
95 directoryConfig.maxTempFilesSize = static_cast<uint64_t>(maxFileSize) << KB_TO_B;
96 int32_t configClearTime = GetInt32ValueFromJson(cJSON_GetObjectItem(json, "fileClearTimeAfterBootInSecond"));
97 directoryConfig.fileClearTimeAfterBoot = std::clamp(configClearTime, 0, MAX_NUM_INT32);
98 auto* tempFiles = cJSON_GetObjectItem(json, "tempFiles");
99 if (tempFiles != nullptr && cJSON_IsArray(tempFiles)) {
100 int arraySize = cJSON_GetArraySize(tempFiles);
101 for (int i = 0; i < arraySize; i++) {
102 ParseSingleFileConfig(cJSON_GetArrayItem(tempFiles, i), directoryConfig.singleFileConfigs);
103 }
104 }
105 }
106 #endif
107
108 #ifdef FAULTLOGGERD_TEST
InitFaultloggerTestConfig(DirectoryConfig & directoryConfig)109 void InitFaultloggerTestConfig(DirectoryConfig& directoryConfig)
110 {
111 directoryConfig.tempFilePath = "/data/test/faultloggerd/temp";
112 constexpr uint64_t maxTempFilesSize = 10ull << 10; // 10KB
113 directoryConfig.maxTempFilesSize = maxTempFilesSize;
114 constexpr int32_t fileClearTimeAfterBoot = 3; // 3S
115 directoryConfig.fileClearTimeAfterBoot = fileClearTimeAfterBoot;
116 directoryConfig.singleFileConfigs = {
117 {
118 .type = FaultLoggerType::CPP_CRASH,
119 .fileNamePrefix = "cppcrash",
120 .maxSingleFileSize = 5 << 10, // 5KB
121 .fileExistTime = 60,
122 .keepFileCount = 5,
123 .maxFileCount = 7
124 },
125 {
126 .type = FaultLoggerType::JS_HEAP_SNAPSHOT,
127 .fileNamePrefix = "jsheap",
128 .maxSingleFileSize = 5 << 10, // 5KB
129 .overFileSizeAction = OverFileSizeAction::DELETE,
130 .fileExistTime = 3,
131 .overTimeFileDeleteType = OverTimeFileDeleteType::ACTIVE,
132 .keepFileCount = 5,
133 .maxFileCount = 7
134 },
135 {
136 .type = FaultLoggerType::LEAK_STACKTRACE,
137 .fileNamePrefix = "leakstack",
138 .overTimeFileDeleteType = OverTimeFileDeleteType::ACTIVE,
139 .keepFileCount = -1,
140 .maxFileCount = 2,
141 }
142 };
143 }
144 #endif
145 }
146
GetInstance()147 FaultLoggerConfig& FaultLoggerConfig::GetInstance()
148 {
149 static FaultLoggerConfig faultLoggerConfig;
150 return faultLoggerConfig;
151 }
152
153 #ifndef is_ohos_lite
FaultLoggerConfig()154 FaultLoggerConfig::FaultLoggerConfig()
155 {
156 std::string content;
157 OHOS::LoadStringFromFile(CONFIG_FILE_PATH, content);
158 cJSON* json = cJSON_Parse(content.c_str());
159 if (json == nullptr) {
160 DFXLOGE("%{public}s :: failed to parse json from the content of file(%{public}s).",
161 FAULTLOGGER_CONFIG_TAG, CONFIG_FILE_PATH);
162 }
163 ParseDirectoryConfig(json, directoryConfig_);
164 cJSON_Delete(json);
165 #ifdef FAULTLOGGERD_TEST
166 InitFaultloggerTestConfig(directoryConfig_);
167 #endif
168 }
169 #else
FaultLoggerConfig()170 FaultLoggerConfig::FaultLoggerConfig()
171 {
172 directoryConfig_.tempFilePath = "/data/log/faultlog/temp";
173 constexpr uint64_t maxTempFilesSize = 2ull << 30; // 2GB
174 directoryConfig_.maxTempFilesSize = maxTempFilesSize;
175 constexpr int32_t fileClearTimeAfterBoot = 300; // 300s
176 directoryConfig_.fileClearTimeAfterBoot = fileClearTimeAfterBoot;
177 directoryConfig_.singleFileConfigs = {
178 {
179 .type = FaultLoggerType::CPP_CRASH,
180 .fileNamePrefix = "cppcrash",
181 .maxSingleFileSize = 2 << 20, // 2M
182 .keepFileCount = 20,
183 .maxFileCount = 40
184 },
185 {
186 .type = FaultLoggerType::CPP_STACKTRACE,
187 .fileNamePrefix = "stacktrace",
188 .maxSingleFileSize = 2 << 20, // 2M
189 .keepFileCount = 20,
190 .maxFileCount = 40
191 },
192 {
193 .type = FaultLoggerType::LEAK_STACKTRACE,
194 .fileNamePrefix = "leakstack",
195 .maxSingleFileSize = 512 << 10, // 512K
196 .fileExistTime = 60, // 60s
197 .keepFileCount = 20,
198 .maxFileCount = 40
199 },
200 {
201 .type = FaultLoggerType::JIT_CODE_LOG,
202 .fileNamePrefix = "jitcode",
203 .maxSingleFileSize = 128 << 10, // 128K
204 .fileExistTime = 60, // 60s
205 .keepFileCount = 20,
206 .maxFileCount = 40
207 }
208 };
209 #ifdef FAULTLOGGERD_TEST
210 InitFaultloggerTestConfig(directoryConfig_);
211 #endif
212 }
213 #endif
214
GetTempFileConfig() const215 const DirectoryConfig& FaultLoggerConfig::GetTempFileConfig() const
216 {
217 return directoryConfig_;
218 }
219 } // namespace HiviewDFX
220 } // namespace OHOS
221