1 /* 2 * Copyright (c) 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 #ifndef BASE_EVENT_RAW_ENCODE_INCLUDE_RAW_DATA_BUILDER_H 17 #define BASE_EVENT_RAW_ENCODE_INCLUDE_RAW_DATA_BUILDER_H 18 19 #include <cstddef> 20 #include <cstdint> 21 #include <list> 22 #include <memory> 23 #include <mutex> 24 #include <sstream> 25 #include <string> 26 #include <vector> 27 #include <unordered_map> 28 #include <functional> 29 30 #include "decoded/decoded_param.h" 31 #include "encoded/encoded_param.h" 32 #include "base/raw_data_base_def.h" 33 #include "base/raw_data.h" 34 35 namespace OHOS { 36 namespace HiviewDFX { 37 namespace EventRaw { 38 class RawDataBuilder { 39 public: RawDataBuilder()40 RawDataBuilder() {}; 41 RawDataBuilder(std::shared_ptr<EventRaw::RawData> rawData); 42 RawDataBuilder(const std::string& domain, const std::string& name, const int eventType); 43 ~RawDataBuilder() = default; 44 45 public: 46 std::shared_ptr<RawData> Build(); 47 std::shared_ptr<EncodedParam> GetValue(const std::string& key); 48 struct HiSysEventHeader& GetHeader(); 49 struct TraceInfo& GetTraceInfo(); 50 std::string GetDomain(); 51 std::string GetName(); 52 int GetEventType(); 53 size_t GetParamCnt(); 54 bool IsBaseInfo(const std::string& key); 55 56 public: 57 RawDataBuilder& AppendValue(std::shared_ptr<EncodedParam> param); 58 RawDataBuilder& AppendDomain(const std::string& domain); 59 RawDataBuilder& AppendName(const std::string& name); 60 RawDataBuilder& AppendType(const int eventType); 61 RawDataBuilder& AppendTimeStamp(const uint64_t timeStamp); 62 RawDataBuilder& AppendTimeZone(const std::string& timeZone); 63 RawDataBuilder& AppendTimeZone(const uint8_t timeZone); 64 RawDataBuilder& AppendUid(const uint32_t uid); 65 RawDataBuilder& AppendPid(const uint32_t pid); 66 RawDataBuilder& AppendTid(const uint32_t tid); 67 RawDataBuilder& AppendLog(const uint8_t log); 68 RawDataBuilder& AppendId(const uint64_t id); 69 RawDataBuilder& AppendId(const std::string& id); 70 RawDataBuilder& AppendTraceId(const uint64_t traceId); 71 RawDataBuilder& AppendSpanId(const uint32_t spanId); 72 RawDataBuilder& AppendPSpanId(const uint32_t pSpanId); 73 RawDataBuilder& AppendTraceFlag(const uint8_t traceFlag); 74 RawDataBuilder& AppendTraceInfo(const uint64_t traceId, const uint32_t spanId, 75 const uint32_t pSpanId, const uint8_t traceFlag); 76 RawDataBuilder& RemoveParam(const std::string& paramName); 77 78 template<typename T> ParseValueByKey(const std::string & key,T & dest)79 bool ParseValueByKey(const std::string& key, T& dest) 80 { 81 if (IsBaseInfo(key)) { 82 return GetBaseInfoValueByKey(key, dest); 83 } 84 return GetValueByKey(key, dest); 85 } 86 87 template<typename T> AppendValue(const std::string & key,T val)88 RawDataBuilder& AppendValue(const std::string& key, T val) 89 { 90 if (IsBaseInfo(key)) { 91 return AppendBaseInfoValue(key, val); 92 } 93 if constexpr (isString<T>) { 94 return AppendValue(std::make_shared<StringEncodedParam>(key, val)); 95 } 96 if constexpr (isFloatingPointNum<T>) { 97 return AppendValue(std::make_shared<FloatingNumberEncodedParam<double>>(key, static_cast<double>(val))); 98 } 99 if constexpr (std::is_same_v<std::decay_t<T>, bool> || isSignedNum<T>) { 100 return AppendValue(std::make_shared<SignedVarintEncodedParam<int64_t>>(key, static_cast<int64_t>(val))); 101 } 102 if constexpr (isUnsignedNum<T>) { 103 return AppendValue(std::make_shared<UnsignedVarintEncodedParam<uint64_t>>(key, 104 static_cast<uint64_t>(val))); 105 } 106 return AppendArrayValue(key, val); 107 } 108 109 private: 110 template<typename T> UpdateType(const T val)111 RawDataBuilder& UpdateType(const T val) 112 { 113 if constexpr (isUnsignedNum<T>) { 114 return AppendType(static_cast<int>(val)); 115 } 116 return *this; 117 } 118 119 template<typename T> UpdateUid(const T val)120 RawDataBuilder& UpdateUid(const T val) 121 { 122 if constexpr (isUnsignedNum<T>) { 123 return AppendUid(static_cast<uint32_t>(val)); 124 } 125 return *this; 126 } 127 128 template<typename T> UpdateLog(const T val)129 RawDataBuilder& UpdateLog(const T val) 130 { 131 if constexpr (isUnsignedNum<T>) { 132 return AppendLog(static_cast<uint8_t>(val)); 133 } 134 return *this; 135 } 136 137 template<typename T> UpdatePid(const T val)138 RawDataBuilder& UpdatePid(const T val) 139 { 140 if constexpr (isUnsignedNum<T>) { 141 return AppendPid(static_cast<uint32_t>(val)); 142 } 143 return *this; 144 } 145 146 template<typename T> UpdateTid(const T val)147 RawDataBuilder& UpdateTid(const T val) 148 { 149 if constexpr (isUnsignedNum<T>) { 150 return AppendTid(static_cast<uint32_t>(val)); 151 } 152 return *this; 153 } 154 155 template<typename T> UpdateId(const T val)156 RawDataBuilder& UpdateId(const T val) 157 { 158 if constexpr (isString<T>) { 159 return AppendId(val); 160 } 161 if constexpr (isUnsignedNum<T>) { 162 return AppendId(static_cast<uint64_t>(val)); 163 } 164 return *this; 165 } 166 167 template<typename T> TransHexStrToNum(const std::string & hexStr,T & num)168 void TransHexStrToNum(const std::string& hexStr, T& num) 169 { 170 std::stringstream ss; 171 ss << std::hex << hexStr; 172 ss >> num >> std::dec; 173 } 174 175 template<typename T> UpdateTraceId(const T val)176 RawDataBuilder& UpdateTraceId(const T val) 177 { 178 if constexpr (isString<T>) { 179 uint64_t traceId = 0; 180 TransHexStrToNum(val, traceId); 181 return AppendTraceId(traceId); 182 } 183 if constexpr (isUnsignedNum<T>) { 184 return AppendTraceId(static_cast<uint64_t>(val)); 185 } 186 return *this; 187 } 188 189 template<typename T> UpdateSpanId(const T val)190 RawDataBuilder& UpdateSpanId(const T val) 191 { 192 if constexpr (isString<T>) { 193 uint32_t spanId = 0; 194 TransHexStrToNum(val, spanId); 195 return AppendSpanId(spanId); 196 } 197 if constexpr (isUnsignedNum<T>) { 198 return AppendSpanId(static_cast<uint32_t>(val)); 199 } 200 return *this; 201 } 202 203 template<typename T> UpdatePSpanId(const T val)204 RawDataBuilder& UpdatePSpanId(const T val) 205 { 206 if constexpr (isString<T>) { 207 uint32_t pSpanId = 0; 208 TransHexStrToNum(val, pSpanId); 209 return AppendPSpanId(pSpanId); 210 } 211 if constexpr (isUnsignedNum<T>) { 212 return AppendPSpanId(static_cast<uint32_t>(val)); 213 } 214 return *this; 215 } 216 217 template<typename T> UpdateTraceFlag(const T val)218 RawDataBuilder& UpdateTraceFlag(const T val) 219 { 220 if constexpr (isUnsignedNum<T>) { 221 return AppendTraceFlag(static_cast<uint8_t>(val)); 222 } 223 return *this; 224 } 225 226 template<typename T> AppendArrayValue(const std::string & key,T val)227 RawDataBuilder& AppendArrayValue(const std::string& key, T val) 228 { 229 if constexpr (std::is_same_v<std::decay_t<T>, std::vector<std::string>>) { 230 return AppendValue(std::make_shared<StringEncodedArrayParam>(key, val)); 231 } 232 if constexpr (isFloatingPointNumArray<T>) { 233 std::vector<double> dVector; 234 for (auto item : val) { 235 dVector.emplace_back(static_cast<double>(item)); 236 } 237 return AppendValue(std::make_shared<FloatingNumberEncodedArrayParam<double>>(key, dVector)); 238 } 239 if constexpr (std::is_same_v<std::decay_t<T>, std::vector<bool>> || isSignedNumArray<T>) { 240 std::vector<int64_t> i64Vector; 241 for (auto item : val) { 242 i64Vector.emplace_back(static_cast<int64_t>(item)); 243 } 244 return AppendValue(std::make_shared<SignedVarintEncodedArrayParam<int64_t>>(key, i64Vector)); 245 } 246 if constexpr (isUnsignedNumArray<T>) { 247 std::vector<uint64_t> i64Vector; 248 for (auto item : val) { 249 i64Vector.emplace_back(static_cast<uint64_t>(item)); 250 } 251 return AppendValue(std::make_shared<UnsignedVarintEncodedArrayParam<uint64_t>>(key, i64Vector)); 252 } 253 return *this; 254 } 255 256 template<typename T> InitBaseAppendHandlers(std::unordered_map<std::string,std::function<RawDataBuilder & (T)>> & handlers)257 void InitBaseAppendHandlers(std::unordered_map<std::string, std::function<RawDataBuilder&(T)>>& handlers) 258 { 259 handlers.emplace(BASE_INFO_KEY_DOMAIN, [this] (T val) -> decltype(auto) { 260 if constexpr (isString<T>) { 261 return this->AppendDomain(val); 262 } 263 return *this; 264 }); 265 handlers.emplace(BASE_INFO_KEY_NAME, [this] (T val) -> decltype(auto) { 266 if constexpr (isString<T>) { 267 return this->AppendName(val); 268 } 269 return *this; 270 }); 271 handlers.emplace(BASE_INFO_KEY_TYPE, [this] (T val) -> decltype(auto) { 272 return this->UpdateType(val); 273 }); 274 handlers.emplace(BASE_INFO_KEY_TIME_STAMP, [this] (T val) -> decltype(auto) { 275 if constexpr (std::is_same_v<std::decay_t<T>, uint64_t>) { 276 return this->AppendTimeStamp(val); 277 } 278 return *this; 279 }); 280 handlers.emplace(BASE_INFO_KEY_TIME_ZONE, [this] (T val) -> decltype(auto) { 281 if constexpr (isString<T>) { 282 return this->AppendTimeZone(val); 283 } 284 return *this; 285 }); 286 } 287 288 template<typename T> InitIdInfoAppendHandlers(std::unordered_map<std::string,std::function<RawDataBuilder & (T)>> & handlers)289 void InitIdInfoAppendHandlers(std::unordered_map<std::string, std::function<RawDataBuilder&(T)>>& handlers) 290 { 291 handlers.emplace(BASE_INFO_KEY_ID, [this] (T val) -> decltype(auto) { 292 return this->UpdateId(val); 293 }); 294 handlers.emplace(BASE_INFO_KEY_PID, [this] (T val) -> decltype(auto) { 295 return this->UpdatePid(val); 296 }); 297 handlers.emplace(BASE_INFO_KEY_TID, [this] (T val) -> decltype(auto) { 298 return this->UpdateTid(val); 299 }); 300 handlers.emplace(BASE_INFO_KEY_UID, [this] (T val) -> decltype(auto) { 301 return this->UpdateUid(val); 302 }); 303 handlers.emplace(BASE_INFO_KEY_LOG, [this] (T val) -> decltype(auto) { 304 return this->UpdateLog(val); 305 }); 306 handlers.emplace(BASE_INFO_KEY_TRACE_ID, [this] (T val) -> decltype(auto) { 307 return this->UpdateTraceId(val); 308 }); 309 handlers.emplace(BASE_INFO_KEY_SPAN_ID, [this] (T val) -> decltype(auto) { 310 return this->UpdateSpanId(val); 311 }); 312 handlers.emplace(BASE_INFO_KEY_PARENT_SPAN_ID, [this] (T val) -> decltype(auto) { 313 return this->UpdatePSpanId(val); 314 }); 315 handlers.emplace(BASE_INFO_KEY_TRACE_FLAG, [this] (T val) -> decltype(auto) { 316 return this->UpdateTraceFlag(val); 317 }); 318 } 319 320 template<typename T> AppendBaseInfoValue(const std::string & key,T val)321 RawDataBuilder& AppendBaseInfoValue(const std::string& key, T val) 322 { 323 std::unordered_map<std::string, std::function<RawDataBuilder&(T)>> appendHandlers; 324 InitBaseAppendHandlers(appendHandlers); 325 InitIdInfoAppendHandlers(appendHandlers); 326 auto iter = appendHandlers.find(key); 327 return (iter == appendHandlers.end()) ? *this : iter->second(val); 328 } 329 330 template<typename T> GetArrayValueByKey(std::shared_ptr<EncodedParam> encodedParam,T & val)331 bool GetArrayValueByKey(std::shared_ptr<EncodedParam> encodedParam, T& val) 332 { 333 std::unordered_map<DataCodedType, 334 std::function<bool(std::shared_ptr<EncodedParam>, T&)>> getFuncs = { 335 {DataCodedType::UNSIGNED_VARINT_ARRAY, [] (std::shared_ptr<EncodedParam> param, T& val) { 336 if constexpr (std::is_same_v<std::decay_t<T>, std::vector<uint64_t>>) { 337 param->AsUint64Vec(val); 338 return true; 339 } 340 return false; 341 } 342 }, 343 {DataCodedType::SIGNED_VARINT_ARRAY, [] (std::shared_ptr<EncodedParam> param, T& val) { 344 if constexpr (std::is_same_v<std::decay_t<T>, std::vector<int64_t>>) { 345 param->AsInt64Vec(val); 346 return true; 347 } 348 return false; 349 } 350 }, 351 {DataCodedType::FLOATING_ARRAY, [] (std::shared_ptr<EncodedParam> param, T& val) { 352 if constexpr (std::is_same_v<std::decay_t<T>, std::vector<double>>) { 353 param->AsDoubleVec(val); 354 return true; 355 } 356 return false; 357 } 358 }, 359 {DataCodedType::DSTRING_ARRAY, [] (std::shared_ptr<EncodedParam> param, T& val) { 360 if constexpr (std::is_same_v<std::decay_t<T>, std::vector<std::string>>) { 361 param->AsStringVec(val); 362 return true; 363 } 364 return false; 365 } 366 } 367 }; 368 auto iter = getFuncs.find(encodedParam->GetDataCodedType()); 369 return (iter == getFuncs.end()) ? false : iter->second(encodedParam, val); 370 } 371 372 template<typename T> GetValueByKey(const std::string & key,T & val)373 bool GetValueByKey(const std::string& key, T& val) 374 { 375 auto encodedParam = GetValue(key); 376 if (encodedParam == nullptr) { 377 return false; 378 } 379 std::unordered_map<DataCodedType, std::function<bool(std::shared_ptr<EncodedParam>, T&)>> getFuncs = { 380 {DataCodedType::UNSIGNED_VARINT, [] (std::shared_ptr<EncodedParam> param, T& val) { 381 if constexpr (std::is_same_v<std::decay_t<T>, uint64_t>) { 382 param->AsUint64(val); 383 return true; 384 } 385 return false; 386 } 387 }, 388 {DataCodedType::SIGNED_VARINT, [] (std::shared_ptr<EncodedParam> param, T& val) { 389 if constexpr (std::is_same_v<std::decay_t<T>, int64_t>) { 390 param->AsInt64(val); 391 return true; 392 } 393 return false; 394 } 395 }, 396 {DataCodedType::FLOATING, [] (std::shared_ptr<EncodedParam> param, T& val) { 397 if constexpr (std::is_same_v<std::decay_t<T>, double>) { 398 param->AsDouble(val); 399 return true; 400 } 401 return false; 402 } 403 }, 404 {DataCodedType::DSTRING, [] (std::shared_ptr<EncodedParam> param, T& val) { 405 if constexpr (isString<T>) { 406 param->AsString(val); 407 return true; 408 } 409 return false; 410 } 411 } 412 }; 413 auto iter = getFuncs.find(encodedParam->GetDataCodedType()); 414 return (iter == getFuncs.end()) ? GetArrayValueByKey(encodedParam, val) : iter->second(encodedParam, val);\ 415 } 416 417 template<typename T, typename V> ParseAndSetTraceInfo(T & to,V from)418 bool ParseAndSetTraceInfo(T& to, V from) 419 { 420 if constexpr (std::is_same_v<std::decay_t<T>, std::string>) { 421 to = TransNumToHexStr(from); 422 return true; 423 } 424 return ParseValue(to, from); 425 } 426 427 template<typename T> GetBaseInfoValueByKey(const std::string & key,T & val)428 bool GetBaseInfoValueByKey(const std::string& key, T& val) 429 { 430 std::unordered_map<std::string, std::function<bool(T&)>> parseFuncs; 431 parseFuncs.emplace(BASE_INFO_KEY_DOMAIN, [this] (T& val) -> bool { 432 return this->ParseValue(val, std::string(header_.domain)); 433 }); 434 parseFuncs.emplace(BASE_INFO_KEY_NAME, [this] (T& val) -> bool { 435 return this->ParseValue(val, std::string(header_.name)); 436 }); 437 parseFuncs.emplace(BASE_INFO_KEY_TYPE, [this] (T& val) -> bool { 438 int type = static_cast<int>(header_.type) + 1; 439 return this->ParseValue(val, type); 440 }); 441 parseFuncs.emplace(BASE_INFO_KEY_TIME_STAMP, [this] (T& val) -> bool { 442 return this->ParseValue(val, header_.timestamp); 443 }); 444 parseFuncs.emplace(BASE_INFO_KEY_TIME_ZONE, [this] (T& val) -> bool { 445 return this->ParseTimeZoneFromHeader(val); 446 }); 447 parseFuncs.emplace(BASE_INFO_KEY_ID, [this] (T& val) -> bool { 448 return this->ParseValue(val, header_.id); 449 }); 450 parseFuncs.emplace(BASE_INFO_KEY_PID, [this] (T& val) -> bool { 451 return this->ParseValue(val, header_.pid); 452 }); 453 parseFuncs.emplace(BASE_INFO_KEY_TID, [this] (T& val) -> bool { 454 return this->ParseValue(val, header_.tid); 455 }); 456 parseFuncs.emplace(BASE_INFO_KEY_UID, [this] (T& val) -> bool { 457 return this->ParseValue(val, header_.uid); 458 }); 459 parseFuncs.emplace(BASE_INFO_KEY_LOG, [this] (T& val) -> bool { 460 return this->ParseValue(val, header_.log); 461 }); 462 parseFuncs.emplace(BASE_INFO_KEY_TRACE_ID, [this] (T& val) -> bool { 463 return this->ParseAndSetTraceInfo(val, traceInfo_.traceId); 464 }); 465 parseFuncs.emplace(BASE_INFO_KEY_SPAN_ID, [this] (T& val) -> bool { 466 return this->ParseAndSetTraceInfo(val, traceInfo_.spanId); 467 }); 468 parseFuncs.emplace(BASE_INFO_KEY_PARENT_SPAN_ID, [this] (T& val) -> bool { 469 return this->ParseAndSetTraceInfo(val, traceInfo_.pSpanId); 470 }); 471 parseFuncs.emplace(BASE_INFO_KEY_TRACE_FLAG, [this] (T& val) -> bool { 472 return this->PareTraceFlagFromHeader(val); 473 }); 474 auto iter = parseFuncs.find(key); 475 return (iter == parseFuncs.end()) ? false : iter->second(val); 476 } 477 478 template<typename T, typename V> ParseValue(T & to,V from)479 bool ParseValue(T& to, V from) 480 { 481 if constexpr (std::is_same_v<std::decay_t<T>, std::decay_t<V>>) { 482 to = from; 483 return true; 484 } 485 if constexpr ((isSignedNum<T> && isSignedNum<V>) || (isUnsignedNum<T> && isUnsignedNum<V>)) { 486 to = static_cast<std::decay_t<T>>(from); 487 return true; 488 } 489 return false; 490 } 491 492 template<typename T> ParseTimeZoneFromHeader(T & val)493 bool ParseTimeZoneFromHeader(T& val) 494 { 495 if constexpr (isUnsignedNum<T>) { 496 val = static_cast<std::decay_t<T>>(header_.timeZone); 497 return true; 498 } 499 if constexpr (isString<T>) { 500 val = ParseTimeZone(header_.timeZone); 501 return true; 502 } 503 return false; 504 } 505 506 template<typename T> PareTraceFlagFromHeader(T & val)507 bool PareTraceFlagFromHeader(T& val) 508 { 509 if constexpr (isUnsignedNum<T>) { 510 val = static_cast<std::decay_t<T>>(traceInfo_.traceFlag); 511 return true; 512 } 513 return false; 514 } 515 516 bool BuildHeader(std::shared_ptr<RawData> dest); 517 bool BuildCustomizedParams(std::shared_ptr<RawData> dest); 518 void InitValueParams(const std::vector<std::shared_ptr<DecodedParam>>& params); 519 void InitArrayValueParams(const std::vector<std::shared_ptr<DecodedParam>>& params); 520 521 private: 522 struct HiSysEventHeader header_ = { 523 .domain = {0}, 524 .name = {0}, 525 .timestamp = 0, 526 .timeZone = 0, 527 .uid = 0, 528 .pid = 0, 529 .tid = 0, 530 .id = 0, 531 .type = 0, 532 .isTraceOpened = 0, 533 .log = 0, 534 }; 535 struct TraceInfo traceInfo_ { 536 .traceFlag = 0, 537 .traceId = 0, 538 .spanId = 0, 539 .pSpanId = 0, 540 }; 541 std::list<std::shared_ptr<EncodedParam>> allParams_; 542 std::mutex paramsOptMtx_; 543 }; 544 } // namespace EventRaw 545 } // namespace HiviewDFX 546 } // namespace OHOS 547 548 #endif // BASE_EVENT_RAW_ENCODE_INCLUDE_RAW_DATA_BUILDER_H 549