• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <regex>
19 #include <sstream>
20 #include <string>
21 #include <sys/time.h>
22 
23 #include "hilog/log.h"
24 #include "string_util.h"
25 #include "time_util.h"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
GetValueFromJson(const std::string & jsonStr,const std::string & expr,std::string & value)29 static int GetValueFromJson(const std::string& jsonStr, const std::string& expr, std::string& value)
30 {
31     std::smatch result;
32     const std::regex pattern(expr);
33     if (std::regex_search(jsonStr, result, pattern)) {
34         value = result.str(1);
35         return 0;
36     }
37     return -1;
38 }
39 
GetValueFromJson(const std::string & jsonStr,const std::string & expr,int16_t & value)40 static int GetValueFromJson(const std::string& jsonStr, const std::string& expr, int16_t& value)
41 {
42     std::smatch result;
43     const std::regex pattern(expr);
44     if (std::regex_search(jsonStr, result, pattern)) {
45         value = std::atoi(result.str(1).c_str());
46         return 0;
47     }
48     return -1;
49 }
50 
GetValueFromJson(const std::string & jsonStr,const std::string & expr,uint16_t & value)51 static int GetValueFromJson(const std::string& jsonStr, const std::string& expr, uint16_t& value)
52 {
53     std::smatch result;
54     const std::regex pattern(expr);
55     if (std::regex_search(jsonStr, result, pattern)) {
56         value = std::atoi(result.str(1).c_str());
57         return 0;
58     }
59     return -1;
60 }
61 
GetValueFromJson(const std::string & jsonStr,const std::string & expr,int32_t & value)62 static int GetValueFromJson(const std::string& jsonStr, const std::string& expr, int32_t& value)
63 {
64     std::smatch result;
65     const std::regex pattern(expr);
66     if (std::regex_search(jsonStr, result, pattern)) {
67         value = std::atoi(result.str(1).c_str());
68         return 0;
69     }
70     return -1;
71 }
72 
GetValueFromJson(const std::string & jsonStr,const std::string & expr,uint64_t & value)73 static int GetValueFromJson(const std::string& jsonStr, const std::string& expr, uint64_t& value)
74 {
75     std::smatch result;
76     const std::regex pattern(expr);
77     if (std::regex_search(jsonStr, result, pattern)) {
78         value = std::atoll(result.str(1).c_str());
79         return 0;
80     }
81     return -1;
82 }
83 
SysEvent(const std::string & sender,PipelineEventProducer * handler,const std::string & jsonStr)84 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, const std::string& jsonStr)
85     : PipelineEvent(sender, handler), seq_(0), pid_(0), tid_(0), uid_(0), tz_(0)
86 {
87     messageType_ = Event::MessageType::SYS_EVENT;
88     jsonExtraInfo_ = jsonStr;
89 }
90 
SysEvent(const std::string & sender,PipelineEventProducer * handler,SysEventCreator & sysEventCreator)91 SysEvent::SysEvent(const std::string& sender, PipelineEventProducer* handler, SysEventCreator& sysEventCreator)
92     : SysEvent(sender, handler, sysEventCreator.BuildSysEventJson())
93 {
94     PaserJson();
95 }
96 
~SysEvent()97 SysEvent::~SysEvent()
98 {
99 }
100 
PaserJson()101 int SysEvent::PaserJson()
102 {
103     if (jsonExtraInfo_.empty()) {
104         return -1;
105     }
106     GetValueFromJson(jsonExtraInfo_, R"~("domain_":"([_\w]+)")~", domain_);
107     GetValueFromJson(jsonExtraInfo_, R"~("name_":"([\w_]+)")~", eventName_);
108     GetValueFromJson(jsonExtraInfo_, R"~("type_":([\d]+))~", what_);
109     GetValueFromJson(jsonExtraInfo_, R"~("time_":([\d]+))~", happenTime_);
110     GetValueFromJson(jsonExtraInfo_, R"~("tz_":([\d]+))~", tz_);
111     GetValueFromJson(jsonExtraInfo_, R"~("pid_":([\d]+))~", pid_);
112     GetValueFromJson(jsonExtraInfo_, R"~("tid_":([\d]+))~", tid_);
113     GetValueFromJson(jsonExtraInfo_, R"~("uid_":([\d]+))~", uid_);
114     GetValueFromJson(jsonExtraInfo_, R"~("traceid_":"([\w]+)")~", traceId_);
115     GetValueFromJson(jsonExtraInfo_, R"~("spanid_":"([\w]+)")~", spanId_);
116     GetValueFromJson(jsonExtraInfo_, R"~("pspanid_":"([\w]+)")~", parentSpanId_);
117     GetValueFromJson(jsonExtraInfo_, R"~("trace_flag_":"([\w]+)")~", traceFlag_);
118     if (domain_.empty()) {
119         return -1;
120     }
121     if (eventName_.empty()) {
122         return -1;
123     }
124     if (what_ == 0) {
125         return -1;
126     }
127     if (happenTime_ == 0) {
128         return -1;
129     }
130     return 0;
131 }
132 
SetSeq(int64_t seq)133 void SysEvent::SetSeq(int64_t seq)
134 {
135     seq_ = seq;
136 }
137 
GetSeq() const138 int64_t SysEvent::GetSeq() const
139 {
140     return seq_;
141 }
142 
GetPid() const143 int32_t SysEvent::GetPid() const
144 {
145     return pid_;
146 }
147 
GetTid() const148 int32_t SysEvent::GetTid() const
149 {
150     return tid_;
151 }
152 
GetUid() const153 int32_t SysEvent::GetUid() const
154 {
155     return uid_;
156 }
157 
GetTz() const158 int16_t SysEvent::GetTz() const
159 {
160     return tz_;
161 }
162 
GetEventValue(const std::string & key)163 std::string SysEvent::GetEventValue(const std::string& key)
164 {
165     std::string value;
166     std::string regexStr = "\"" + key + "\":\"([.\\s\\S\\r\\n]*?)\"";
167     GetValueFromJson(jsonExtraInfo_, regexStr, value);
168     if (!value.empty() && !key.empty()) {
169         SetValue(key, value);
170     }
171     return value;
172 }
173 
GetEventIntValue(const std::string & key)174 uint64_t SysEvent::GetEventIntValue(const std::string& key)
175 {
176     uint64_t value = 0;
177     std::string regexStr = "\"" + key + "\":(\\d+)"; // "PID":PID
178     GetValueFromJson(jsonExtraInfo_, regexStr, value);
179     return value;
180 }
181 
SetEventValue(const std::string & key,int64_t value)182 void SysEvent::SetEventValue(const std::string& key, int64_t value)
183 {
184     std::smatch keyMatch;
185     std::string keyReplace = "\"" + key + "\":" + std::to_string(value);
186     std::regex keyReg("\"" + key + "\":([\\d]*?)");
187     if (std::regex_search(jsonExtraInfo_, keyMatch, keyReg)) {
188         jsonExtraInfo_ = std::regex_replace(jsonExtraInfo_, keyReg, keyReplace);
189         return;
190     }
191 
192     // new key here
193     std::regex newReg("\\{([.\\s\\S\\r\\n]*)\\}");
194     std::string newReplace = "{$1,\"" + key + "\":" + std::to_string(value) + "}";
195     if (std::regex_search(jsonExtraInfo_, keyMatch, newReg)) {
196         jsonExtraInfo_ = std::regex_replace(jsonExtraInfo_, newReg, newReplace);
197     }
198     else {
199         jsonExtraInfo_ = "{\"" + key + "\":" + std::to_string(value) + "}";
200     }
201     return;
202 }
203 
SetEventValue(const std::string & key,const std::string & value,bool append)204 void SysEvent::SetEventValue(const std::string& key, const std::string& value, bool append)
205 {
206     // fixme, $1 in value may cause error
207     std::smatch keyMatch;
208     std::string keyReplace;
209     if (append) {
210         keyReplace = "\"" + key + "\":\"" + value + ",$1\"";
211     }
212     else {
213         keyReplace = "\"" + key + "\":\"" + value + "\"";
214     }
215     std::regex keyReg("\"" + key + "\":\"([.\\s\\S\\r\\n]*?)\"");
216     if (std::regex_search(jsonExtraInfo_, keyMatch, keyReg)) {
217         jsonExtraInfo_ = std::regex_replace(jsonExtraInfo_, keyReg, keyReplace);
218         return;
219     }
220 
221     // new key here
222     std::regex newReg("\\{([.\\s\\S\\r\\n]*)\\}");
223     auto kvStr = "\"" + key + "\":\"" + value + "\"";
224     if (std::regex_search(jsonExtraInfo_, keyMatch, newReg)) {
225         auto pos = jsonExtraInfo_.find_last_of("}");
226         if (pos == std::string::npos) {
227             return;
228         }
229         jsonExtraInfo_.insert(pos, "," + kvStr);
230     } else {
231         jsonExtraInfo_ = "{" + kvStr + "}";
232     }
233     return;
234 }
235 
SysEventCreator(const std::string & domain,const std::string & eventName,SysEventCreator::EventType type)236 SysEventCreator::SysEventCreator(const std::string &domain, const std::string &eventName,
237     SysEventCreator::EventType type)
238 {
239     jsonStr_ << "{";
240     SetKeyValue("domain_", domain);
241     SetKeyValue("name_", eventName);
242     SetKeyValue("type_", static_cast<int>(type));
243     SetKeyValue("time_", TimeUtil::GetMilliseconds());
244     SetKeyValue("tz_", TimeUtil::GetTimeZone());
245     SetKeyValue("pid_", getpid());
246     SetKeyValue("tid_", gettid());
247     SetKeyValue("uid_", getuid());
248 }
249 
BuildSysEventJson()250 std::string SysEventCreator::BuildSysEventJson()
251 {
252     jsonStr_.seekp(-1, std::ios_base::end);
253     jsonStr_ << "}";
254     return jsonStr_.str();
255 }
256 
EscapeStringValue(const std::string & value)257 std::string SysEventCreator::EscapeStringValue(const std::string& value)
258 {
259     return StringUtil::EscapeJsonStringValue(value);
260 }
261 
EscapeStringValue(const char * value)262 std::string SysEventCreator::EscapeStringValue(const char* value)
263 {
264     return StringUtil::EscapeJsonStringValue(value);
265 }
266 
EscapeStringValue(char * value)267 std::string SysEventCreator::EscapeStringValue(char* value)
268 {
269     return StringUtil::EscapeJsonStringValue(value);
270 }
271 } // namespace HiviewDFX
272 } // namespace OHOS
273