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 "event_threshold_manager.h"
17
18 #include <fstream>
19
20 #include "file_util.h"
21 #include "logger.h"
22
23 namespace OHOS {
24 namespace HiviewDFX {
25 namespace EventThreshold {
26 DEFINE_LOG_TAG("HiView-EventThresholdManager");
27 namespace {
28 const std::string DEFAULT_THRESHOLD_FILE_NAME = "/system/etc/hiview/hisysevent_threshold.json";
29 constexpr char USERS_KEY[] = "USERS";
30 constexpr char NAME_KEY[] = "NAME";
31 constexpr char TYPE_KEY[] = "TYPE";
32 constexpr char CONFIGS_KEY[] = "CONFIGS";
33 constexpr char QUERY_RULE_LIMIT_KEY[] = "QUERY_RULE_LIMIT";
34 constexpr size_t DEFAULT_QUERY_RULE_LIMIT = 100;
35 constexpr size_t QUERY_RULE_MAX_LIMIT = 1000;
36
ReadEventThresholdConfigsFromFile(const std::string & path,Json::Value & thresholds)37 bool ReadEventThresholdConfigsFromFile(const std::string& path, Json::Value& thresholds)
38 {
39 std::ifstream fin(path, std::ifstream::binary);
40 Json::CharReaderBuilder jsonRBuilder;
41 Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
42 JSONCPP_STRING errs;
43 return parseFromStream(jsonRBuilder, fin, &thresholds, &errs);
44 }
45 }
46
EventThresholdManager()47 EventThresholdManager::EventThresholdManager()
48 {
49 if (!ParseThresholdFile(DEFAULT_THRESHOLD_FILE_NAME)) {
50 HIVIEW_LOGE("failed to parse threshold file: %{public}s.", DEFAULT_THRESHOLD_FILE_NAME.c_str());
51 return;
52 }
53 }
54
GetInstance()55 EventThresholdManager& EventThresholdManager::GetInstance()
56 {
57 static EventThresholdManager instance;
58 return instance;
59 }
60
GetQueryRuleLimit(const std::string & name,ProcessType type)61 size_t EventThresholdManager::GetQueryRuleLimit(const std::string& name, ProcessType type)
62 {
63 for (auto& user : sysEventUsers_) {
64 std::string userName;
65 user.GetName(userName);
66 if (name == userName && user.GetProcessType() == type) {
67 Configs config;
68 user.GetConfigs(config);
69 return config.queryRuleLimit;
70 }
71 }
72 return DEFAULT_QUERY_RULE_LIMIT;
73 }
74
GetDefaultQueryRuleLimit()75 size_t EventThresholdManager::GetDefaultQueryRuleLimit()
76 {
77 return DEFAULT_QUERY_RULE_LIMIT;
78 }
79
ParseThresholdFile(const std::string & path)80 bool EventThresholdManager::ParseThresholdFile(const std::string& path)
81 {
82 if (!FileUtil::FileExists(path)) {
83 HIVIEW_LOGE("threshold file not exist.");
84 return false;
85 }
86 Json::Value thresholds;
87 if (!ReadEventThresholdConfigsFromFile(path, thresholds)) {
88 HIVIEW_LOGE("failed to parse threshold file.");
89 return false;
90 }
91 return ParseSysEventUsers(thresholds, sysEventUsers_);
92 }
93
ParseSysEventUsers(Json::Value & thresholdsJson,std::vector<SysEventUser> & users)94 bool EventThresholdManager::ParseSysEventUsers(Json::Value& thresholdsJson, std::vector<SysEventUser>& users)
95 {
96 users.clear();
97 if (!thresholdsJson.isObject()) {
98 HIVIEW_LOGE("thresholdjson is not object.");
99 return false;
100 }
101 if (!thresholdsJson.isMember(USERS_KEY) || !thresholdsJson[USERS_KEY].isArray()) {
102 HIVIEW_LOGE("USERS isn't configured or type matched in threshold file.");
103 return false;
104 }
105 auto usersJson = thresholdsJson[USERS_KEY];
106 auto size = usersJson.size();
107 for (unsigned int index = 0; index < size; ++index) {
108 SysEventUser user;
109 if (!ParseUser(usersJson[index], user)) {
110 continue;
111 }
112 users.emplace_back(user);
113 }
114 return true;
115 }
116
ParseUser(Json::Value & userJson,SysEventUser & user)117 bool EventThresholdManager::ParseUser(Json::Value& userJson, SysEventUser& user)
118 {
119 if (!userJson.isObject()) {
120 HIVIEW_LOGE("user configured in array is not object.");
121 return false;
122 }
123 if (!userJson.isMember(NAME_KEY) || !userJson[NAME_KEY].isString()) {
124 HIVIEW_LOGE("NAME isn't configured or type matched in user.");
125 return false;
126 }
127 auto configuredName = userJson[NAME_KEY].asString();
128 user.SetName(configuredName);
129 if (!userJson.isMember(TYPE_KEY) || !userJson[TYPE_KEY].isInt()) {
130 HIVIEW_LOGE("TYPE isn't configured or type matched in user.");
131 return false;
132 }
133 user.SetProcessType(ProcessType(userJson[TYPE_KEY].asInt()));
134 if (!userJson.isMember(CONFIGS_KEY) || !userJson[CONFIGS_KEY].isObject()) {
135 HIVIEW_LOGE("CONFIGS isn't configured or type matched in user.");
136 return false;
137 }
138 Configs configs;
139 if (!ParseConfigs(userJson[CONFIGS_KEY], configs)) {
140 return false;
141 }
142 user.SetConfigs(configs);
143 return true;
144 }
145
ParseConfigs(Json::Value & configJson,Configs & config)146 bool EventThresholdManager::ParseConfigs(Json::Value& configJson, Configs& config)
147 {
148 if (!configJson.isMember(QUERY_RULE_LIMIT_KEY) || !configJson[QUERY_RULE_LIMIT_KEY].isUInt()) {
149 HIVIEW_LOGE("QUERY_RULE_LIMIT_KEY isn't configured or type matched in configs.");
150 return false;
151 }
152 config.queryRuleLimit = static_cast<size_t>(configJson[QUERY_RULE_LIMIT_KEY].asUInt());
153 if (config.queryRuleLimit > QUERY_RULE_MAX_LIMIT) {
154 config.queryRuleLimit = QUERY_RULE_MAX_LIMIT;
155 }
156 return true;
157 }
158 } // namespace EventThreshold
159 } // namespace HiviewDFX
160 } // namespace OHOS