• 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 "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