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