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 "event_json_parser.h"
17
18 #include <cctype>
19 #include <cinttypes>
20 #include <fstream>
21 #include <map>
22
23 #include "hiview_logger.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 namespace {
28 DEFINE_LOG_TAG("Event-JsonParser");
29
30 constexpr char BASE[] = "__BASE";
31 constexpr char LEVEL[] = "level";
32 constexpr char TAG[] = "tag";
33 constexpr char TYPE[] = "type";
34 constexpr char PRIVACY[] = "privacy";
35 constexpr char PRESERVE[] = "preserve";
36 const std::map<std::string, uint8_t> EVENT_TYPE_MAP = {
37 {"FAULT", 1}, {"STATISTIC", 2}, {"SECURITY", 3}, {"BEHAVIOR", 4}
38 };
39
ReadSysEventDefFromFile(const std::string & path,Json::Value & hiSysEventDef)40 bool ReadSysEventDefFromFile(const std::string& path, Json::Value& hiSysEventDef)
41 {
42 std::ifstream fin(path, std::ifstream::binary);
43 Json::CharReaderBuilder jsonRBuilder;
44 Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
45 JSONCPP_STRING errs;
46 return parseFromStream(jsonRBuilder, fin, &hiSysEventDef, &errs);
47 }
48 }
49
EventJsonParser(const std::string & defFilePath)50 EventJsonParser::EventJsonParser(const std::string& defFilePath)
51 {
52 // read json file
53 ReadDefFile(defFilePath);
54 }
55
GetTagByDomainAndName(const std::string & domain,const std::string & name) const56 std::string EventJsonParser::GetTagByDomainAndName(const std::string& domain, const std::string& name) const
57 {
58 return GetDefinedBaseInfoByDomainName(domain, name).tag;
59 }
60
GetTypeByDomainAndName(const std::string & domain,const std::string & name) const61 int EventJsonParser::GetTypeByDomainAndName(const std::string& domain, const std::string& name) const
62 {
63 return GetDefinedBaseInfoByDomainName(domain, name).type;
64 }
65
GetPreserveByDomainAndName(const std::string & domain,const std::string & name) const66 bool EventJsonParser::GetPreserveByDomainAndName(const std::string& domain, const std::string& name) const
67 {
68 return GetDefinedBaseInfoByDomainName(domain, name).preserve;
69 }
70
GetDefinedBaseInfoByDomainName(const std::string & domain,const std::string & name) const71 BaseInfo EventJsonParser::GetDefinedBaseInfoByDomainName(const std::string& domain,
72 const std::string& name) const
73 {
74 if (hiSysEventDefMap_ == nullptr) {
75 HIVIEW_LOGD("sys def map is null");
76 return BaseInfo();
77 }
78 auto domainIter = hiSysEventDefMap_->find(domain);
79 if (domainIter == hiSysEventDefMap_->end()) {
80 HIVIEW_LOGD("domain %{public}s is not defined.", domain.c_str());
81 return BaseInfo();
82 }
83 auto domainNames = hiSysEventDefMap_->at(domain);
84 auto nameIter = domainNames.find(name);
85 if (nameIter == domainNames.end()) {
86 HIVIEW_LOGD("%{public}s is not defined in domain %{public}s.", name.c_str(), domain.c_str());
87 return BaseInfo();
88 }
89 return nameIter->second;
90 }
91
HasIntMember(const Json::Value & jsonObj,const std::string & name) const92 bool EventJsonParser::HasIntMember(const Json::Value& jsonObj, const std::string& name) const
93 {
94 return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isInt();
95 }
96
HasStringMember(const Json::Value & jsonObj,const std::string & name) const97 bool EventJsonParser::HasStringMember(const Json::Value& jsonObj, const std::string& name) const
98 {
99 return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isString();
100 }
101
HasBoolMember(const Json::Value & jsonObj,const std::string & name) const102 bool EventJsonParser::HasBoolMember(const Json::Value& jsonObj, const std::string& name) const
103 {
104 return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isBool();
105 }
106
InitEventInfoMapRef(const Json::Value & eventJson,JSON_VALUE_LOOP_HANDLER handler) const107 void EventJsonParser::InitEventInfoMapRef(const Json::Value& eventJson, JSON_VALUE_LOOP_HANDLER handler) const
108 {
109 if (!eventJson.isObject()) {
110 return;
111 }
112 auto attrList = eventJson.getMemberNames();
113 for (auto it = attrList.cbegin(); it != attrList.cend(); it++) {
114 std::string key = *it;
115 if (key.empty()) {
116 continue;
117 }
118 if (handler != nullptr) {
119 handler(key, eventJson[key]);
120 }
121 }
122 }
123
ParseBaseConfig(const Json::Value & eventNameJson) const124 BaseInfo EventJsonParser::ParseBaseConfig(const Json::Value& eventNameJson) const
125 {
126 BaseInfo baseInfo;
127 if (!eventNameJson.isObject() || !eventNameJson[BASE].isObject()) {
128 HIVIEW_LOGD("__BASE definition is invalid.");
129 return baseInfo;
130 }
131
132 Json::Value baseJsonInfo = eventNameJson[BASE];
133 if (!baseJsonInfo.isObject() || !HasStringMember(baseJsonInfo, TYPE)) {
134 HIVIEW_LOGD("type is not defined in __BASE.");
135 return baseInfo;
136 }
137 std::string typeDes = baseJsonInfo[TYPE].asString();
138 if (EVENT_TYPE_MAP.find(typeDes) == EVENT_TYPE_MAP.end()) {
139 HIVIEW_LOGD("type is defined as %{public}s, but a valid type must be FAULT, STATISTIC, SECURITY, or BEHAVIOR",
140 typeDes.c_str());
141 return baseInfo;
142 }
143 baseInfo.type = EVENT_TYPE_MAP.at(typeDes);
144
145 if (!HasStringMember(baseJsonInfo, LEVEL)) {
146 HIVIEW_LOGD("level is not defined in __BASE.");
147 return baseInfo;
148 }
149 baseInfo.level = baseJsonInfo[LEVEL].asString();
150
151 if (HasStringMember(baseJsonInfo, TAG)) {
152 baseInfo.tag = baseJsonInfo[TAG].asString();
153 }
154
155 if (HasIntMember(baseJsonInfo, PRIVACY)) {
156 int privacy = baseJsonInfo[PRIVACY].asInt();
157 baseInfo.privacy = privacy > 0 ? static_cast<uint8_t>(privacy) : baseInfo.privacy;
158 }
159
160 if (HasBoolMember(baseJsonInfo, PRESERVE)) {
161 baseInfo.preserve = baseJsonInfo[PRESERVE].asBool();
162 }
163
164 return baseInfo;
165 }
166
ParseHiSysEventDef(const Json::Value & hiSysEventDef,std::shared_ptr<DOMAIN_INFO_MAP> sysDefMap)167 void EventJsonParser::ParseHiSysEventDef(const Json::Value& hiSysEventDef, std::shared_ptr<DOMAIN_INFO_MAP> sysDefMap)
168 {
169 InitEventInfoMapRef(hiSysEventDef, [this, sysDefMap] (const std::string& key, const Json::Value& value) {
170 sysDefMap->insert(std::make_pair(key, this->ParseNameConfig(value)));
171 });
172 }
173
ParseNameConfig(const Json::Value & domainJson) const174 NAME_INFO_MAP EventJsonParser::ParseNameConfig(const Json::Value& domainJson) const
175 {
176 NAME_INFO_MAP allNames;
177 if (!domainJson.isObject()) {
178 return allNames;
179 }
180 InitEventInfoMapRef(domainJson, [this, &allNames] (const std::string& key, const Json::Value& value) {
181 allNames[key] = ParseBaseConfig(value);
182 });
183 return allNames;
184 }
185
ReadDefFile(const std::string & defFilePath)186 void EventJsonParser::ReadDefFile(const std::string& defFilePath)
187 {
188 Json::Value hiSysEventDef;
189 if (!ReadSysEventDefFromFile(defFilePath, hiSysEventDef)) {
190 HIVIEW_LOGE("parse json file failed, please check the style of json file: %{public}s", defFilePath.c_str());
191 return;
192 }
193 auto tmpMap = std::make_shared<DOMAIN_INFO_MAP>();
194 ParseHiSysEventDef(hiSysEventDef, tmpMap);
195 hiSysEventDefMap_ = tmpMap;
196 }
197 } // namespace HiviewDFX
198 } // namespace OHOS
199