• 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 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