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,
224 std::bind(&HiSysEventRecord::IsInt64ValueType, this, std::placeholders::_1)));
225 },
226 [&value] (JsonValue src) {
227 int arraySize = src->Size();
228 for (int i = 0; i < arraySize; i++) {
229 value.emplace_back(src->Index(i).asInt64());
230 }
231 });
232 }
233
GetParamValue(const std::string & param,std::vector<uint64_t> & value) const234 int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<uint64_t>& value) const
235 {
236 return GetParamValue(param,
237 [this] (JsonValue val) {
238 return !(this->IsArray(val,
239 std::bind(&HiSysEventRecord::IsUInt64ValueType, this, std::placeholders::_1)));
240 },
241 [&value] (JsonValue src) {
242 int arraySize = src->Size();
243 for (int i = 0; i < arraySize; i++) {
244 value.emplace_back(src->Index(i).asUInt64());
245 }
246 });
247 }
248
GetParamValue(const std::string & param,std::vector<double> & value) const249 int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<double>& value) const
250 {
251 return GetParamValue(param,
252 [this] (JsonValue val) {
253 return !(this->IsArray(val,
254 std::bind(&HiSysEventRecord::IsDoubleValueType, this, std::placeholders::_1)));
255 },
256 [&value] (JsonValue src) {
257 int arraySize = src->Size();
258 for (int i = 0; i < arraySize; i++) {
259 value.emplace_back(src->Index(i).asDouble());
260 }
261 });
262 }
263
GetParamValue(const std::string & param,std::vector<std::string> & value) const264 int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<std::string>& value) const
265 {
266 return GetParamValue(param,
267 [this] (JsonValue val) {
268 return !(this->IsArray(val,
269 std::bind(&HiSysEventRecord::IsStringValueType, this, std::placeholders::_1)));
270 },
271 [&value] (JsonValue src) {
272 int arraySize = src->Size();
273 for (int i = 0; i < arraySize; i++) {
274 value.emplace_back(src->Index(i).asString());
275 }
276 });
277 }
278
ParseJsonStr(const std::string jsonStr)279 void HiSysEventRecord::ParseJsonStr(const std::string jsonStr)
280 {
281 jsonVal_ = std::make_shared<HiSysEventValue>(jsonStr);
282 jsonStr_ = jsonStr;
283 }
284
GetParamValue(const std::string & param,const TypeFilter filterFunc,const ValueAssigner assignFunc) const285 int HiSysEventRecord::GetParamValue(const std::string& param, const TypeFilter filterFunc,
286 const ValueAssigner assignFunc) const
287 {
288 if (!jsonVal_->HasInitialized()) {
289 HILOG_DEBUG(LOG_CORE, "this hisysevent record is not initialized");
290 return ERR_INIT_FAILED;
291 }
292 if (!jsonVal_->IsMember(param)) {
293 HILOG_DEBUG(LOG_CORE, "key named \"%{public}s\" is not found in json.",
294 param.c_str());
295 return ERR_KEY_NOT_EXIST;
296 }
297 auto parsedVal = std::make_shared<HiSysEventValue>(jsonVal_->GetParamValue(param));
298 if (filterFunc(parsedVal)) {
299 HILOG_DEBUG(LOG_CORE, "value type with key named \"%{public}s\" is %{public}d, not match.",
300 param.c_str(), parsedVal->Type());
301 return ERR_TYPE_NOT_MATCH;
302 }
303 assignFunc(parsedVal);
304 return VALUE_PARSED_SUCCEED;
305 }
306
IsInt64ValueType(const JsonValue val) const307 bool HiSysEventRecord::IsInt64ValueType(const JsonValue val) const
308 {
309 return val->IsInt64() || val->IsNull() || val->IsBool();
310 }
311
IsUInt64ValueType(const JsonValue val) const312 bool HiSysEventRecord::IsUInt64ValueType(const JsonValue val) const
313 {
314 return val->IsUInt64() || val->IsNull() || val->IsBool();
315 }
316
IsDoubleValueType(const JsonValue val) const317 bool HiSysEventRecord::IsDoubleValueType(const JsonValue val) const
318 {
319 return val->IsDouble() || val->IsNull() || val->IsBool();
320 }
321
IsStringValueType(const JsonValue val) const322 bool HiSysEventRecord::IsStringValueType(const JsonValue val) const
323 {
324 return val->IsNull() || val->IsBool() || val->IsNumeric() || val->IsString();
325 }
326
IsArray(const JsonValue val,const TypeFilter filterFunc) const327 bool HiSysEventRecord::IsArray(const JsonValue val, const TypeFilter filterFunc) const
328 {
329 if (!val->IsArray()) {
330 return false;
331 }
332 if (val->Size() > 0) {
333 return filterFunc(std::make_shared<HiSysEventValue>(val->Index(0)));
334 }
335 return (val->Size() == 0);
336 }
337
ParseJsonStr(const std::string jsonStr)338 void HiSysEventValue::ParseJsonStr(const std::string jsonStr)
339 {
340 #ifdef JSONCPP_VERSION_STRING
341 Json::CharReaderBuilder jsonRBuilder;
342 Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
343 std::unique_ptr<Json::CharReader> const reader(jsonRBuilder.newCharReader());
344 JSONCPP_STRING errs;
345 if (!reader->parse(jsonStr.data(), jsonStr.data() + jsonStr.size(), &jsonVal_, &errs)) {
346 #else
347 Json::Reader reader(Json::Features::strictMode());
348 if (!reader.parse(jsonStr, jsonVal_)) {
349 #endif
350 HILOG_ERROR(LOG_CORE, "parse json file failed, please check the style of json string: %{public}s.",
351 jsonStr.c_str());
352 return;
353 }
354 hasInitialized_ = true;
355 }
356
357 bool HiSysEventValue::HasInitialized() const
358 {
359 return hasInitialized_;
360 }
361
362 void HiSysEventValue::GetParamNames(std::vector<std::string>& params) const
363 {
364 if (!hasInitialized_ || (jsonVal_.type() != Json::ValueType::nullValue &&
365 jsonVal_.type() != Json::ValueType::objectValue)) {
366 return;
367 }
368 params = jsonVal_.getMemberNames();
369 }
370
371 bool HiSysEventValue::IsArray() const
372 {
373 if (!hasInitialized_) {
374 return false;
375 }
376 return jsonVal_.isArray();
377 }
378
379 bool HiSysEventValue::IsMember(const std::string key) const
380 {
381 if (!hasInitialized_) {
382 return false;
383 }
384 return jsonVal_.isMember(key);
385 }
386
387 bool HiSysEventValue::IsInt64() const
388 {
389 if (!hasInitialized_) {
390 return false;
391 }
392 return jsonVal_.isInt64();
393 }
394
395 bool HiSysEventValue::IsUInt64() const
396 {
397 if (!hasInitialized_) {
398 return false;
399 }
400 return jsonVal_.isUInt64();
401 }
402
403 bool HiSysEventValue::IsDouble() const
404 {
405 if (!hasInitialized_) {
406 return false;
407 }
408 return jsonVal_.isDouble();
409 }
410
411 bool HiSysEventValue::IsString() const
412 {
413 if (!hasInitialized_) {
414 return false;
415 }
416 return jsonVal_.isString();
417 }
418
419 bool HiSysEventValue::IsBool() const
420 {
421 if (!hasInitialized_) {
422 return false;
423 }
424 return jsonVal_.isBool();
425 }
426
427 bool HiSysEventValue::IsNull() const
428 {
429 if (!hasInitialized_) {
430 return false;
431 }
432 return jsonVal_.isNull();
433 }
434
435 bool HiSysEventValue::IsNumeric() const
436 {
437 if (!hasInitialized_) {
438 return false;
439 }
440 return jsonVal_.isNumeric();
441 }
442
443 Json::Value HiSysEventValue::Index(const int index) const
444 {
445 if (!hasInitialized_ || index < 0 ||
446 (jsonVal_.type() != Json::ValueType::nullValue &&
447 jsonVal_.type() != Json::ValueType::arrayValue)) {
448 return Json::Value(Json::ValueType::nullValue);
449 }
450 return jsonVal_[index];
451 }
452 Json::Value HiSysEventValue::GetParamValue(const std::string& key) const
453 {
454 if (!hasInitialized_) {
455 return Json::Value(Json::ValueType::nullValue);
456 }
457 return jsonVal_[key];
458 }
459
460 int HiSysEventValue::Size() const
461 {
462 if (!hasInitialized_) {
463 return DEFAULT_INT_VAL;
464 }
465 return jsonVal_.size();
466 }
467
468 int64_t HiSysEventValue::AsInt64() const
469 {
470 #ifdef JSON_HAS_INT64
471 if (!hasInitialized_ ||
472 (jsonVal_.type() == Json::ValueType::uintValue && !jsonVal_.isInt64()) ||
473 (jsonVal_.type() == Json::ValueType::realValue &&
474 !InValidRange(jsonVal_.asDouble(), Json::Value::minInt64, Json::Value::maxInt64))) {
475 return DEFAULT_INT64_VAL;
476 }
477 return jsonVal_.asInt64();
478 #else
479 return DEFAULT_INT64_VAL;
480 #endif
481 }
482
483 uint64_t HiSysEventValue::AsUInt64() const
484 {
485 #ifdef JSON_HAS_INT64
486 if (!hasInitialized_ ||
487 (jsonVal_.type() == Json::ValueType::intValue && !jsonVal_.isUInt64()) ||
488 (jsonVal_.type() == Json::ValueType::realValue &&
489 !InValidRange(jsonVal_.asDouble(), 0, Json::Value::maxUInt64))) {
490 return DEFAULT_UINT64_VAL;
491 }
492 return jsonVal_.asUInt64();
493 #else
494 return DEFAULT_UINT64_VAL;
495 #endif
496 }
497
498 double HiSysEventValue::AsDouble() const
499 {
500 if (!hasInitialized_) {
501 return DEFAULT_DOUBLE_VAL;
502 }
503 return jsonVal_.asDouble();
504 }
505
506 std::string HiSysEventValue::AsString() const
507 {
508 if (!hasInitialized_) {
509 return "";
510 }
511 return jsonVal_.asString();
512 }
513
514 Json::ValueType HiSysEventValue::Type() const
515 {
516 if (!hasInitialized_) {
517 return Json::ValueType::nullValue;
518 }
519 return jsonVal_.type();
520 }
521 } // HiviewDFX
522 } // OHOS
523