1 /*
2  * Copyright (c) 2022-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 "hisysevent_record.h"
17 
18 #include <sstream>
19 
20 #include "hilog/log.h"
21 #include "hisysevent_value.h"
22 
23 #undef LOG_DOMAIN
24 #define LOG_DOMAIN 0xD002D08
25 
26 #undef LOG_TAG
27 #define LOG_TAG "HISYSEVENT_RECORD"
28 
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace {
32 constexpr int DEFAULT_INT_VAL = 0;
33 constexpr uint64_t DEFAULT_UINT64_VAL = 0;
34 constexpr int64_t DEFAULT_INT64_VAL = 0;
35 constexpr double DEFAULT_DOUBLE_VAL = 0.0;
36 constexpr double DOUBLE_CONVERT_FACTOR = 2.0;
37 constexpr Json::UInt64 BIT = 2;
38 constexpr Json::UInt64 BIT_AND_VAL = 1;
39 
40 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
41 template <typename T, typename U>
InValidRange(double d,T min,U max)42 static inline bool InValidRange(double d, T min, U max)
43 {
44     return d >= static_cast<double>(min) && d <= static_cast<double>(max);
45 }
46 #else
int64ToDouble(Json::UInt64 value)47 static inline double int64ToDouble(Json::UInt64 value)
48 {
49     return static_cast<double>(Json::Int64(value / BIT)) * DOUBLE_CONVERT_FACTOR +
50         static_cast<double>(Json::Int64(value & BIT_AND_VAL));
51 }
int64ToDouble(T value)52 template <typename T> static inline double int64ToDouble(T value)
53 {
54     return static_cast<double>(value);
55 }
56 template <typename T, typename U>
InValidRange(double d,T min,U max)57 static inline bool InValidRange(double d, T min, U max)
58 {
59     return d >= int64ToDouble(min) && d <= int64ToDouble(max);
60 }
61 #endif
62 }
63 
GetDomain() const64 std::string HiSysEventRecord::GetDomain() const
65 {
66     return GetStringValueByKey("domain_");
67 }
68 
GetEventName() const69 std::string HiSysEventRecord::GetEventName() const
70 {
71     return GetStringValueByKey("name_");
72 }
73 
GetEventType() const74 HiSysEvent::EventType HiSysEventRecord::GetEventType() const
75 {
76     return HiSysEvent::EventType(GetIntValueByKey("type_"));
77 }
78 
GetTime() const79 uint64_t HiSysEventRecord::GetTime() const
80 {
81     return GetUInt64ValueByKey("time_");
82 }
83 
GetTimeZone() const84 std::string HiSysEventRecord::GetTimeZone() const
85 {
86     return GetStringValueByKey("tz_");
87 }
88 
GetPid() const89 int64_t HiSysEventRecord::GetPid() const
90 {
91     return GetInt64ValueByKey("pid_");
92 }
93 
GetTid() const94 int64_t HiSysEventRecord::GetTid() const
95 {
96     return GetInt64ValueByKey("tid_");
97 }
98 
GetUid() const99 int64_t HiSysEventRecord::GetUid() const
100 {
101     return GetInt64ValueByKey("uid_");
102 }
103 
GetTraceId() const104 uint64_t HiSysEventRecord::GetTraceId() const
105 {
106     std::string hexStr = GetStringValueByKey("traceid_");
107     uint64_t traceId = 0; // default trace id is 0
108     std::stringstream ss;
109     ss << hexStr;
110     ss >> std::hex >> traceId;
111     return traceId;
112 }
113 
GetSpanId() const114 uint64_t HiSysEventRecord::GetSpanId() const
115 {
116     return GetUInt64ValueByKey("spanid_");
117 }
118 
GetPspanId() const119 uint64_t HiSysEventRecord::GetPspanId() const
120 {
121     return GetUInt64ValueByKey("pspanid_");
122 }
123 
GetTraceFlag() const124 int HiSysEventRecord::GetTraceFlag() const
125 {
126     return static_cast<int>(GetInt64ValueByKey("trace_flag_"));
127 }
128 
GetLevel() const129 std::string HiSysEventRecord::GetLevel() const
130 {
131     return GetStringValueByKey("level_");
132 }
133 
GetTag() const134 std::string HiSysEventRecord::GetTag() const
135 {
136     return GetStringValueByKey("tag_");
137 }
138 
GetParamNames(std::vector<std::string> & params) const139 void HiSysEventRecord::GetParamNames(std::vector<std::string>& params) const
140 {
141     jsonVal_->GetParamNames(params);
142 }
143 
AsJson() const144 std::string HiSysEventRecord::AsJson() const
145 {
146     return jsonStr_;
147 }
148 
GetIntValueByKey(const std::string key) const149 int HiSysEventRecord::GetIntValueByKey(const std::string key) const
150 {
151     return static_cast<int>(GetInt64ValueByKey(key));
152 }
153 
GetInt64ValueByKey(const std::string key) const154 int64_t HiSysEventRecord::GetInt64ValueByKey(const std::string key) const
155 {
156     int64_t value = 0;
157     (void)GetParamValue(key, value);
158     return value;
159 }
160 
GetUInt64ValueByKey(const std::string key) const161 uint64_t HiSysEventRecord::GetUInt64ValueByKey(const std::string key) const
162 {
163     uint64_t value = 0;
164     (void)GetParamValue(key, value);
165     return value;
166 }
167 
GetStringValueByKey(const std::string key) const168 std::string HiSysEventRecord::GetStringValueByKey(const std::string key) const
169 {
170     std::string value;
171     (void)GetParamValue(key, value);
172     return value;
173 }
174 
GetParamValue(const std::string & param,int64_t & value) const175 int HiSysEventRecord::GetParamValue(const std::string& param, int64_t& value) const
176 {
177     return GetParamValue(param,
178         [this] (JsonValue val) {
179             return !(this->IsInt64ValueType(val));
180         },
181         [&value] (JsonValue src) {
182             value = src->AsInt64();
183         });
184 }
185 
GetParamValue(const std::string & param,uint64_t & value) const186 int HiSysEventRecord::GetParamValue(const std::string& param, uint64_t& value) const
187 {
188     return GetParamValue(param,
189         [this] (JsonValue val) {
190             return !(this->IsUInt64ValueType(val));
191         },
192         [&value] (JsonValue src) {
193             value = src->AsUInt64();
194         });
195 }
196 
GetParamValue(const std::string & param,double & value) const197 int HiSysEventRecord::GetParamValue(const std::string& param, double& value) const
198 {
199     return GetParamValue(param,
200         [this] (JsonValue val) {
201             return !(this->IsDoubleValueType(val));
202         },
203         [&value] (JsonValue src) {
204             value = src->AsDouble();
205         });
206 }
207 
GetParamValue(const std::string & param,std::string & value) const208 int HiSysEventRecord::GetParamValue(const std::string& param, std::string& value) const
209 {
210     return GetParamValue(param,
211         [this] (JsonValue val) {
212             return !(this->IsStringValueType(val));
213         },
214         [&value] (JsonValue src) {
215             value = src->AsString();
216         });
217 }
218 
GetParamValue(const std::string & param,std::vector<int64_t> & value) const219 int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<int64_t>& value) const
220 {
221     return GetParamValue(param,
222         [this] (JsonValue val) {
223             return !(this->IsArray(val, [this] (const JsonValue val) {
224                     return this->IsInt64ValueType(val);
225                 }));
226         },
227         [&value] (JsonValue src) {
228             int arraySize = src->Size();
229             for (int i = 0; i < arraySize; i++) {
230                 value.emplace_back(src->Index(i).asInt64());
231             }
232         });
233 }
234 
GetParamValue(const std::string & param,std::vector<uint64_t> & value) const235 int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<uint64_t>& value) const
236 {
237     return GetParamValue(param,
238         [this] (JsonValue val) {
239             return !(this->IsArray(val, [this] (const JsonValue val) {
240                     return this->IsUInt64ValueType(val);
241                 }));
242         },
243         [&value] (JsonValue src) {
244             int arraySize = src->Size();
245             for (int i = 0; i < arraySize; i++) {
246                 value.emplace_back(src->Index(i).asUInt64());
247             }
248         });
249 }
250 
GetParamValue(const std::string & param,std::vector<double> & value) const251 int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<double>& value) const
252 {
253     return GetParamValue(param,
254         [this] (JsonValue val) {
255             return !(this->IsArray(val, [this] (const JsonValue val) {
256                     return this->IsDoubleValueType(val);
257                 }));
258         },
259         [&value] (JsonValue src) {
260             int arraySize = src->Size();
261             for (int i = 0; i < arraySize; i++) {
262                 value.emplace_back(src->Index(i).asDouble());
263             }
264         });
265 }
266 
GetParamValue(const std::string & param,std::vector<std::string> & value) const267 int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<std::string>& value) const
268 {
269     return GetParamValue(param,
270         [this] (JsonValue val) {
271             return !(this->IsArray(val, [this] (const JsonValue val) {
272                     return this->IsStringValueType(val);
273                 }));
274         },
275         [&value] (JsonValue src) {
276             int arraySize = src->Size();
277             for (int i = 0; i < arraySize; i++) {
278                 value.emplace_back(src->Index(i).asString());
279             }
280         });
281 }
282 
ParseJsonStr(const std::string jsonStr)283 void HiSysEventRecord::ParseJsonStr(const std::string jsonStr)
284 {
285     jsonVal_ = std::make_shared<HiSysEventValue>(jsonStr);
286     jsonStr_ = jsonStr;
287 }
288 
GetParamValue(const std::string & param,const TypeFilter filterFunc,const ValueAssigner assignFunc) const289 int HiSysEventRecord::GetParamValue(const std::string& param, const TypeFilter filterFunc,
290     const ValueAssigner assignFunc) const
291 {
292     if (!jsonVal_->HasInitialized()) {
293         HILOG_DEBUG(LOG_CORE, "this hisysevent record is not initialized");
294         return ERR_INIT_FAILED;
295     }
296     if (!jsonVal_->IsMember(param)) {
297         HILOG_DEBUG(LOG_CORE, "key named \"%{public}s\" is not found in json.",
298             param.c_str());
299         return ERR_KEY_NOT_EXIST;
300     }
301     auto parsedVal = std::make_shared<HiSysEventValue>(jsonVal_->GetParamValue(param));
302     if (filterFunc(parsedVal)) {
303         HILOG_DEBUG(LOG_CORE, "value type with key named \"%{public}s\" is %{public}d, not match.",
304             param.c_str(), parsedVal->Type());
305         return ERR_TYPE_NOT_MATCH;
306     }
307     assignFunc(parsedVal);
308     return VALUE_PARSED_SUCCEED;
309 }
310 
IsInt64ValueType(const JsonValue val) const311 bool HiSysEventRecord::IsInt64ValueType(const JsonValue val) const
312 {
313     return val->IsInt64() || val->IsNull() || val->IsBool();
314 }
315 
IsUInt64ValueType(const JsonValue val) const316 bool HiSysEventRecord::IsUInt64ValueType(const JsonValue val) const
317 {
318     return val->IsUInt64() || val->IsNull() || val->IsBool();
319 }
320 
IsDoubleValueType(const JsonValue val) const321 bool HiSysEventRecord::IsDoubleValueType(const JsonValue val) const
322 {
323     return val->IsDouble() || val->IsNull() || val->IsBool();
324 }
325 
IsStringValueType(const JsonValue val) const326 bool HiSysEventRecord::IsStringValueType(const JsonValue val) const
327 {
328     return val->IsNull() || val->IsBool() || val->IsNumeric() || val->IsString();
329 }
330 
IsArray(const JsonValue val,const TypeFilter filterFunc) const331 bool HiSysEventRecord::IsArray(const JsonValue val, const TypeFilter filterFunc) const
332 {
333     if (!val->IsArray()) {
334         return false;
335     }
336     if (val->Size() > 0) {
337         return filterFunc(std::make_shared<HiSysEventValue>(val->Index(0)));
338     }
339     return (val->Size() == 0);
340 }
341 
ParseJsonStr(const std::string jsonStr)342 void HiSysEventValue::ParseJsonStr(const std::string jsonStr)
343 {
344 #ifdef JSONCPP_VERSION_STRING
345     Json::CharReaderBuilder jsonRBuilder;
346     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
347     std::unique_ptr<Json::CharReader> const reader(jsonRBuilder.newCharReader());
348     JSONCPP_STRING errs;
349     if (!reader->parse(jsonStr.data(), jsonStr.data() + jsonStr.size(), &jsonVal_, &errs)) {
350 #else
351     Json::Reader reader(Json::Features::strictMode());
352     if (!reader.parse(jsonStr, jsonVal_)) {
353 #endif
354         HILOG_ERROR(LOG_CORE, "parse json file failed, please check the style of json string: %{public}s.",
355             jsonStr.c_str());
356         return;
357     }
358     hasInitialized_ = true;
359 }
360 
361 bool HiSysEventValue::HasInitialized() const
362 {
363     return hasInitialized_;
364 }
365 
366 void HiSysEventValue::GetParamNames(std::vector<std::string>& params) const
367 {
368     if (!hasInitialized_ || (jsonVal_.type() != Json::ValueType::nullValue &&
369         jsonVal_.type() != Json::ValueType::objectValue)) {
370         return;
371     }
372     params = jsonVal_.getMemberNames();
373 }
374 
375 bool HiSysEventValue::IsArray() const
376 {
377     if (!hasInitialized_) {
378         return false;
379     }
380     return jsonVal_.isArray();
381 }
382 
383 bool HiSysEventValue::IsMember(const std::string key) const
384 {
385     if (!hasInitialized_ || !jsonVal_.isObject()) {
386         return false;
387     }
388     return jsonVal_.isMember(key);
389 }
390 
391 bool HiSysEventValue::IsInt64() const
392 {
393     if (!hasInitialized_) {
394         return false;
395     }
396     return jsonVal_.isInt64();
397 }
398 
399 bool HiSysEventValue::IsUInt64() const
400 {
401     if (!hasInitialized_) {
402         return false;
403     }
404     return jsonVal_.isUInt64();
405 }
406 
407 bool HiSysEventValue::IsDouble() const
408 {
409     if (!hasInitialized_) {
410         return false;
411     }
412     return jsonVal_.isDouble();
413 }
414 
415 bool HiSysEventValue::IsString() const
416 {
417     if (!hasInitialized_) {
418         return false;
419     }
420     return jsonVal_.isString();
421 }
422 
423 bool HiSysEventValue::IsBool() const
424 {
425     if (!hasInitialized_) {
426         return false;
427     }
428     return jsonVal_.isBool();
429 }
430 
431 bool HiSysEventValue::IsNull() const
432 {
433     if (!hasInitialized_) {
434         return false;
435     }
436     return jsonVal_.isNull();
437 }
438 
439 bool HiSysEventValue::IsNumeric() const
440 {
441     if (!hasInitialized_) {
442         return false;
443     }
444     return jsonVal_.isNumeric();
445 }
446 
447 Json::Value HiSysEventValue::Index(const int index) const
448 {
449     if (!hasInitialized_ || index < 0 ||
450         (jsonVal_.type() != Json::ValueType::nullValue &&
451         jsonVal_.type() != Json::ValueType::arrayValue)) {
452         return Json::Value(Json::ValueType::nullValue);
453     }
454     return jsonVal_[index];
455 }
456 Json::Value HiSysEventValue::GetParamValue(const std::string& key) const
457 {
458     if (!hasInitialized_ ||
459         (jsonVal_.type() != Json::ValueType::nullValue &&
460         jsonVal_.type() != Json::ValueType::objectValue)) {
461         return Json::Value(Json::ValueType::nullValue);
462     }
463     return jsonVal_[key];
464 }
465 
466 int HiSysEventValue::Size() const
467 {
468     if (!hasInitialized_) {
469         return DEFAULT_INT_VAL;
470     }
471     return jsonVal_.size();
472 }
473 
474 int64_t HiSysEventValue::AsInt64() const
475 {
476 #ifdef JSON_HAS_INT64
477     if (!hasInitialized_ ||
478         (jsonVal_.type() == Json::ValueType::uintValue && !jsonVal_.isInt64()) ||
479         (jsonVal_.type() == Json::ValueType::realValue &&
480         !InValidRange(jsonVal_.asDouble(), Json::Value::minInt64, Json::Value::maxInt64))) {
481         return DEFAULT_INT64_VAL;
482     }
483     return jsonVal_.asInt64();
484 #else
485     return DEFAULT_INT64_VAL;
486 #endif
487 }
488 
489 uint64_t HiSysEventValue::AsUInt64() const
490 {
491 #ifdef JSON_HAS_INT64
492     if (!hasInitialized_ ||
493         (jsonVal_.type() == Json::ValueType::intValue && !jsonVal_.isUInt64()) ||
494         (jsonVal_.type() == Json::ValueType::realValue &&
495         !InValidRange(jsonVal_.asDouble(), 0, Json::Value::maxUInt64))) {
496         return DEFAULT_UINT64_VAL;
497     }
498     return jsonVal_.asUInt64();
499 #else
500     return DEFAULT_UINT64_VAL;
501 #endif
502 }
503 
504 double HiSysEventValue::AsDouble() const
505 {
506     if (!hasInitialized_) {
507         return DEFAULT_DOUBLE_VAL;
508     }
509     return jsonVal_.asDouble();
510 }
511 
512 std::string HiSysEventValue::AsString() const
513 {
514     if (!hasInitialized_) {
515         return "";
516     }
517     return jsonVal_.asString();
518 }
519 
520 Json::ValueType HiSysEventValue::Type() const
521 {
522     if (!hasInitialized_) {
523         return Json::ValueType::nullValue;
524     }
525     return jsonVal_.type();
526 }
527 } // HiviewDFX
528 } // OHOS
529