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 namespace {
48 constexpr int64_t DEFAULT_INT_VALUE = 0;
49 constexpr uint64_t DEFAULT_UINT_VALUE = 0;
50 constexpr double DEFAULT_DOUBLE_VALUE = 0.0;
51 template<typename T>
AppendJsonValue(std::string & eventJson,const std::string & key,T val)52 void AppendJsonValue(std::string& eventJson, const std::string& key, T val)
53 {
54 if (eventJson.empty()) {
55 return;
56 }
57 std::string findKey = "\"" + key + "\":";
58 if (eventJson.find(findKey) != std::string::npos) {
59 return;
60 }
61 std::string appendStr;
62 appendStr.append(",\"").append(key).append("\":");
63 if constexpr (std::is_same_v<std::decay_t<T>, std::string>) {
64 appendStr.append("\"").append(val).append("\"");
65 } else {
66 appendStr.append(std::to_string(val));
67 }
68 eventJson.insert(eventJson.size() - 1, appendStr); // 1 for '}'
69 }
70
71 template<typename T>
ParseArrayValue(std::shared_ptr<EventRaw::RawDataBuilder> builder,const std::string & key,std::function<bool (T &)> itemHandler)72 bool ParseArrayValue(std::shared_ptr<EventRaw::RawDataBuilder> builder, const std::string& key,
73 std::function<bool(T&)> itemHandler)
74 {
75 if (builder == nullptr) {
76 return false;
77 }
78 if (std::vector<T> arr; builder->ParseValueByKey(key, arr)) {
79 if (arr.empty()) {
80 return true;
81 }
82 return all_of(arr.begin(), arr.end(), [&itemHandler] (T& item) {
83 return itemHandler(item);
84 });
85 }
86 return false;
87 }
88 }
89 using EventRaw::UnsignedVarintEncodedParam;
90 using EventRaw::SignedVarintEncodedParam;
91 using EventRaw::FloatingNumberEncodedParam;
92 using EventRaw::StringEncodedParam;
93 using EventRaw::UnsignedVarintEncodedArrayParam;
94 using EventRaw::SignedVarintEncodedArrayParam;
95 using EventRaw::FloatingNumberEncodedArrayParam;
96 using EventRaw::StringEncodedArrayParam;
97 std::atomic<uint32_t> SysEvent::totalCount_(0);
98 std::atomic<int64_t> SysEvent::totalSize_(0);
99
SysEvent(const std::string & sender,PipelineEventProducer * handler,std::shared_ptr<EventRaw::RawData> rawData)100 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler,
101 std::shared_ptr<EventRaw::RawData> rawData)
102 : PipelineEvent(sender, handler), eventType_(0), preserve_(true), seq_(0), pid_(0),
103 tid_(0), uid_(0), tz_(0), eventSeq_(-1)
104 {
105 messageType_ = Event::MessageType::SYS_EVENT;
106 if (rawData == nullptr) {
107 return;
108 }
109 rawData_ = rawData;
110 builder_ = std::make_shared<EventRaw::RawDataBuilder>(rawData);
111 totalCount_.fetch_add(1);
112 if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
113 totalSize_.fetch_add(*(reinterpret_cast<int32_t*>(rawData_->GetData())));
114 }
115 InitialMembers();
116 }
117
SysEvent(const std::string & sender,PipelineEventProducer * handler,SysEventCreator & sysEventCreator)118 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, SysEventCreator& sysEventCreator)
119 : SysEvent(sender, handler, sysEventCreator.GetRawData())
120 {}
121
SysEvent(const std::string & sender,PipelineEventProducer * handler,const std::string & jsonStr)122 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, const std::string& jsonStr)
123 : SysEvent(sender, handler, TansJsonStrToRawData(jsonStr))
124 {}
125
~SysEvent()126 SysEvent::~SysEvent()
127 {
128 if (totalCount_ > 0) {
129 totalCount_.fetch_sub(1);
130 }
131 if (rawData_ != nullptr && rawData_->GetData() != nullptr) {
132 totalSize_.fetch_sub(*(reinterpret_cast<int32_t*>(rawData_->GetData())));
133 }
134 if (totalSize_ < 0) {
135 totalSize_.store(0);
136 }
137 }
138
InitialMembers()139 void SysEvent::InitialMembers()
140 {
141 if (builder_ == nullptr) {
142 return;
143 }
144 domain_ = builder_->GetDomain();
145 eventName_ = builder_->GetName();
146 auto header = builder_->GetHeader();
147 eventType_ = builder_->GetEventType();
148 what_ = static_cast<uint16_t>(eventType_);
149 happenTime_ = header.timestamp;
150 if (happenTime_ == 0) {
151 auto currentTimeStamp = OHOS::HiviewDFX::TimeUtil::GetMilliseconds();
152 builder_->AppendTimeStamp(currentTimeStamp);
153 happenTime_ = currentTimeStamp;
154 }
155 auto seqParam = builder_->GetValue("seq_");
156 if (seqParam != nullptr) {
157 seqParam->AsInt64(eventSeq_);
158 }
159 tz_ = static_cast<int16_t>(header.timeZone);
160 pid_ = static_cast<int32_t>(header.pid);
161 tid_ = static_cast<int32_t>(header.tid);
162 uid_ = static_cast<int32_t>(header.uid);
163 if (header.isTraceOpened == 1) {
164 auto traceInfo = builder_->GetTraceInfo();
165 traceId_ = StringUtil::ToString(traceInfo.traceId);
166 spanId_ = StringUtil::ToString(traceInfo.spanId);
167 parentSpanId_ = StringUtil::ToString(traceInfo.pSpanId);
168 traceFlag_ = StringUtil::ToString(traceInfo.traceFlag);
169 }
170 }
171
TansJsonStrToRawData(const std::string & jsonStr)172 std::shared_ptr<EventRaw::RawData> SysEvent::TansJsonStrToRawData(const std::string& jsonStr)
173 {
174 auto parser = std::make_unique<EventRaw::RawDataBuilderJsonParser>(jsonStr);
175 if (parser == nullptr) {
176 return nullptr;
177 }
178 auto rawDataBuilder = parser->Parse();
179 if (rawDataBuilder == nullptr) {
180 return nullptr;
181 }
182 return rawDataBuilder->Build();
183 }
184
SetTag(const std::string & tag)185 void SysEvent::SetTag(const std::string& tag)
186 {
187 tag_ = tag;
188 }
189
GetTag() const190 std::string SysEvent::GetTag() const
191 {
192 return tag_;
193 }
194
SetLevel(const std::string & level)195 void SysEvent::SetLevel(const std::string& level)
196 {
197 level_ = level;
198 }
199
GetLevel() const200 std::string SysEvent::GetLevel() const
201 {
202 return level_;
203 }
204
SetSeq(int64_t seq)205 void SysEvent::SetSeq(int64_t seq)
206 {
207 seq_ = seq;
208 }
209
GetSeq() const210 int64_t SysEvent::GetSeq() const
211 {
212 return seq_;
213 }
214
SetEventSeq(int64_t eventSeq)215 void SysEvent::SetEventSeq(int64_t eventSeq)
216 {
217 eventSeq_ = eventSeq;
218 }
219
GetEventSeq() const220 int64_t SysEvent::GetEventSeq() const
221 {
222 return eventSeq_;
223 }
224
GetPid() const225 int32_t SysEvent::GetPid() const
226 {
227 return pid_;
228 }
229
GetTid() const230 int32_t SysEvent::GetTid() const
231 {
232 return tid_;
233 }
234
GetUid() const235 int32_t SysEvent::GetUid() const
236 {
237 return uid_;
238 }
239
GetTz() const240 int16_t SysEvent::GetTz() const
241 {
242 return tz_;
243 }
244
GetEventValue(const std::string & key)245 std::string SysEvent::GetEventValue(const std::string& key)
246 {
247 std::string dest;
248 if (builder_ == nullptr) {
249 return dest;
250 }
251 builder_->ParseValueByKey(key, dest);
252 return dest;
253 }
254
GetEventIntValue(const std::string & key)255 int64_t SysEvent::GetEventIntValue(const std::string& key)
256 {
257 if (builder_ == nullptr) {
258 return DEFAULT_INT_VALUE;
259 }
260 if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest)) {
261 return intDest;
262 }
263 if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest) &&
264 (uIntDest <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))) {
265 return static_cast<int64_t>(uIntDest);
266 }
267 if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest) &&
268 (dDest >= static_cast<double>(std::numeric_limits<int64_t>::min())) &&
269 (dDest <= static_cast<double>(std::numeric_limits<int64_t>::max()))) {
270 return static_cast<int64_t>(dDest);
271 }
272 return DEFAULT_INT_VALUE;
273 }
274
GetEventUintValue(const std::string & key)275 uint64_t SysEvent::GetEventUintValue(const std::string& key)
276 {
277 if (builder_ == nullptr) {
278 return DEFAULT_UINT_VALUE;
279 }
280 if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest)) {
281 return uIntDest;
282 }
283 if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest) &&
284 (intDest >= DEFAULT_INT_VALUE)) {
285 return static_cast<uint64_t>(intDest);
286 }
287 if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest) &&
288 (dDest >= static_cast<double>(std::numeric_limits<uint64_t>::min())) &&
289 (dDest <= static_cast<double>(std::numeric_limits<uint64_t>::max()))) {
290 return static_cast<uint64_t>(dDest);
291 }
292 return DEFAULT_UINT_VALUE;
293 }
294
GetEventDoubleValue(const std::string & key)295 double SysEvent::GetEventDoubleValue(const std::string& key)
296 {
297 if (builder_ == nullptr) {
298 return DEFAULT_DOUBLE_VALUE;
299 }
300 if (double dDest = DEFAULT_DOUBLE_VALUE; builder_->ParseValueByKey(key, dDest)) {
301 return dDest;
302 }
303 if (int64_t intDest = DEFAULT_INT_VALUE; builder_->ParseValueByKey(key, intDest)) {
304 return static_cast<double>(intDest);
305 }
306 if (uint64_t uIntDest = DEFAULT_UINT_VALUE; builder_->ParseValueByKey(key, uIntDest)) {
307 return static_cast<double>(uIntDest);
308 }
309 return DEFAULT_DOUBLE_VALUE;
310 }
311
GetEventIntArrayValue(const std::string & key,std::vector<int64_t> & dest)312 bool SysEvent::GetEventIntArrayValue(const std::string& key, std::vector<int64_t>& dest)
313 {
314 dest.clear();
315 if (builder_ == nullptr) {
316 return false;
317 }
318 auto intArrayItemHandler = [&dest] (int64_t& item) {
319 dest.emplace_back(item);
320 return true;
321 };
322 auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
323 if (item <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
324 dest.emplace_back(static_cast<int64_t>(item));
325 return true;
326 }
327 return false;
328 };
329 auto dArrayItemHandler = [&dest] (double& item) {
330 if ((item >= static_cast<double>(std::numeric_limits<int64_t>::min())) &&
331 (item <= static_cast<double>(std::numeric_limits<int64_t>::max()))) {
332 dest.emplace_back(static_cast<int64_t>(item));
333 return true;
334 }
335 return false;
336 };
337 auto strArrayItemHandler = [&dest] (std::string& item) {
338 return false;
339 };
340 if (ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
341 ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
342 ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
343 ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
344 return true;
345 }
346 dest.clear();
347 return false;
348 }
349
GetEventUintArrayValue(const std::string & key,std::vector<uint64_t> & dest)350 bool SysEvent::GetEventUintArrayValue(const std::string& key, std::vector<uint64_t>& dest)
351 {
352 dest.clear();
353 if (builder_ == nullptr) {
354 return false;
355 }
356 auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
357 dest.emplace_back(item);
358 return true;
359 };
360 auto intArrayItemHandler = [&dest] (int64_t& item) {
361 if (item >= DEFAULT_INT_VALUE) {
362 dest.emplace_back(static_cast<uint64_t>(item));
363 return true;
364 }
365 return false;
366 };
367 auto dArrayItemHandler = [&dest] (double& item) {
368 if ((item >= static_cast<double>(std::numeric_limits<uint64_t>::min())) &&
369 (item <= static_cast<double>(std::numeric_limits<uint64_t>::max()))) {
370 dest.emplace_back(static_cast<uint64_t>(item));
371 return true;
372 }
373 return false;
374 };
375 auto strArrayItemHandler = [&dest] (std::string& item) {
376 return false;
377 };
378 if (ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
379 ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
380 ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
381 ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
382 return true;
383 }
384 dest.clear();
385 return false;
386 }
387
GetEventDoubleArrayValue(const std::string & key,std::vector<double> & dest)388 bool SysEvent::GetEventDoubleArrayValue(const std::string& key, std::vector<double>& dest)
389 {
390 dest.clear();
391 if (builder_ == nullptr) {
392 return false;
393 }
394 auto dArrayItemHandler = [&dest] (double& item) {
395 dest.emplace_back(item);
396 return true;
397 };
398 auto intArrayItemHandler = [&dest] (int64_t& item) {
399 dest.emplace_back(static_cast<double>(item));
400 return true;
401 };
402 auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
403 dest.emplace_back(static_cast<double>(item));
404 return true;
405 };
406 auto strArrayItemHandler = [&dest] (std::string& item) {
407 return false;
408 };
409 if (ParseArrayValue<double>(builder_, key, dArrayItemHandler) ||
410 ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
411 ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
412 ParseArrayValue<std::string>(builder_, key, strArrayItemHandler)) {
413 return true;
414 }
415 dest.clear();
416 return false;
417 }
418
GetEventStringArrayValue(const std::string & key,std::vector<std::string> & dest)419 bool SysEvent::GetEventStringArrayValue(const std::string& key, std::vector<std::string>& dest)
420 {
421 dest.clear();
422 if (builder_ == nullptr) {
423 return false;
424 }
425 auto strArrayItemHandler = [&dest] (std::string& item) {
426 dest.emplace_back(item);
427 return true;
428 };
429 auto dArrayItemHandler = [&dest] (double& item) {
430 return false;
431 };
432 auto intArrayItemHandler = [&dest] (int64_t& item) {
433 return false;
434 };
435 auto uIntArrayItemHandler = [&dest] (uint64_t& item) {
436 return false;
437 };
438 if (ParseArrayValue<std::string>(builder_, key, strArrayItemHandler) ||
439 ParseArrayValue<uint64_t>(builder_, key, uIntArrayItemHandler) ||
440 ParseArrayValue<int64_t>(builder_, key, intArrayItemHandler) ||
441 ParseArrayValue<double>(builder_, key, dArrayItemHandler)) {
442 return true;
443 }
444 dest.clear();
445 return false;
446 }
447
GetEventType()448 int SysEvent::GetEventType()
449 {
450 return eventType_;
451 }
452
AsJsonStr()453 std::string SysEvent::AsJsonStr()
454 {
455 if (builder_ == nullptr) {
456 return "";
457 }
458 rawData_ = builder_->Build(); // update
459 if (rawData_ == nullptr) {
460 return "";
461 }
462 EventRaw::DecodedEvent event(rawData_->GetData());
463
464 std::string jsonStr = event.AsJsonStr();
465 if (!tag_.empty()) {
466 AppendJsonValue(jsonStr, EventStore::EventCol::TAG, tag_);
467 }
468 if (!level_.empty()) {
469 AppendJsonValue(jsonStr, EventStore::EventCol::LEVEL, level_);
470 }
471 if (eventSeq_ >= 0) {
472 AppendJsonValue(jsonStr, EventStore::EventCol::SEQ, eventSeq_);
473 }
474 return jsonStr;
475 }
476
AsRawData()477 uint8_t* SysEvent::AsRawData()
478 {
479 if (builder_ == nullptr) {
480 return nullptr;
481 }
482 rawData_ = builder_->Build();
483 if (rawData_ == nullptr) {
484 return nullptr;
485 }
486 return rawData_->GetData();
487 }
488
EscapeJsonStringValue(const std::string & src)489 std::string SysEvent::EscapeJsonStringValue(const std::string& src)
490 {
491 return StringUtil::EscapeJsonStringValue(src);
492 }
493
UnescapeJsonStringValue(const std::string & src)494 std::string SysEvent::UnescapeJsonStringValue(const std::string& src)
495 {
496 return StringUtil::UnescapeJsonStringValue(src);
497 }
498
SysEventCreator(const std::string & domain,const std::string & eventName,SysEventCreator::EventType type)499 SysEventCreator::SysEventCreator(const std::string& domain, const std::string& eventName,
500 SysEventCreator::EventType type)
501 {
502 builder_ = std::make_shared<EventRaw::RawDataBuilder>();
503 if (builder_ != nullptr) {
504 builder_->AppendDomain(domain).AppendName(eventName).AppendType(static_cast<int>(type)).
505 AppendTimeStamp(TimeUtil::GetMilliseconds()).AppendTimeZone(TimeUtil::GetTimeZone()).
506 AppendPid(getpid()).AppendTid(gettid()).AppendUid(getuid());
507 }
508 }
509
GetRawData()510 std::shared_ptr<EventRaw::RawData> SysEventCreator::GetRawData()
511 {
512 if (builder_ == nullptr) {
513 return nullptr;
514 }
515 return builder_->Build();
516 }
517
EscapeJsonStringValue(const std::string & src)518 std::string SysEventCreator::EscapeJsonStringValue(const std::string& src)
519 {
520 return StringUtil::EscapeJsonStringValue(src);
521 }
522 } // namespace HiviewDFX
523 } // namespace OHOS
524