1 /*
2  * Copyright (c) 2021-2024 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 #include "sys_event.h"
16 
17 #include <chrono>
18 #include <functional>
19 #include <limits>
20 #include <memory>
21 #include <regex>
22 #include <sstream>
23 #include <string>
24 #include <sys/time.h>
25 #include <vector>
26 
27 #include "encoded/raw_data_builder_json_parser.h"
28 #include "string_util.h"
29 #include "time_util.h"
30 
31 namespace OHOS {
32 namespace HiviewDFX {
33 namespace EventStore {
34 std::string EventCol::DOMAIN = "domain_";
35 std::string EventCol::NAME = "name_";
36 std::string EventCol::TYPE = "type_";
37 std::string EventCol::TS = "time_";
38 std::string EventCol::TZ = "tz_";
39 std::string EventCol::PID = "pid_";
40 std::string EventCol::TID = "tid_";
41 std::string EventCol::UID = "uid_";
42 std::string EventCol::INFO = "info_";
43 std::string EventCol::LEVEL = "level_";
44 std::string EventCol::SEQ = "seq_";
45 std::string EventCol::TAG = "tag_";
46 }
47 using EventRaw::HiSysEventHeader;
48 namespace {
49 constexpr int64_t DEFAULT_INT_VALUE = 0;
50 constexpr uint64_t DEFAULT_UINT_VALUE = 0;
51 constexpr double DEFAULT_DOUBLE_VALUE = 0.0;
52 constexpr size_t BLOCK_SIZE_OFFSET = sizeof(int32_t);
53 
54 template<typename T>
AppendJsonValue(std::string & eventJson,const std::string & key,T val)55 void AppendJsonValue(std::string& eventJson, const std::string& key, T val)
56 {
57     if (eventJson.empty()) {
58         return;
59     }
60     std::string findKey = "\"" + key + "\":";
61     if (eventJson.find(findKey) != std::string::npos) {
62         return;
63     }
64     std::string appendStr;
65     appendStr.append(",\"").append(key).append("\":");
66     if constexpr (std::is_same_v<std::decay_t<T>, std::string>) {
67         appendStr.append("\"").append(val).append("\"");
68     } else {
69         appendStr.append(std::to_string(val));
70     }
71     eventJson.insert(eventJson.size() - 1, appendStr); // 1 for '}'
72 }
73 
74 template<typename T>
ParseArrayValue(std::shared_ptr<EventRaw::RawDataBuilder> builder,const std::string & key,std::function<bool (T &)> itemHandler)75 bool ParseArrayValue(std::shared_ptr<EventRaw::RawDataBuilder> builder, const std::string& key,
76     std::function<bool(T&)> itemHandler)
77 {
78     if (builder == nullptr) {
79         return false;
80     }
81     if (std::vector<T> arr; builder->ParseValueByKey(key, arr)) {
82         if (arr.empty()) {
83             return true;
84         }
85         return all_of(arr.begin(), arr.end(), [&itemHandler] (T& item) {
86             return itemHandler(item);
87         });
88     }
89     return false;
90 }
91 }
92 using EventRaw::UnsignedVarintEncodedParam;
93 using EventRaw::SignedVarintEncodedParam;
94 using EventRaw::FloatingNumberEncodedParam;
95 using EventRaw::StringEncodedParam;
96 using EventRaw::UnsignedVarintEncodedArrayParam;
97 using EventRaw::SignedVarintEncodedArrayParam;
98 using EventRaw::FloatingNumberEncodedArrayParam;
99 using EventRaw::StringEncodedArrayParam;
100 std::atomic<uint32_t> SysEvent::totalCount_(0);
101 std::atomic<int64_t> SysEvent::totalSize_(0);
102 
SysEvent(const std::string & sender,PipelineEventProducer * handler,std::shared_ptr<EventRaw::RawData> rawData,int64_t seq,const std::string & sysVersion,const std::string & patchVersion)103 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler,
104     std::shared_ptr<EventRaw::RawData> rawData, int64_t seq,
105     const std::string& sysVersion, const std::string& patchVersion)
106     : PipelineEvent(sender, handler), eventType_(0), preserve_(true), log_(0),  seq_(seq)
107 {
108     messageType_ = Event::MessageType::SYS_EVENT;
109     if (rawData == nullptr || rawData->GetData() == nullptr ||
110         rawData->GetDataLength() < EventRaw::GetValidDataMinimumByteCount()) {
111         return;
112     }
113     sysVersion_ = sysVersion;
114     patchVersion_ = patchVersion;
115     rawData_ = rawData;
116     totalCount_.fetch_add(1);
117     totalSize_.fetch_add(*(reinterpret_cast<int32_t*>(rawData_->GetData())));
118     InitialMembers();
119 }
120 
SysEvent(const std::string & sender,PipelineEventProducer * handler,std::shared_ptr<EventRaw::RawData> rawData,int64_t seq)121 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler,
122     std::shared_ptr<EventRaw::RawData> rawData, int64_t seq)
123     : SysEvent(sender, handler, rawData, seq, "", "")
124 {
125 }
126 
SysEvent(const std::string & sender,PipelineEventProducer * handler,std::shared_ptr<EventRaw::RawData> rawData)127 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler,
128     std::shared_ptr<EventRaw::RawData> rawData)
129     : SysEvent(sender, handler, rawData, 0)
130 {}
131 
SysEvent(const std::string & sender,PipelineEventProducer * handler,SysEventCreator & sysEventCreator)132 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, SysEventCreator& sysEventCreator)
133     : SysEvent(sender, handler, sysEventCreator.GetRawData())
134 {}
135 
SysEvent(const std::string & sender,PipelineEventProducer * handler,const std::string & jsonStr)136 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, const std::string& jsonStr)
137     : SysEvent(sender, handler, TansJsonStrToRawData(jsonStr))
138 {}
139 
~SysEvent()140 SysEvent::~SysEvent()
141 {
142     if (totalCount_ > 0) {
143         totalCount_.fetch_sub(1);
144     }
145     if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
146         totalSize_.fetch_sub(*(reinterpret_cast<int32_t*>(rawData_->GetData())));
147     }
148     if (totalSize_ < 0) {
149         totalSize_.store(0);
150     }
151 }
152 
InitialMembers()153 void SysEvent::InitialMembers()
154 {
155     HiSysEventHeader header = *(reinterpret_cast<struct HiSysEventHeader*>(rawData_->GetData() + BLOCK_SIZE_OFFSET));
156     domain_ = header.domain;
157     eventName_ = header.name;
158     eventType_ = static_cast<int32_t>(header.type) + 1;
159     happenTime_ = header.timestamp;
160     if (happenTime_ == 0) {
161         auto currentTimeStamp = TimeUtil::GetMilliseconds();
162         happenTime_ = currentTimeStamp;
163     }
164     tz_ = static_cast<int16_t>(header.timeZone);
165     pid_ = static_cast<int32_t>(header.pid);
166     tid_ = static_cast<int32_t>(header.tid);
167     uid_ = static_cast<int32_t>(header.uid);
168     log_ = header.log;
169 }
170 
InitBuilder()171 bool SysEvent::InitBuilder()
172 {
173     if (builder_ != nullptr) {
174         return true;
175     }
176     builder_ = std::make_shared<EventRaw::RawDataBuilder>(rawData_);
177     return builder_ != nullptr;
178 }
179 
TansJsonStrToRawData(const std::string & jsonStr)180 std::shared_ptr<EventRaw::RawData> SysEvent::TansJsonStrToRawData(const std::string& jsonStr)
181 {
182     auto parser = std::make_unique<EventRaw::RawDataBuilderJsonParser>(jsonStr);
183     if (parser == nullptr) {
184         return nullptr;
185     }
186     auto rawDataBuilder = parser->Parse();
187     if (rawDataBuilder == nullptr) {
188         return nullptr;
189     }
190     return rawDataBuilder->Build();
191 }
192 
SetTag(const std::string & tag)193 void SysEvent::SetTag(const std::string& tag)
194 {
195     tag_ = tag;
196 }
197 
GetTag() const198 std::string SysEvent::GetTag() const
199 {
200     return tag_;
201 }
202 
SetLevel(const std::string & level)203 void SysEvent::SetLevel(const std::string& level)
204 {
205     level_ = level;
206 }
207 
GetLevel() const208 std::string SysEvent::GetLevel() const
209 {
210     return level_;
211 }
212 
SetSeq(int64_t seq)213 void SysEvent::SetSeq(int64_t seq)
214 {
215     seq_ = seq;
216 }
217 
GetSeq() const218 int64_t SysEvent::GetSeq() const
219 {
220     return seq_;
221 }
222 
SetEventSeq(int64_t eventSeq)223 void SysEvent::SetEventSeq(int64_t eventSeq)
224 {
225     eventSeq_ = eventSeq;
226 }
227 
GetEventSeq() const228 int64_t SysEvent::GetEventSeq() const
229 {
230     return eventSeq_;
231 }
232 
GetPid() const233 int32_t SysEvent::GetPid() const
234 {
235     return pid_;
236 }
237 
GetTid() const238 int32_t SysEvent::GetTid() const
239 {
240     return tid_;
241 }
242 
GetUid() const243 int32_t SysEvent::GetUid() const
244 {
245     return uid_;
246 }
247 
GetTz() const248 int16_t SysEvent::GetTz() const
249 {
250     return tz_;
251 }
252 
GetEventType() const253 int SysEvent::GetEventType() const
254 {
255     return eventType_;
256 }
257 
SetId(uint64_t id)258 void SysEvent::SetId(uint64_t id)
259 {
260     if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
261         rawData_->Update(reinterpret_cast<uint8_t*>(&id), sizeof(uint64_t),
262             BLOCK_SIZE_OFFSET + EventRaw::POS_OF_ID_IN_HEADER);
263     }
264     if (builder_ != nullptr) {
265         builder_->AppendId(id);
266     }
267 }
268 
SetLog(uint8_t log)269 void SysEvent::SetLog(uint8_t log)
270 {
271     log_ = log;
272     if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
273         reinterpret_cast<struct HiSysEventHeader*>(
274             rawData_->GetData() + BLOCK_SIZE_OFFSET)->log = log;
275     }
276     if (builder_ != nullptr) {
277         builder_->AppendLog(log);
278     }
279 }
280 
SetPrivacy(uint8_t privacy)281 void SysEvent::SetPrivacy(uint8_t privacy)
282 {
283     privacy_ = privacy;
284 }
285 
GetPrivacy() const286 uint8_t SysEvent::GetPrivacy() const
287 {
288     return privacy_;
289 }
290 
GetEventValue(const std::string & key)291 std::string SysEvent::GetEventValue(const std::string& key)
292 {
293     if (!InitBuilder()) {
294         return "";
295     }
296     std::string dest;
297     builder_->ParseValueByKey(key, dest);
298     return dest;
299 }
300 
GetEventIntValue(const std::string & key)301 int64_t SysEvent::GetEventIntValue(const std::string& key)
302 {
303     if (!InitBuilder()) {
304         return DEFAULT_INT_VALUE;
305     }
306     if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest)) {
307         return intDest;
308     }
309     if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest) &&
310         (uIntDest <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))) {
311         return static_cast<int64_t>(uIntDest);
312     }
313     if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest) &&
314         (dDest >= static_cast<double>(std::numeric_limits<int64_t>::min())) &&
315         (dDest <= static_cast<double>(std::numeric_limits<int64_t>::max()))) {
316         return static_cast<int64_t>(dDest);
317     }
318     return DEFAULT_INT_VALUE;
319 }
320 
GetEventUintValue(const std::string & key)321 uint64_t SysEvent::GetEventUintValue(const std::string& key)
322 {
323     if (!InitBuilder()) {
324         return DEFAULT_UINT_VALUE;
325     }
326     if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest)) {
327         return uIntDest;
328     }
329     if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest) &&
330         (intDest >= DEFAULT_INT_VALUE)) {
331         return static_cast<uint64_t>(intDest);
332     }
333     if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest) &&
334         (dDest >= static_cast<double>(std::numeric_limits<uint64_t>::min())) &&
335         (dDest <= static_cast<double>(std::numeric_limits<uint64_t>::max()))) {
336         return static_cast<uint64_t>(dDest);
337     }
338     return DEFAULT_UINT_VALUE;
339 }
340 
GetEventDoubleValue(const std::string & key)341 double SysEvent::GetEventDoubleValue(const std::string& key)
342 {
343     if (!InitBuilder()) {
344         return DEFAULT_DOUBLE_VALUE;
345     }
346     if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest)) {
347         return dDest;
348     }
349     if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest)) {
350         return static_cast<double>(intDest);
351     }
352     if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest)) {
353         return static_cast<double>(uIntDest);
354     }
355     return DEFAULT_DOUBLE_VALUE;
356 }
357 
GetEventIntArrayValue(const std::string & key,std::vector<int64_t> & dest)358 bool SysEvent::GetEventIntArrayValue(const std::string& key, std::vector<int64_t>& dest)
359 {
360     dest.clear();
361     if (!InitBuilder()) {
362         return false;
363     }
364     auto intArrayItemHandler = [&dest] (int64_t& item) {
365         dest.emplace_back(item);
366         return true;
367     };
368     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
369         if (item <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
370             dest.emplace_back(static_cast<int64_t>(item));
371             return true;
372         }
373         return false;
374     };
375     auto dArrayItemHandler = [&dest] (double& item) {
376         if ((item >= static_cast<double>(std::numeric_limits<int64_t>::min())) &&
377             (item <= static_cast<double>(std::numeric_limits<int64_t>::max()))) {
378             dest.emplace_back(static_cast<int64_t>(item));
379             return true;
380         }
381         return false;
382     };
383     auto strArrayItemHandler = [&dest] (std::string& item) {
384         return false;
385     };
386     if (ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
387         ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
388         ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
389         ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
390         return true;
391     }
392     dest.clear();
393     return false;
394 }
395 
GetEventUintArrayValue(const std::string & key,std::vector<uint64_t> & dest)396 bool SysEvent::GetEventUintArrayValue(const std::string& key, std::vector<uint64_t>& dest)
397 {
398     dest.clear();
399     if (!InitBuilder()) {
400         return false;
401     }
402     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
403         dest.emplace_back(item);
404         return true;
405     };
406     auto intArrayItemHandler = [&dest] (int64_t& item) {
407         if (item >= DEFAULT_INT_VALUE) {
408             dest.emplace_back(static_cast<uint64_t>(item));
409             return true;
410         }
411         return false;
412     };
413     auto dArrayItemHandler = [&dest] (double& item) {
414         if ((item >= static_cast<double>(std::numeric_limits<uint64_t>::min())) &&
415             (item <= static_cast<double>(std::numeric_limits<uint64_t>::max()))) {
416             dest.emplace_back(static_cast<uint64_t>(item));
417             return true;
418         }
419         return false;
420     };
421     auto strArrayItemHandler = [&dest] (std::string& item) {
422         return false;
423     };
424     if (ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
425         ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
426         ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
427         ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
428         return true;
429     }
430     dest.clear();
431     return false;
432 }
433 
GetEventDoubleArrayValue(const std::string & key,std::vector<double> & dest)434 bool SysEvent::GetEventDoubleArrayValue(const std::string& key, std::vector<double>& dest)
435 {
436     dest.clear();
437     if (!InitBuilder()) {
438         return false;
439     }
440     auto dArrayItemHandler = [&dest] (double& item) {
441         dest.emplace_back(item);
442         return true;
443     };
444     auto intArrayItemHandler = [&dest] (int64_t& item) {
445         dest.emplace_back(static_cast<double>(item));
446         return true;
447     };
448     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
449         dest.emplace_back(static_cast<double>(item));
450         return true;
451     };
452     auto strArrayItemHandler = [&dest] (std::string& item) {
453         return false;
454     };
455     if (ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
456         ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
457         ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
458         ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
459         return true;
460     }
461     dest.clear();
462     return false;
463 }
464 
GetEventStringArrayValue(const std::string & key,std::vector<std::string> & dest)465 bool SysEvent::GetEventStringArrayValue(const std::string& key, std::vector<std::string>& dest)
466 {
467     dest.clear();
468     if (!InitBuilder()) {
469         return false;
470     }
471     auto strArrayItemHandler = [&dest] (std::string& item) {
472         dest.emplace_back(item);
473         return true;
474     };
475     auto dArrayItemHandler = [&dest] (double& item) {
476         return false;
477     };
478     auto intArrayItemHandler = [&dest] (int64_t& item) {
479         return false;
480     };
481     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
482         return false;
483     };
484     if (ParseArrayValue<std::string>(builder_, key, strArrayItemHandler) ||
485         ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
486         ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
487         ParseArrayValue<double>(builder_, key, dArrayItemHandler)) {
488         return true;
489     }
490     dest.clear();
491     return false;
492 }
493 
TryToUpdateRawData()494 bool SysEvent::TryToUpdateRawData()
495 {
496     if (rawData_ == nullptr) {
497         return false;
498     }
499 
500     // raw data does not need to be re-initialized
501     if (!isUpdated_) {
502         return true;
503     }
504 
505     // raw data needs to be re-initialized
506     if (!InitBuilder()) {
507         return false;
508     }
509     builder_->AppendLog(log_);
510     rawData_ = builder_->Build();
511     if (rawData_ == nullptr) {
512         return false;
513     }
514     isUpdated_ = false;
515     return true;
516 }
517 
AsJsonStr()518 std::string SysEvent::AsJsonStr()
519 {
520     if (!TryToUpdateRawData()) {
521         return "";
522     }
523 
524     std::string jsonStr;
525     {
526         EventRaw::DecodedEvent event(rawData_->GetData());
527         jsonStr = event.AsJsonStr();
528     }
529     if (!tag_.empty()) {
530         AppendJsonValue(jsonStr, EventStore::EventCol::TAG, tag_);
531     }
532     if (!level_.empty()) {
533         AppendJsonValue(jsonStr, EventStore::EventCol::LEVEL, level_);
534     }
535     if (eventSeq_ >= 0) {
536         AppendJsonValue(jsonStr, EventStore::EventCol::SEQ, eventSeq_);
537     }
538     return jsonStr;
539 }
540 
AsRawData()541 uint8_t* SysEvent::AsRawData()
542 {
543     if (!TryToUpdateRawData()) {
544         return nullptr;
545     }
546     return rawData_->GetData();
547 }
548 
EscapeJsonStringValue(const std::string & src)549 std::string SysEvent::EscapeJsonStringValue(const std::string& src)
550 {
551     return StringUtil::EscapeJsonStringValue(src);
552 }
553 
UnescapeJsonStringValue(const std::string & src)554 std::string SysEvent::UnescapeJsonStringValue(const std::string& src)
555 {
556     return StringUtil::UnescapeJsonStringValue(src);
557 }
558 
GetSysVersion()559 std::string SysEvent::GetSysVersion()
560 {
561     return sysVersion_;
562 }
563 
GetPatchVersion()564 std::string SysEvent::GetPatchVersion()
565 {
566     return patchVersion_;
567 }
568 
SysEventCreator(const std::string & domain,const std::string & eventName,SysEventCreator::EventType type)569 SysEventCreator::SysEventCreator(const std::string& domain, const std::string& eventName,
570     SysEventCreator::EventType type)
571 {
572     builder_ = std::make_shared<EventRaw::RawDataBuilder>();
573     if (builder_ != nullptr) {
574         builder_->AppendDomain(domain).AppendName(eventName).AppendType(static_cast<int>(type)).
575             AppendTimeStamp(TimeUtil::GetMilliseconds()).AppendTimeZone(TimeUtil::GetTimeZone()).
576             AppendPid(getpid()).AppendTid(gettid()).AppendUid(getuid());
577     }
578 }
579 
GetRawData()580 std::shared_ptr<EventRaw::RawData> SysEventCreator::GetRawData()
581 {
582     if (builder_ == nullptr) {
583         return nullptr;
584     }
585     return builder_->Build();
586 }
587 
EscapeJsonStringValue(const std::string & src)588 std::string SysEventCreator::EscapeJsonStringValue(const std::string& src)
589 {
590     return StringUtil::EscapeJsonStringValue(src);
591 }
592 } // namespace HiviewDFX
593 } // namespace OHOS
594