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