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