• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "decoded/decoded_event.h"
17 
18 #include <functional>
19 #include <securec.h>
20 #include <sstream>
21 #include <unordered_map>
22 
23 #include "base/raw_data_base_def.h"
24 #include "decoded/raw_data_decoder.h"
25 #include "hiview_logger.h"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace EventRaw {
30 DEFINE_LOG_TAG("HiView-DecodedEvent");
31 namespace {
32 constexpr size_t MAX_BLOCK_SIZE = 384 * 1024; // 384K
33 constexpr size_t MAX_PARAM_CNT = 128 + 10; // 128 for Write, 10 for hiview
34 
TransUInt64ToFixedLengthStr(uint64_t src)35 std::string TransUInt64ToFixedLengthStr(uint64_t src)
36 {
37     const size_t maxIdLen = 20;
38     std::string uint64Str = std::to_string(src);
39     if (uint64Str.size() >= maxIdLen) {
40         return uint64Str;
41     }
42     std::string dest(maxIdLen, '0');
43     dest.replace(maxIdLen - uint64Str.size(), uint64Str.size(), uint64Str);
44     return dest;
45 }
46 }
47 
DecodedEvent(uint8_t * src)48 DecodedEvent::DecodedEvent(uint8_t* src)
49 {
50     if (src == nullptr) {
51         return;
52     }
53     size_t blockSize = static_cast<size_t>(*(reinterpret_cast<int32_t*>(src)));
54     if (blockSize < GetValidDataMinimumByteCount() || blockSize > MAX_BLOCK_SIZE) {
55         HIVIEW_LOGE("size of raw data is %{public}zu, which is invalid.", blockSize);
56         return;
57     }
58     rawData_ = new(std::nothrow) uint8_t[blockSize];
59     if (rawData_ == nullptr) {
60         return;
61     }
62     auto ret = memcpy_s(rawData_, blockSize, src, blockSize);
63     if (ret != EOK) {
64         HIVIEW_LOGE("Decode memory copy failed, ret is %{public}d.", ret);
65         delete[] rawData_;
66         return;
67     }
68     Parse();
69 }
70 
~DecodedEvent()71 DecodedEvent::~DecodedEvent()
72 {
73     if (rawData_ != nullptr) {
74         delete[] rawData_;
75         rawData_ = nullptr;
76     }
77 }
78 
AppendBaseInfo(std::stringstream & ss)79 void DecodedEvent::AppendBaseInfo(std::stringstream& ss)
80 {
81     size_t domainArraySize = MAX_DOMAIN_LENGTH + 1;
82     char* domain = new(std::nothrow) char[domainArraySize];
83     if (domain == nullptr) {
84         return;
85     }
86     if (memcpy_s(domain, domainArraySize, header_.domain, MAX_DOMAIN_LENGTH) != EOK) {
87         delete[] domain;
88         return;
89     }
90     domain[MAX_DOMAIN_LENGTH] = '\0';
91     auto eventDomain = std::string(domain);
92     AppendValue(ss, BASE_INFO_KEY_DOMAIN, eventDomain);
93     delete[] domain;
94     size_t nameArraySize = MAX_EVENT_NAME_LENGTH + 1;
95     char* name = new(std::nothrow) char[nameArraySize];
96     if (name == nullptr) {
97         return;
98     }
99     if (memcpy_s(name, nameArraySize, header_.name, MAX_EVENT_NAME_LENGTH) != EOK) {
100         delete[] name;
101         return;
102     }
103     name[MAX_EVENT_NAME_LENGTH] = '\0';
104     auto eventName = std::string(name);
105     AppendValue(ss, BASE_INFO_KEY_NAME, eventName);
106     delete[] name;
107     AppendValue(ss, BASE_INFO_KEY_TYPE, (static_cast<int>(header_.type) + 1)); // header_.type is only 2 bits which has
108                                                                           // been subtracted 1 before wrote.
109     AppendValue(ss, BASE_INFO_KEY_TIME_STAMP, header_.timestamp);
110     auto timeZone = ParseTimeZone(static_cast<size_t>(header_.timeZone));
111     AppendValue(ss, BASE_INFO_KEY_TIME_ZONE, timeZone);
112     AppendValue(ss, BASE_INFO_KEY_PID, header_.pid);
113     AppendValue(ss, BASE_INFO_KEY_TID, header_.tid);
114     AppendValue(ss, BASE_INFO_KEY_UID, header_.uid);
115     AppendValue(ss, BASE_INFO_KEY_LOG, static_cast<uint32_t>(header_.log));
116     AppendValue(ss, BASE_INFO_KEY_ID, TransUInt64ToFixedLengthStr(header_.id));
117     if (header_.isTraceOpened == 1) {
118         AppendValue(ss, BASE_INFO_KEY_TRACE_FLAG, static_cast<int>(traceInfo_.traceFlag));
119         AppendValue(ss, BASE_INFO_KEY_TRACE_ID, TransNumToHexStr(traceInfo_.traceId));
120         AppendValue(ss, BASE_INFO_KEY_SPAN_ID, TransNumToHexStr(traceInfo_.spanId));
121         AppendValue(ss, BASE_INFO_KEY_PARENT_SPAN_ID, TransNumToHexStr(traceInfo_.pSpanId));
122     }
123 }
124 
AppendCustomizedArrayParam(std::stringstream & ss,std::shared_ptr<DecodedParam> param)125 void DecodedEvent::AppendCustomizedArrayParam(std::stringstream& ss, std::shared_ptr<DecodedParam> param)
126 {
127     std::unordered_map<DataCodedType, std::function<void(std::shared_ptr<DecodedParam>)>> allFuncs = {
128         {DataCodedType::UNSIGNED_VARINT_ARRAY, [this, &ss](std::shared_ptr<DecodedParam> param) {
129                 std::vector<uint64_t> u64Vec;
130                 if (param->AsUint64Vec(u64Vec)) {
131                     this->AppendValue(ss, param->GetKey(), u64Vec);
132                 }
133             }
134         },
135         {DataCodedType::SIGNED_VARINT_ARRAY, [this, &ss](std::shared_ptr<DecodedParam> param) {
136                 std::vector<int64_t> i64Vec;
137                 if (param->AsInt64Vec(i64Vec)) {
138                     this->AppendValue(ss, param->GetKey(), i64Vec);
139                 }
140             }
141         },
142         {DataCodedType::FLOATING_ARRAY, [this, &ss](std::shared_ptr<DecodedParam> param) {
143                 std::vector<double> dVec;
144                 if (param->AsDoubleVec(dVec)) {
145                     this->AppendValue(ss, param->GetKey(), dVec);
146                 }
147             }
148         },
149         {DataCodedType::DSTRING_ARRAY, [this, &ss](std::shared_ptr<DecodedParam> param) {
150                 std::vector<std::string> strVec;
151                 if (param->AsStringVec(strVec)) {
152                     this->AppendValue(ss, param->GetKey(), strVec);
153                 }
154             }
155         }
156     };
157     auto iter = allFuncs.find(param->GetDataCodedType());
158     if (iter == allFuncs.end()) {
159         return;
160     }
161     iter->second(param);
162 }
163 
AppendCustomizedParam(std::stringstream & ss,std::shared_ptr<DecodedParam> param)164 void DecodedEvent::AppendCustomizedParam(std::stringstream& ss, std::shared_ptr<DecodedParam> param)
165 {
166     std::unordered_map<DataCodedType, std::function<void(std::shared_ptr<DecodedParam>)>> allFuncs = {
167         {DataCodedType::UNSIGNED_VARINT, [this, &ss](std::shared_ptr<DecodedParam> param) {
168                 uint64_t uint64DecodedVal;
169                 if (param->AsUint64(uint64DecodedVal)) {
170                     this->AppendValue(ss, param->GetKey(), uint64DecodedVal);
171                 }
172             }
173         },
174         {DataCodedType::SIGNED_VARINT, [this, &ss](std::shared_ptr<DecodedParam> param) {
175                 int64_t int64DecodedVal;
176                 if (param->AsInt64(int64DecodedVal)) {
177                     this->AppendValue(ss, param->GetKey(), int64DecodedVal);
178                 }
179             }
180         },
181         {DataCodedType::FLOATING, [this, &ss](std::shared_ptr<DecodedParam> param) {
182                 double dDecodedVal;
183                 if (param->AsDouble(dDecodedVal)) {
184                     this->AppendValue(ss, param->GetKey(), dDecodedVal);
185                 }
186             }
187         },
188         {DataCodedType::DSTRING, [this, &ss](std::shared_ptr<DecodedParam> param) {
189                 std::string strDecodedVal;
190                 if (param->AsString(strDecodedVal)) {
191                     this->AppendValue(ss, param->GetKey(), strDecodedVal);
192                 }
193             }
194         }
195     };
196     auto iter = allFuncs.find(param->GetDataCodedType());
197     if (iter == allFuncs.end()) {
198         return;
199     }
200     iter->second(param);
201 }
202 
AppendCustomizedParams(std::stringstream & ss)203 void DecodedEvent::AppendCustomizedParams(std::stringstream& ss)
204 {
205     for (auto param: allParams_) {
206         if (param == nullptr) {
207             continue;
208         }
209         std::vector<DataCodedType> noArrayEncodedTypes = {
210             DataCodedType::UNSIGNED_VARINT,
211             DataCodedType::SIGNED_VARINT,
212             DataCodedType::FLOATING,
213             DataCodedType::DSTRING,
214         };
215         if (find(noArrayEncodedTypes.begin(), noArrayEncodedTypes.end(), param->GetDataCodedType()) !=
216             noArrayEncodedTypes.end()) {
217             AppendCustomizedParam(ss, param);
218             continue;
219         }
220         AppendCustomizedArrayParam(ss, param);
221     }
222 }
223 
AsJsonStr()224 std::string DecodedEvent::AsJsonStr()
225 {
226     std::stringstream jsonStream;
227     jsonStream << "{";
228     AppendBaseInfo(jsonStream);
229     AppendCustomizedParams(jsonStream);
230     if (jsonStream.tellp() != 0) {
231         jsonStream.seekp(-1, std::ios_base::end);
232     }
233     jsonStream << "}";
234     return jsonStream.str();
235 }
236 
GetRawData()237 std::shared_ptr<RawData> DecodedEvent::GetRawData()
238 {
239     return std::make_shared<RawData>(rawData_, pos_);
240 }
241 
IsValid()242 bool DecodedEvent::IsValid()
243 {
244     return isValid_;
245 }
246 
GetHeader()247 const struct HiSysEventHeader& DecodedEvent::GetHeader()
248 {
249     return header_;
250 }
251 
GetTraceInfo()252 const struct TraceInfo& DecodedEvent::GetTraceInfo()
253 {
254     return traceInfo_;
255 }
256 
GetAllCustomizedValues()257 const std::vector<std::shared_ptr<DecodedParam>>& DecodedEvent::GetAllCustomizedValues()
258 {
259     return allParams_;
260 }
261 
Parse()262 void DecodedEvent::Parse()
263 {
264     isValid_ = true;
265     if (rawData_ == nullptr) {
266         isValid_ = false;
267         return;
268     }
269     pos_ = 0; // reset to 0
270     // decode block size
271     size_t blockSize = static_cast<size_t>(*(reinterpret_cast<int32_t*>(rawData_)));
272     pos_ += sizeof(int32_t);
273     ParseHeader(blockSize);
274     ParseCustomizedParams(blockSize);
275 }
276 
ParseHeader(const size_t maxLen)277 void DecodedEvent::ParseHeader(const size_t maxLen)
278 {
279     // decode event header
280     if ((pos_ + sizeof(struct HiSysEventHeader)) > maxLen) {
281         isValid_ = false;
282         return;
283     }
284     header_ = *(reinterpret_cast<struct HiSysEventHeader*>(rawData_ + pos_));
285     pos_ += sizeof(struct HiSysEventHeader);
286     // decode trace info
287     if (header_.isTraceOpened == 1) { // 1: include trace info, 0: exclude trace info
288         if (((pos_ + sizeof(struct TraceInfo)) > maxLen)) {
289             isValid_ = false;
290             return;
291         }
292         traceInfo_ = *(reinterpret_cast<struct TraceInfo*>(rawData_ + pos_));
293         pos_ += sizeof(struct TraceInfo);
294     }
295 }
296 
ParseCustomizedParams(const size_t maxLen)297 void DecodedEvent::ParseCustomizedParams(const size_t maxLen)
298 {
299     if ((pos_ + sizeof(int32_t)) > maxLen) {
300         isValid_ = false;
301         return;
302     }
303     auto paramCnt = static_cast<size_t>(*(reinterpret_cast<int32_t*>(rawData_ + pos_)));
304     if (paramCnt > MAX_PARAM_CNT) {
305         HIVIEW_LOGW("invalid param cnt=%{public}zu.", paramCnt);
306         isValid_ = false;
307         return;
308     }
309     pos_ += sizeof(int32_t);
310     while (paramCnt > 0) {
311         auto decodedParam = ParseCustomizedParam(maxLen);
312         if (decodedParam == nullptr || !(decodedParam->DecodeValue())) {
313             HIVIEW_LOGE("Value of customized parameter is decoded failed.");
314             isValid_ = false;
315             return;
316         }
317         pos_ = decodedParam->GetPosition();
318         allParams_.emplace_back(decodedParam);
319         --paramCnt;
320     }
321 }
322 
CreateFloatingNumTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)323 std::shared_ptr<DecodedParam> DecodedEvent::CreateFloatingNumTypeDecodedParam(const size_t maxLen,
324     const std::string& key, bool isArray)
325 {
326     if (isArray) {
327         return std::make_shared<FloatingNumberDecodedArrayParam>(rawData_, maxLen, pos_, key);
328     }
329     return std::make_shared<FloatingNumberDecodedParam>(rawData_, maxLen, pos_, key);
330 }
331 
CreateSignedVarintTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)332 std::shared_ptr<DecodedParam> DecodedEvent::CreateSignedVarintTypeDecodedParam(const size_t maxLen,
333     const std::string& key, bool isArray)
334 {
335     if (isArray) {
336         return std::make_shared<SignedVarintDecodedArrayParam>(rawData_, maxLen, pos_, key);
337     }
338     return std::make_shared<SignedVarintDecodedParam>(rawData_, maxLen, pos_, key);
339 }
340 
CreateStringTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)341 std::shared_ptr<DecodedParam> DecodedEvent::CreateStringTypeDecodedParam(const size_t maxLen,
342     const std::string& key, bool isArray)
343 {
344     if (isArray) {
345         return std::make_shared<StringDecodedArrayParam>(rawData_, maxLen, pos_, key);
346     }
347     return std::make_shared<StringDecodedParam>(rawData_, maxLen, pos_, key);
348 }
349 
CreateUnsignedVarintTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)350 std::shared_ptr<DecodedParam> DecodedEvent::CreateUnsignedVarintTypeDecodedParam(const size_t maxLen,
351     const std::string& key, bool isArray)
352 {
353     if (isArray) {
354         return std::make_shared<UnsignedVarintDecodedArrayParam>(rawData_, maxLen, pos_, key);
355     }
356     return std::make_shared<UnsignedVarintDecodedParam>(rawData_, maxLen, pos_, key);
357 }
358 
ParseCustomizedParam(const size_t maxLen)359 std::shared_ptr<DecodedParam> DecodedEvent::ParseCustomizedParam(const size_t maxLen)
360 {
361     std::string key;
362     if (!RawDataDecoder::StringValueDecoded(rawData_, maxLen, pos_, key)) {
363         isValid_ = false;
364         return nullptr;
365     }
366     struct ParamValueType valueType {
367         .isArray = 0,
368         .valueType = static_cast<uint8_t>(ValueType::UNKNOWN),
369         .valueByteCnt = 0,
370     };
371     if (!RawDataDecoder::ValueTypeDecoded(rawData_, maxLen, pos_, valueType)) {
372         isValid_ = false;
373         return nullptr;
374     }
375     std::shared_ptr<DecodedParam> ret = nullptr;
376     switch (ValueType(valueType.valueType)) {
377         case ValueType::STRING: {
378             ret = CreateStringTypeDecodedParam(maxLen, key, valueType.isArray == 1);
379             break;
380         }
381         case ValueType::FLOAT:
382         case ValueType::DOUBLE: {
383             ret = CreateFloatingNumTypeDecodedParam(maxLen, key, valueType.isArray == 1);
384             break;
385         }
386         case ValueType::UINT8:
387         case ValueType::UINT16:
388         case ValueType::UINT32:
389         case ValueType::UINT64: {
390             ret = CreateUnsignedVarintTypeDecodedParam(maxLen, key, valueType.isArray == 1);
391             break;
392         }
393         case ValueType::BOOL:
394         case ValueType::INT8:
395         case ValueType::INT16:
396         case ValueType::INT32:
397         case ValueType::INT64: {
398             ret = CreateSignedVarintTypeDecodedParam(maxLen, key, valueType.isArray == 1);
399             break;
400         }
401         default:
402             break;
403     }
404     return ret;
405 }
406 } // namespace EventRaw
407 } // namespace HiviewDFX
408 } // namespace OHOS