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