• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "hisysevent_json_decorator.h"
17 
18 #include <algorithm>
19 #include <fstream>
20 #include <sstream>
21 
22 #include "hilog/log.h"
23 #include "hisysevent.h"
24 #include "json_flatten_parser.h"
25 
26 #undef LOG_DOMAIN
27 #define LOG_DOMAIN 0xD002D08
28 
29 #undef LOG_TAG
30 #define LOG_TAG "HISYSEVENT_JSON_DECORATOR"
31 
32 namespace OHOS {
33 namespace HiviewDFX {
34 namespace {
35 constexpr char ARRY_SIZE[] = "arrsize";
36 constexpr char DECORATE_PREFIX[] = "\033[31m";
37 constexpr char DECORATE_SUFFIX[] = "\033[0m";
38 constexpr char HISYSEVENT_YAML_DEF_JSON_PATH[] = "/data/system/hiview/unzip_configs/sys_event_def/hisysevent.def";
39 constexpr char LEVEL[] = "level";
40 constexpr char LEVEL_[] = "level_";
41 constexpr char TYPE[] = "type";
42 constexpr int BASE_INDEX = 0;
43 constexpr int DOMAIN_INDEX = 1;
44 constexpr int NAME_INDEX = 2;
45 const char* INNER_BUILD_KEYS[] = {
46     "__BASE", "domain_", "name_", "type_", "level_", "tag_",
47     "time_", "tz_", "pid_", "tid_", "uid_", "traceid_", "log_",
48     "id_", "spanid_", "pspanid_", "trace_flag_", "info_", "seq_",
49     "period_seq_", "reportInterval_"};
50 const std::string VALID_LEVELS[] = { "CRITICAL", "MINOR" };
51 const std::map<std::string, int> EVENT_TYPE_MAP = {{"FAULT", 1}, {"STATISTIC", 2}, {"SECURITY", 3}, {"BEHAVIOR", 4} };
52 }
53 
HiSysEventJsonDecorator()54 HiSysEventJsonDecorator::HiSysEventJsonDecorator()
55 {
56     std::ifstream fin(HISYSEVENT_YAML_DEF_JSON_PATH, std::ifstream::binary);
57 #ifdef JSONCPP_VERSION_STRING
58     Json::CharReaderBuilder jsonRBuilder;
59     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
60     JSONCPP_STRING errs;
61     if (!parseFromStream(jsonRBuilder, fin, &jsonRoot_, &errs)) {
62 #else
63     Json::Reader reader(Json::Features::strictMode());
64     if (!reader.parse(fin, jsonRoot_)) {
65 #endif
66         HILOG_ERROR(LOG_CORE, "parse json file failed, please check the style of json file: %{public}s.",
67             HISYSEVENT_YAML_DEF_JSON_PATH);
68     } else {
69         isJsonRootValid_ = true;
70     }
71 }
72 
73 bool HiSysEventJsonDecorator::CheckAttrDecorationNeed(const Json::Value& eventJson, const std::string& key,
74     const Json::Value& standard)
75 {
76     auto ret = CheckAttrValidity(eventJson, key, standard);
77     decoratedMarks_[key] = ret;
78     return ret != Validity::KV_BOTH_VALID;
79 }
80 
81 Validity HiSysEventJsonDecorator::CheckAttrValidity(const Json::Value& eventJson, const std::string& key,
82     const Json::Value& standard)
83 {
84     if (!standard.isMember(key)) {
85         return Validity::KEY_INVALID;
86     }
87     bool ret = false;
88     if (standard[key].isMember(ARRY_SIZE)) {
89         if (!eventJson[key].isArray() || eventJson[key].size() > standard[key][ARRY_SIZE].asUInt()) {
90             return Validity::VALUE_INVALID;
91         }
92         ret = JudgeDataType(standard[key][TYPE].asString(), eventJson[key][0]);
93         return ret ? Validity::KV_BOTH_VALID : Validity::VALUE_INVALID;
94     }
95     ret = JudgeDataType(standard[key][TYPE].asString(), eventJson[key]);
96     return ret ? Validity::KV_BOTH_VALID : Validity::VALUE_INVALID;
97 }
98 
99 Validity HiSysEventJsonDecorator::CheckLevelValidity(const Json::Value& baseInfo)
100 {
101     if (!baseInfo.isMember(LEVEL)) {
102         HILOG_ERROR(LOG_CORE, "level not defined in __BASE");
103         return Validity::KEY_INVALID;
104     }
105     std::string levelDes = baseInfo[LEVEL].asString();
106     if (std::any_of(std::begin(VALID_LEVELS), std::end(VALID_LEVELS), [&levelDes] (auto& level) {
107         return level == levelDes;
108     })) {
109         return Validity::KV_BOTH_VALID;
110     }
111     return Validity::VALUE_INVALID;
112 }
113 
114 bool HiSysEventJsonDecorator::CheckEventDecorationNeed(const Json::Value& eventJson,
115     BaseInfoHandler baseJsonInfoHandler, ExtensiveInfoHander extensiveJsonInfoHandler)
116 {
117     if (!isJsonRootValid_ || !jsonRoot_.isObject() || !eventJson.isObject()) {
118         return true;
119     }
120     std::string domain = eventJson[INNER_BUILD_KEYS[DOMAIN_INDEX]].asString();
121     std::string name = eventJson[INNER_BUILD_KEYS[NAME_INDEX]].asString();
122     if (!jsonRoot_.isMember(domain)) {
123         return true;
124     }
125     Json::Value definedDomain = jsonRoot_[domain];
126     if (!definedDomain.isObject() || !definedDomain.isMember(name)) {
127         return true;
128     }
129     Json::Value definedName = definedDomain[name];
130     if (!definedName.isObject()) {
131         return true;
132     }
133     auto baseInfoNeed = false;
134     if (definedName.isMember(INNER_BUILD_KEYS[BASE_INDEX])) {
135         baseInfoNeed = baseJsonInfoHandler(definedName[INNER_BUILD_KEYS[BASE_INDEX]]);
136     }
137     auto extensiveInfoNeed = extensiveJsonInfoHandler(eventJson, definedName);
138     return baseInfoNeed || extensiveInfoNeed;
139 }
140 
141 std::string HiSysEventJsonDecorator::Decorate(Validity validity, std::string& key, std::string& value)
142 {
143     std::stringstream ss;
144     switch (validity) {
145         case Validity::KEY_INVALID:
146             ss << "\"" << DECORATE_PREFIX << key << DECORATE_SUFFIX << "\":" << value;
147             break;
148         case Validity::VALUE_INVALID:
149             ss << "\"" << key << "\":" << DECORATE_PREFIX << value << DECORATE_SUFFIX;
150             break;
151         case Validity::KV_BOTH_VALID:
152             ss << "\"" << key << "\":" << value;
153             break;
154         default:
155             break;
156     }
157     std::string ret = ss.str();
158     ss.clear();
159     return ret;
160 }
161 
162 std::string HiSysEventJsonDecorator::DecorateEventJsonStr(const HiSysEventRecord& record)
163 {
164     std::string origin = record.AsJson();
165     decoratedMarks_.clear(); // reset marked keys.
166     if (!isJsonRootValid_) {
167         HILOG_ERROR(LOG_CORE, "root json value is not valid, failed to decorate.");
168         return origin;
169     }
170     Json::Value eventJson;
171 #ifdef JSONCPP_VERSION_STRING
172     Json::CharReaderBuilder jsonRBuilder;
173     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
174     std::unique_ptr<Json::CharReader> const reader(jsonRBuilder.newCharReader());
175     JSONCPP_STRING errs;
176     if (!reader->parse(origin.data(), origin.data() + origin.size(), &eventJson, &errs)) {
177 #else
178     Json::Reader reader(Json::Features::strictMode());
179     if (!reader.parse(origin, eventJson)) {
180 #endif
181         HILOG_ERROR(LOG_CORE, "parse json file failed, please check the style of json file: %{public}s.",
182             origin.c_str());
183         return origin;
184     }
185     auto needDecorate = CheckEventDecorationNeed(eventJson,
186         [this] (const Json::Value& definedBase) {
187             auto levelValidity = this->CheckLevelValidity(definedBase);
188             decoratedMarks_[LEVEL_] = levelValidity;
189             return levelValidity != Validity::KV_BOTH_VALID;
190         }, [this] (const Json::Value& eventJson, const Json::Value& definedName) {
191                 auto attrList = eventJson.getMemberNames();
192                 bool ret = false;
193                 for (auto it = attrList.cbegin(); it != attrList.cend(); it++) {
194                     std::string key = *it;
195                     if (std::find_if(std::cbegin(INNER_BUILD_KEYS), std::cend(INNER_BUILD_KEYS),
196                         [&ret, &eventJson, &key, &definedName] (const char* ele) {
197                             return (key.compare(ele) == 0);
198                         }) == std::cend(INNER_BUILD_KEYS)) {
199                         ret = this->CheckAttrDecorationNeed(eventJson, key, definedName) || ret;
200                     }
201                 }
202                 return ret;
203             });
204     if (!needDecorate) {
205         HILOG_DEBUG(LOG_CORE, "no need to decorate this event json string.");
206         return origin;
207     }
208     HILOG_DEBUG(LOG_CORE, "all invalid key or value will be high-lighted with red color.");
209     return DecorateJsonStr(origin, decoratedMarks_);
210 }
211 
212 std::string HiSysEventJsonDecorator::DecorateJsonStr(const std::string& origin, DecorateMarks marks)
213 {
214     if (marks.empty()) {
215         return origin;
216     }
217     JsonFlattenParser parser(origin);
218     return parser.Print([this, &marks] (KV& kv) -> std::string {
219         auto iter = marks.find(kv.first);
220         return this->Decorate((iter == marks.end() ? Validity::KV_BOTH_VALID : iter->second), kv.first, kv.second);
221     });
222 }
223 
224 bool HiSysEventJsonDecorator::JudgeDataType(const std::string &dataType, const Json::Value &eventJson)
225 {
226     if (dataType.compare("BOOL") == 0) {
227         return eventJson.isBool() || (eventJson.isInt() && (eventJson.asInt() == 0 || eventJson.asInt() == 1));
228     } else if ((dataType.compare("INT8") == 0) || (dataType.compare("INT16") == 0) ||
229         (dataType.compare("INT32") == 0)) {
230         return eventJson.isInt();
231     } else if (dataType.compare("INT64") == 0) {
232         return eventJson.isInt64();
233     } else if ((dataType.compare("UINT8") == 0) || (dataType.compare("UINT16") == 0) ||
234         (dataType.compare("UINT32") == 0)) {
235         return eventJson.isUInt();
236     } else if (dataType.compare("UINT64") == 0) {
237         return eventJson.isUInt64();
238     } else if ((dataType.compare("FLOAT") == 0) || (dataType.compare("DOUBLE") == 0)) {
239         return eventJson.isDouble();
240     } else if (dataType.compare("STRING") == 0) {
241         return eventJson.isString();
242     } else {
243         return false;
244     }
245 }
246 } // namespace HiviewDFX
247 } // namespace OHOS
248