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