• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)103 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler,
104     std::shared_ptr<EventRaw::RawData> rawData, int64_t seq, const std::string& sysVersion)
105     : PipelineEvent(sender, handler), eventType_(0), preserve_(true), log_(0),  seq_(seq)
106 {
107     messageType_ = Event::MessageType::SYS_EVENT;
108     if (rawData == nullptr || rawData->GetData() == nullptr ||
109         rawData->GetDataLength() < EventRaw::GetValidDataMinimumByteCount()) {
110         return;
111     }
112     sysVersion_ = sysVersion;
113     rawData_ = rawData;
114     totalCount_.fetch_add(1);
115     totalSize_.fetch_add(*(reinterpret_cast<int32_t*>(rawData_->GetData())));
116     InitialMembers();
117 }
118 
SysEvent(const std::string & sender,PipelineEventProducer * handler,std::shared_ptr<EventRaw::RawData> rawData,int64_t seq)119 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler,
120     std::shared_ptr<EventRaw::RawData> rawData, int64_t seq)
121     : SysEvent(sender, handler, rawData, seq, "")
122 {
123 }
124 
SysEvent(const std::string & sender,PipelineEventProducer * handler,std::shared_ptr<EventRaw::RawData> rawData)125 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler,
126     std::shared_ptr<EventRaw::RawData> rawData)
127     : SysEvent(sender, handler, rawData, 0)
128 {}
129 
SysEvent(const std::string & sender,PipelineEventProducer * handler,SysEventCreator & sysEventCreator)130 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, SysEventCreator& sysEventCreator)
131     : SysEvent(sender, handler, sysEventCreator.GetRawData())
132 {}
133 
SysEvent(const std::string & sender,PipelineEventProducer * handler,const std::string & jsonStr)134 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, const std::string& jsonStr)
135     : SysEvent(sender, handler, TansJsonStrToRawData(jsonStr))
136 {}
137 
~SysEvent()138 SysEvent::~SysEvent()
139 {
140     if (totalCount_ > 0) {
141         totalCount_.fetch_sub(1);
142     }
143     if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
144         totalSize_.fetch_sub(*(reinterpret_cast<int32_t*>(rawData_->GetData())));
145     }
146     if (totalSize_ < 0) {
147         totalSize_.store(0);
148     }
149 }
150 
InitialMembers()151 void SysEvent::InitialMembers()
152 {
153     HiSysEventHeader header = *(reinterpret_cast<struct HiSysEventHeader*>(rawData_->GetData() + BLOCK_SIZE_OFFSET));
154     domain_ = header.domain;
155     eventName_ = header.name;
156     eventType_ = static_cast<int32_t>(header.type) + 1;
157     happenTime_ = header.timestamp;
158     if (happenTime_ == 0) {
159         auto currentTimeStamp = TimeUtil::GetMilliseconds();
160         happenTime_ = currentTimeStamp;
161     }
162     tz_ = static_cast<int16_t>(header.timeZone);
163     pid_ = static_cast<int32_t>(header.pid);
164     tid_ = static_cast<int32_t>(header.tid);
165     uid_ = static_cast<int32_t>(header.uid);
166     log_ = header.log;
167 }
168 
InitBuilder()169 bool SysEvent::InitBuilder()
170 {
171     if (builder_ != nullptr) {
172         return true;
173     }
174     builder_ = std::make_shared<EventRaw::RawDataBuilder>(rawData_);
175     return builder_ != nullptr;
176 }
177 
TansJsonStrToRawData(const std::string & jsonStr)178 std::shared_ptr<EventRaw::RawData> SysEvent::TansJsonStrToRawData(const std::string& jsonStr)
179 {
180     auto parser = std::make_unique<EventRaw::RawDataBuilderJsonParser>(jsonStr);
181     if (parser == nullptr) {
182         return nullptr;
183     }
184     auto rawDataBuilder = parser->Parse();
185     if (rawDataBuilder == nullptr) {
186         return nullptr;
187     }
188     return rawDataBuilder->Build();
189 }
190 
SetTag(const std::string & tag)191 void SysEvent::SetTag(const std::string& tag)
192 {
193     tag_ = tag;
194 }
195 
GetTag() const196 std::string SysEvent::GetTag() const
197 {
198     return tag_;
199 }
200 
SetLevel(const std::string & level)201 void SysEvent::SetLevel(const std::string& level)
202 {
203     level_ = level;
204 }
205 
GetLevel() const206 std::string SysEvent::GetLevel() const
207 {
208     return level_;
209 }
210 
SetSeq(int64_t seq)211 void SysEvent::SetSeq(int64_t seq)
212 {
213     seq_ = seq;
214 }
215 
GetSeq() const216 int64_t SysEvent::GetSeq() const
217 {
218     return seq_;
219 }
220 
SetEventSeq(int64_t eventSeq)221 void SysEvent::SetEventSeq(int64_t eventSeq)
222 {
223     eventSeq_ = eventSeq;
224 }
225 
GetEventSeq() const226 int64_t SysEvent::GetEventSeq() const
227 {
228     return eventSeq_;
229 }
230 
GetPid() const231 int32_t SysEvent::GetPid() const
232 {
233     return pid_;
234 }
235 
GetTid() const236 int32_t SysEvent::GetTid() const
237 {
238     return tid_;
239 }
240 
GetUid() const241 int32_t SysEvent::GetUid() const
242 {
243     return uid_;
244 }
245 
GetTz() const246 int16_t SysEvent::GetTz() const
247 {
248     return tz_;
249 }
250 
GetEventType() const251 int SysEvent::GetEventType() const
252 {
253     return eventType_;
254 }
255 
SetId(uint64_t id)256 void SysEvent::SetId(uint64_t id)
257 {
258     if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
259         rawData_->Update(reinterpret_cast<uint8_t*>(&id), sizeof(uint64_t),
260             BLOCK_SIZE_OFFSET + EventRaw::POS_OF_ID_IN_HEADER);
261     }
262     if (builder_ != nullptr) {
263         builder_->AppendId(id);
264     }
265 }
266 
SetLog(uint8_t log)267 void SysEvent::SetLog(uint8_t log)
268 {
269     log_ = log;
270     if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
271         reinterpret_cast<struct HiSysEventHeader*>(
272             rawData_->GetData() + BLOCK_SIZE_OFFSET)->log = log;
273     }
274     if (builder_ != nullptr) {
275         builder_->AppendLog(log);
276     }
277 }
278 
SetPrivacy(uint8_t privacy)279 void SysEvent::SetPrivacy(uint8_t privacy)
280 {
281     privacy_ = privacy;
282 }
283 
GetPrivacy() const284 uint8_t SysEvent::GetPrivacy() const
285 {
286     return privacy_;
287 }
288 
GetEventValue(const std::string & key)289 std::string SysEvent::GetEventValue(const std::string& key)
290 {
291     if (!InitBuilder()) {
292         return "";
293     }
294     std::string dest;
295     builder_->ParseValueByKey(key, dest);
296     return dest;
297 }
298 
GetEventIntValue(const std::string & key)299 int64_t SysEvent::GetEventIntValue(const std::string& key)
300 {
301     if (!InitBuilder()) {
302         return DEFAULT_INT_VALUE;
303     }
304     if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest)) {
305         return intDest;
306     }
307     if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest) &&
308         (uIntDest <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))) {
309         return static_cast<int64_t>(uIntDest);
310     }
311     if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest) &&
312         (dDest >= static_cast<double>(std::numeric_limits<int64_t>::min())) &&
313         (dDest <= static_cast<double>(std::numeric_limits<int64_t>::max()))) {
314         return static_cast<int64_t>(dDest);
315     }
316     return DEFAULT_INT_VALUE;
317 }
318 
GetEventUintValue(const std::string & key)319 uint64_t SysEvent::GetEventUintValue(const std::string& key)
320 {
321     if (!InitBuilder()) {
322         return DEFAULT_UINT_VALUE;
323     }
324     if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest)) {
325         return uIntDest;
326     }
327     if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest) &&
328         (intDest >= DEFAULT_INT_VALUE)) {
329         return static_cast<uint64_t>(intDest);
330     }
331     if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest) &&
332         (dDest >= static_cast<double>(std::numeric_limits<uint64_t>::min())) &&
333         (dDest <= static_cast<double>(std::numeric_limits<uint64_t>::max()))) {
334         return static_cast<uint64_t>(dDest);
335     }
336     return DEFAULT_UINT_VALUE;
337 }
338 
GetEventDoubleValue(const std::string & key)339 double SysEvent::GetEventDoubleValue(const std::string& key)
340 {
341     if (!InitBuilder()) {
342         return DEFAULT_DOUBLE_VALUE;
343     }
344     if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest)) {
345         return dDest;
346     }
347     if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest)) {
348         return static_cast<double>(intDest);
349     }
350     if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest)) {
351         return static_cast<double>(uIntDest);
352     }
353     return DEFAULT_DOUBLE_VALUE;
354 }
355 
GetEventIntArrayValue(const std::string & key,std::vector<int64_t> & dest)356 bool SysEvent::GetEventIntArrayValue(const std::string& key, std::vector<int64_t>& dest)
357 {
358     dest.clear();
359     if (!InitBuilder()) {
360         return false;
361     }
362     auto intArrayItemHandler = [&dest] (int64_t& item) {
363         dest.emplace_back(item);
364         return true;
365     };
366     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
367         if (item <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
368             dest.emplace_back(static_cast<int64_t>(item));
369             return true;
370         }
371         return false;
372     };
373     auto dArrayItemHandler = [&dest] (double& item) {
374         if ((item >= static_cast<double>(std::numeric_limits<int64_t>::min())) &&
375             (item <= static_cast<double>(std::numeric_limits<int64_t>::max()))) {
376             dest.emplace_back(static_cast<int64_t>(item));
377             return true;
378         }
379         return false;
380     };
381     auto strArrayItemHandler = [&dest] (std::string& item) {
382         return false;
383     };
384     if (ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
385         ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
386         ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
387         ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
388         return true;
389     }
390     dest.clear();
391     return false;
392 }
393 
GetEventUintArrayValue(const std::string & key,std::vector<uint64_t> & dest)394 bool SysEvent::GetEventUintArrayValue(const std::string& key, std::vector<uint64_t>& dest)
395 {
396     dest.clear();
397     if (!InitBuilder()) {
398         return false;
399     }
400     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
401         dest.emplace_back(item);
402         return true;
403     };
404     auto intArrayItemHandler = [&dest] (int64_t& item) {
405         if (item >= DEFAULT_INT_VALUE) {
406             dest.emplace_back(static_cast<uint64_t>(item));
407             return true;
408         }
409         return false;
410     };
411     auto dArrayItemHandler = [&dest] (double& item) {
412         if ((item >= static_cast<double>(std::numeric_limits<uint64_t>::min())) &&
413             (item <= static_cast<double>(std::numeric_limits<uint64_t>::max()))) {
414             dest.emplace_back(static_cast<uint64_t>(item));
415             return true;
416         }
417         return false;
418     };
419     auto strArrayItemHandler = [&dest] (std::string& item) {
420         return false;
421     };
422     if (ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
423         ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
424         ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
425         ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
426         return true;
427     }
428     dest.clear();
429     return false;
430 }
431 
GetEventDoubleArrayValue(const std::string & key,std::vector<double> & dest)432 bool SysEvent::GetEventDoubleArrayValue(const std::string& key, std::vector<double>& dest)
433 {
434     dest.clear();
435     if (!InitBuilder()) {
436         return false;
437     }
438     auto dArrayItemHandler = [&dest] (double& item) {
439         dest.emplace_back(item);
440         return true;
441     };
442     auto intArrayItemHandler = [&dest] (int64_t& item) {
443         dest.emplace_back(static_cast<double>(item));
444         return true;
445     };
446     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
447         dest.emplace_back(static_cast<double>(item));
448         return true;
449     };
450     auto strArrayItemHandler = [&dest] (std::string& item) {
451         return false;
452     };
453     if (ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
454         ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
455         ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
456         ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
457         return true;
458     }
459     dest.clear();
460     return false;
461 }
462 
GetEventStringArrayValue(const std::string & key,std::vector<std::string> & dest)463 bool SysEvent::GetEventStringArrayValue(const std::string& key, std::vector<std::string>& dest)
464 {
465     dest.clear();
466     if (!InitBuilder()) {
467         return false;
468     }
469     auto strArrayItemHandler = [&dest] (std::string& item) {
470         dest.emplace_back(item);
471         return true;
472     };
473     auto dArrayItemHandler = [&dest] (double& item) {
474         return false;
475     };
476     auto intArrayItemHandler = [&dest] (int64_t& item) {
477         return false;
478     };
479     auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
480         return false;
481     };
482     if (ParseArrayValue<std::string>(builder_, key, strArrayItemHandler) ||
483         ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
484         ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
485         ParseArrayValue<double>(builder_, key, dArrayItemHandler)) {
486         return true;
487     }
488     dest.clear();
489     return false;
490 }
491 
TryToUpdateRawData()492 bool SysEvent::TryToUpdateRawData()
493 {
494     if (rawData_ == nullptr) {
495         return false;
496     }
497 
498     // raw data does not need to be re-initialized
499     if (!isUpdated_) {
500         return true;
501     }
502 
503     // raw data needs to be re-initialized
504     if (!InitBuilder()) {
505         return false;
506     }
507     builder_->AppendLog(log_);
508     rawData_ = builder_->Build();
509     if (rawData_ == nullptr) {
510         return false;
511     }
512     isUpdated_ = false;
513     return true;
514 }
515 
AsJsonStr()516 std::string SysEvent::AsJsonStr()
517 {
518     if (!TryToUpdateRawData()) {
519         return "";
520     }
521 
522     std::string jsonStr;
523     {
524         EventRaw::DecodedEvent event(rawData_->GetData());
525         jsonStr = event.AsJsonStr();
526     }
527     if (!tag_.empty()) {
528         AppendJsonValue(jsonStr, EventStore::EventCol::TAG, tag_);
529     }
530     if (!level_.empty()) {
531         AppendJsonValue(jsonStr, EventStore::EventCol::LEVEL, level_);
532     }
533     if (eventSeq_ >= 0) {
534         AppendJsonValue(jsonStr, EventStore::EventCol::SEQ, eventSeq_);
535     }
536     return jsonStr;
537 }
538 
AsRawData()539 uint8_t* SysEvent::AsRawData()
540 {
541     if (!TryToUpdateRawData()) {
542         return nullptr;
543     }
544     return rawData_->GetData();
545 }
546 
EscapeJsonStringValue(const std::string & src)547 std::string SysEvent::EscapeJsonStringValue(const std::string& src)
548 {
549     return StringUtil::EscapeJsonStringValue(src);
550 }
551 
UnescapeJsonStringValue(const std::string & src)552 std::string SysEvent::UnescapeJsonStringValue(const std::string& src)
553 {
554     return StringUtil::UnescapeJsonStringValue(src);
555 }
556 
GetSysVersion()557 std::string SysEvent::GetSysVersion()
558 {
559     return sysVersion_;
560 }
561 
SysEventCreator(const std::string & domain,const std::string & eventName,SysEventCreator::EventType type)562 SysEventCreator::SysEventCreator(const std::string& domain, const std::string& eventName,
563     SysEventCreator::EventType type)
564 {
565     builder_ = std::make_shared<EventRaw::RawDataBuilder>();
566     if (builder_ != nullptr) {
567         builder_->AppendDomain(domain).AppendName(eventName).AppendType(static_cast<int>(type)).
568             AppendTimeStamp(TimeUtil::GetMilliseconds()).AppendTimeZone(TimeUtil::GetTimeZone()).
569             AppendPid(getpid()).AppendTid(gettid()).AppendUid(getuid());
570     }
571 }
572 
GetRawData()573 std::shared_ptr<EventRaw::RawData> SysEventCreator::GetRawData()
574 {
575     if (builder_ == nullptr) {
576         return nullptr;
577     }
578     return builder_->Build();
579 }
580 
EscapeJsonStringValue(const std::string & src)581 std::string SysEventCreator::EscapeJsonStringValue(const std::string& src)
582 {
583     return StringUtil::EscapeJsonStringValue(src);
584 }
585 } // namespace HiviewDFX
586 } // namespace OHOS
587