1 /*
2 * Copyright (c) 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 #include "daily_config.h"
16
17 #include "hiview_logger.h"
18 #include "parameter_ex.h"
19
20 namespace OHOS {
21 namespace HiviewDFX {
22 DEFINE_LOG_TAG("DailyController");
23 namespace {
24 constexpr int64_t INVALID_INT = -1;
25 constexpr int32_t TYPE_FAULT = 1;
26 constexpr int32_t TYPE_STATISTIC = 2;
27 constexpr int32_t TYPE_SECURITY = 3;
28 constexpr int32_t TYPE_BEHAVIOR = 4;
29 }
30
DailyConfig(const std::string & configPath)31 DailyConfig::DailyConfig(const std::string& configPath)
32 {
33 isValid_ = Parse(configPath);
34 }
35
Parse(const std::string & configPath)36 bool DailyConfig::Parse(const std::string& configPath)
37 {
38 auto root = CJsonUtil::ParseJsonRoot(configPath);
39 if (root == nullptr) {
40 HIVIEW_LOGW("failed to parse config file=%{public}s", configPath.c_str());
41 return false;
42 }
43 std::string version = Parameter::GetVersionStr();
44 auto config = CJsonUtil::GetObjectValue(root, version);
45 if (config == nullptr) {
46 HIVIEW_LOGW("failed to parse config file=%{public}s, version=%{public}s",
47 configPath.c_str(), version.c_str());
48 cJSON_Delete(root);
49 return false;
50 }
51 bool ret = ParseCommonThreshold(config) && ParseCustomThreshold(config);
52 cJSON_Delete(root);
53 return ret;
54 }
55
ParseCommonThreshold(const cJSON * config)56 bool DailyConfig::ParseCommonThreshold(const cJSON* config)
57 {
58 const std::string comKey = "Common";
59 auto comConfig = CJsonUtil::GetObjectValue(config, comKey);
60 if (comConfig == nullptr) {
61 HIVIEW_LOGW("failed to parse common config");
62 return false;
63 }
64
65 const std::unordered_map<std::string, int32_t> configMap = {
66 {"FAULT", TYPE_FAULT}, {"STATISTIC", TYPE_STATISTIC},
67 {"SECURITY", TYPE_SECURITY}, {"BEHAVIOR", TYPE_BEHAVIOR}
68 };
69 for (const auto& [key, value] : configMap) {
70 int32_t configValue = CJsonUtil::GetIntValue(comConfig, key, INVALID_INT);
71 if (configValue < 0) {
72 HIVIEW_LOGW("failed to parse common config, key=%{public}s", key.c_str());
73 return false;
74 }
75 commonThresholds_[value] = configValue;
76 HIVIEW_LOGD("parse common config, key=%{public}s, value=%{public}d", key.c_str(), configValue);
77 }
78 return true;
79 }
80
ParseCustomThreshold(const cJSON * config)81 bool DailyConfig::ParseCustomThreshold(const cJSON* config)
82 {
83 const std::string customKey = "Custom";
84 auto customConfig = CJsonUtil::GetObjectValue(config, customKey);
85 if (customConfig == nullptr) {
86 HIVIEW_LOGW("failed to parse custom config");
87 return false;
88 }
89
90 auto childConfig = customConfig->child;
91 while (childConfig) {
92 if (!ParseThresholdOfDomain(childConfig)) {
93 return false;
94 }
95 childConfig = childConfig->next;
96 }
97 return true;
98 }
99
ParseThresholdOfDomain(const cJSON * config)100 bool DailyConfig::ParseThresholdOfDomain(const cJSON* config)
101 {
102 if (!cJSON_IsObject(config)) {
103 HIVIEW_LOGW("failed to parse domain config");
104 return false;
105 }
106
107 std::string domain = config->string;
108 if (domain.empty()) {
109 HIVIEW_LOGW("failed to parse the domain");
110 return false;
111 }
112
113 HIVIEW_LOGD("start to parse domain=%{public}s", domain.c_str());
114 auto childConfig = config->child;
115 while (childConfig) {
116 std::string name;
117 int32_t threshold = 0;
118 if (!ParseThresholdOfName(childConfig, name, threshold)) {
119 return false;
120 }
121 customThresholds_[std::make_pair(domain, name)] = threshold;
122 childConfig = childConfig->next;
123 }
124 return true;
125 }
126
ParseThresholdOfName(const cJSON * config,std::string & name,int32_t & threshold)127 bool DailyConfig::ParseThresholdOfName(const cJSON* config, std::string& name, int32_t& threshold)
128 {
129 if (config->string == nullptr || strlen(config->string) == 0) {
130 HIVIEW_LOGW("failed to parse the name");
131 return false;
132 }
133 name = std::string(config->string);
134
135 int32_t value = static_cast<int32_t>(config->valuedouble);
136 if (value < 0) {
137 HIVIEW_LOGW("failed to parse the value=%{public}d of name=%{public}s", value, name.c_str());
138 return false;
139 }
140 threshold = value;
141 HIVIEW_LOGD("parse name=%{public}s, value=%{public}d", name.c_str(), value);
142 return true;
143 }
144
GetThreshold(const std::string & domain,const std::string name,int32_t type) const145 int32_t DailyConfig::GetThreshold(const std::string& domain, const std::string name, int32_t type) const
146 {
147 auto keyPair = std::make_pair(domain, name);
148 if (customThresholds_.find(keyPair) != customThresholds_.end()) {
149 return customThresholds_.at(keyPair);
150 }
151
152 if (commonThresholds_.find(type) != commonThresholds_.end()) {
153 return commonThresholds_.at(type);
154 }
155
156 return 0;
157 }
158
IsValid() const159 bool DailyConfig::IsValid() const
160 {
161 return isValid_;
162 }
163 } // namespace HiviewDFX
164 } // namespace OHOS
165