1 /*
2 * Copyright (c) 2024-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
16 #include "export_config_parser.h"
17
18 #include <fstream>
19
20 #include "cjson_util.h"
21 #include "file_util.h"
22 #include "hiview_logger.h"
23 #include "parameter_ex.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 DEFINE_LOG_TAG("HiView-EventExportConfig");
28 namespace {
29 constexpr char EXPORT_SWITCH_PARAM_KEY[] = "exportSwitchParam";
30 constexpr char SYS_UPGRADE_PARAM_KEY[] = "sysUpgradeParam";
31 constexpr char SETTING_PARAM_NAME_KEY[] = "name";
32 constexpr char SETTING_PARAM_ENABLED_KEY[] = "enabledValue";
33 constexpr char EXPORT_DIR[] = "exportDir";
34 constexpr char EXPORT_DIR_MAX_CAPACITY[] = "exportDirMaxCapacity";
35 constexpr char EXPORT_SINGLE_FILE_MAX_SIZE[] = "exportSingleFileMaxSize";
36 constexpr char TASK_EXECUTING_CYCLE[] = "taskExecutingCycle";
37 constexpr char EXPORT_EVENT_LIST_CONFIG_PATHS[] = "exportEventListConfigPaths";
38 constexpr char FILE_STORED_MAX_DAY_CNT[] = "fileStoredMaxDayCnt";
39 constexpr char EXPORT_TASK_TYPE[] = "exportTaskType";
40 constexpr char INHERITED_MODULE[] = "inheritedModule";
41 constexpr int32_t INVALID_INT_VAL = -1;
42
ParseIntFromCfg(cJSON * json,std::string & areaTag,std::string & versionTag,int64_t & val)43 bool ParseIntFromCfg(cJSON* json, std::string& areaTag, std::string& versionTag, int64_t& val)
44 {
45 if (!cJSON_IsObject(json) || !cJSON_HasObjectItem(json, areaTag.c_str())) {
46 return false;
47 }
48 auto areaJson = cJSON_GetObjectItem(json, areaTag.c_str());
49 if (!cJSON_IsObject(areaJson) || !cJSON_HasObjectItem(areaJson, versionTag.c_str())) {
50 return false;
51 }
52 auto versionJson = cJSON_GetObjectItem(areaJson, versionTag.c_str());
53 if (!cJSON_IsNumber(versionJson)) {
54 return false;
55 }
56 double num = cJSON_GetNumberValue(versionJson);
57 if (num < static_cast<double>(std::numeric_limits<int64_t>::lowest()) ||
58 num > static_cast<double>(std::numeric_limits<int64_t>::max())) {
59 return false;
60 }
61 val = static_cast<int64_t>(num);
62 return true;
63 }
64
RebuildExportDir(std::shared_ptr<ExportConfig> config,bool appendTaskType)65 void RebuildExportDir(std::shared_ptr<ExportConfig> config, bool appendTaskType)
66 {
67 config->exportDir = FileUtil::IncludeTrailingPathDelimiter(config->exportDir);
68 config->exportDir = FileUtil::IncludeTrailingPathDelimiter(config->exportDir.append("sys_event_export"));
69 if (!appendTaskType) {
70 HIVIEW_LOGI("no need to rebuild export dir: %{public}s", config->exportDir.c_str());
71 return;
72 }
73 std::string dirSuffix("0");
74 if (config->taskType > ALL_EVENT_TASK_TYPE) {
75 dirSuffix = std::to_string(config->taskType);
76 }
77 config->exportDir = FileUtil::IncludeTrailingPathDelimiter(config->exportDir.append(dirSuffix));
78 HIVIEW_LOGI("rebuild export dir to %{public}s", config->exportDir.c_str());
79 }
80 }
81
ExportConfigParser(const std::string & configFile,const std::string & moduleName)82 ExportConfigParser::ExportConfigParser(const std::string& configFile, const std::string& moduleName)
83 {
84 HIVIEW_LOGI("cfg file is %{public}s", configFile.c_str());
85 jsonRoot_ = CJsonUtil::ParseJsonRoot(configFile);
86 moduleName_ = moduleName;
87 }
88
~ExportConfigParser()89 ExportConfigParser::~ExportConfigParser()
90 {
91 if (jsonRoot_ == nullptr) {
92 return;
93 }
94 cJSON_Delete(jsonRoot_);
95 }
96
Parse()97 std::shared_ptr<ExportConfig> ExportConfigParser::Parse()
98 {
99 if (jsonRoot_ == nullptr || !cJSON_IsObject(jsonRoot_)) {
100 HIVIEW_LOGE("the file format of export config file is not json.");
101 return nullptr;
102 }
103 auto exportConfig = std::make_shared<ExportConfig>();
104 exportConfig->moduleName = moduleName_;
105 // read event export config files
106 CJsonUtil::GetStringArray(jsonRoot_, EXPORT_EVENT_LIST_CONFIG_PATHS, exportConfig->eventsConfigFiles);
107 // parse export switch setting parameter
108 if (!ParseSettingDbParam(exportConfig->exportSwitchParam, EXPORT_SWITCH_PARAM_KEY)) {
109 HIVIEW_LOGE("failed to parse export switch parameter.");
110 return nullptr;
111 }
112 // parse system upgrade setting parameter
113 if (!ParseSettingDbParam(exportConfig->sysUpgradeParam, SYS_UPGRADE_PARAM_KEY)) {
114 HIVIEW_LOGI("failed to parse system upgrade parameter.");
115 }
116 // parse residual content of the config file
117 if (!ParseResidualContent(exportConfig)) {
118 HIVIEW_LOGE("failed to parse residual content.");
119 return nullptr;
120 }
121 return exportConfig;
122 }
123
ParseSettingDbParam(SettingDbParam & settingDbParam,const std::string & paramKey)124 bool ExportConfigParser::ParseSettingDbParam(SettingDbParam& settingDbParam, const std::string& paramKey)
125 {
126 cJSON* settingDbParamJson = cJSON_GetObjectItem(jsonRoot_, paramKey.c_str());
127 if (settingDbParamJson == nullptr || !cJSON_IsObject(settingDbParamJson)) {
128 HIVIEW_LOGW("settingDbParam configured is invalid.");
129 return false;
130 }
131 settingDbParam.name = CJsonUtil::GetStringValue(settingDbParamJson, SETTING_PARAM_NAME_KEY);
132 if (settingDbParam.name.empty()) {
133 HIVIEW_LOGW("name of setting db parameter configured is invalid.");
134 return false;
135 }
136 settingDbParam.enabledVal = CJsonUtil::GetStringValue(settingDbParamJson, SETTING_PARAM_ENABLED_KEY);
137 if (settingDbParam.enabledVal.empty()) {
138 HIVIEW_LOGW("enabled value of setting db parameter configured is invalid.");
139 return false;
140 }
141 return true;
142 }
143
ParseResidualContent(std::shared_ptr<ExportConfig> config)144 bool ExportConfigParser::ParseResidualContent(std::shared_ptr<ExportConfig> config)
145 {
146 // read export diectory
147 config->exportDir = CJsonUtil::GetStringValue(jsonRoot_, EXPORT_DIR);
148 if (config->exportDir.empty()) {
149 HIVIEW_LOGW("exportDirectory configured is invalid.");
150 return false;
151 }
152 // read maximum capacity of the export diectory
153 config->maxCapcity = CJsonUtil::GetIntValue(jsonRoot_, EXPORT_DIR_MAX_CAPACITY, INVALID_INT_VAL);
154 if (config->maxCapcity == INVALID_INT_VAL) {
155 HIVIEW_LOGW("exportDirMaxCapacity configured is invalid.");
156 return false;
157 }
158 // read maximum size of the export single event file
159 config->maxSize = CJsonUtil::GetIntValue(jsonRoot_, EXPORT_SINGLE_FILE_MAX_SIZE, INVALID_INT_VAL);
160 if (config->maxSize == INVALID_INT_VAL) {
161 HIVIEW_LOGW("exportSingleFileMaxSize configured is invalid.");
162 return false;
163 }
164 config->dayCnt = CJsonUtil::GetIntValue(jsonRoot_, FILE_STORED_MAX_DAY_CNT, INVALID_INT_VAL);
165 if (config->dayCnt == INVALID_INT_VAL) {
166 HIVIEW_LOGW("fileStoredMaxDayCnt configured is invalid.");
167 return false;
168 }
169 config->inheritedModule = CJsonUtil::GetStringValue(jsonRoot_, INHERITED_MODULE);
170 if (!ParseTaskType(config) || !ParseTaskExecutingCycle(config)) {
171 return false;
172 }
173 return true;
174 }
175
ParseTaskType(std::shared_ptr<ExportConfig> config)176 bool ExportConfigParser::ParseTaskType(std::shared_ptr<ExportConfig> config)
177 {
178 auto taskTypeJson = cJSON_GetObjectItem(jsonRoot_, EXPORT_TASK_TYPE);
179 if (taskTypeJson == nullptr) {
180 // old cfg file
181 HIVIEW_LOGI("task type isn't configured for module: %{public}s", config->moduleName.c_str());
182 config->taskType = ALL_EVENT_TASK_TYPE;
183 RebuildExportDir(config, false);
184 return true;
185 }
186 if (!cJSON_IsObject(taskTypeJson)) {
187 return false;
188 }
189 std::string areaTag(Parameter::IsOversea() ? "oversea" : "domestic");
190 std::string versionTag(Parameter::IsBetaVersion() ? "beta" : "commercial");
191 int64_t taskType = INVALID_TASK_TYPE;
192 if (!ParseIntFromCfg(taskTypeJson, areaTag, versionTag, taskType)) {
193 HIVIEW_LOGE("failed to parse task type");
194 config->taskType = INVALID_TASK_TYPE;
195 return false;
196 }
197 config->taskType = taskType;
198 HIVIEW_LOGI("task type is configured as object for module: %{public}s, value is %{public}" PRId16 "",
199 config->moduleName.c_str(), config->taskType);
200 config->needPostEvent = true;
201 RebuildExportDir(config, true);
202 return true;
203 }
204
ParseTaskExecutingCycle(std::shared_ptr<ExportConfig> config)205 bool ExportConfigParser::ParseTaskExecutingCycle(std::shared_ptr<ExportConfig> config)
206 {
207 auto taskCycleJson = cJSON_GetObjectItem(jsonRoot_, TASK_EXECUTING_CYCLE);
208 if (taskCycleJson == nullptr) {
209 config->taskCycle = 0;
210 return false;
211 }
212 if (cJSON_IsNumber(taskCycleJson)) {
213 config->taskCycle = CJsonUtil::GetIntValue(jsonRoot_, TASK_EXECUTING_CYCLE);
214 HIVIEW_LOGI("task cycle is configured as number for module: %{public}s, value is %{public}" PRId64 "",
215 config->moduleName.c_str(), config->taskCycle);
216 return true;
217 }
218 if (!cJSON_IsObject(taskCycleJson)) {
219 return false;
220 }
221 std::string areaTag(Parameter::IsOversea() ? "oversea" : "domestic");
222 std::string versionTag(Parameter::IsBetaVersion() ? "beta" : "commercial");
223 if (!ParseIntFromCfg(taskCycleJson, areaTag, versionTag, config->taskCycle)) {
224 HIVIEW_LOGE("failed to parse task type");
225 config->taskCycle = 0;
226 return false;
227 }
228 HIVIEW_LOGI("task cycle is configured as object for module: %{public}s, value is %{public}" PRId64 "",
229 config->moduleName.c_str(), config->taskCycle);
230 return true;
231 }
232 } // HiviewDFX
233 } // OHOS