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
16 #include "hisysevent.h"
17
18 #include <chrono>
19 #include <iomanip>
20 #include <sys/time.h>
21 #include <unistd.h>
22
23 #include "def.h"
24 #include "hilog/log.h"
25 #include "hitrace/trace.h"
26 #include "stringfilter.h"
27 #include "transport.h"
28
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace {
32 constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D08, "HISYSEVENT" };
33 }
34
35 WriteController HiSysEvent::controller;
36
GetMilliseconds()37 static inline uint64_t GetMilliseconds()
38 {
39 auto now = std::chrono::system_clock::now();
40 auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
41 return millisecs.count();
42 }
43
GetTimeZone()44 static std::string GetTimeZone()
45 {
46 struct timeval tv;
47 if (gettimeofday(&tv, nullptr) != 0) {
48 HiLog::Error(LABEL, "can not get tz");
49 return "";
50 }
51 time_t sysSec = tv.tv_sec;
52 struct tm tmLocal;
53 if (localtime_r(&sysSec, &tmLocal) == nullptr) {
54 HiLog::Error(LABEL, "failed to get local time.");
55 return "";
56 }
57 int timeZoneBufSize = 20;
58 char timeZone[timeZoneBufSize];
59 auto ret = strftime(timeZone, timeZoneBufSize, "%z", &tmLocal);
60 if (ret > 0) {
61 return std::string(timeZone);
62 }
63 return std::string("+0000");
64 }
65
CheckKey(const std::string & key)66 int HiSysEvent::CheckKey(const std::string &key)
67 {
68 if (!StringFilter::GetInstance().IsValidName(key, MAX_PARAM_NAME_LENGTH)) {
69 return ERR_KEY_NAME_INVALID;
70 }
71 return SUCCESS;
72 }
73
CheckValue(const std::string & value)74 int HiSysEvent::CheckValue(const std::string &value)
75 {
76 if (value.length() > MAX_STRING_LENGTH) {
77 return ERR_VALUE_LENGTH_TOO_LONG;
78 }
79 return SUCCESS;
80 }
81
CheckArraySize(unsigned long size)82 int HiSysEvent::CheckArraySize(unsigned long size)
83 {
84 if (size > MAX_ARRAY_SIZE) {
85 return ERR_ARRAY_TOO_MUCH;
86 }
87 return SUCCESS;
88 }
89
GetArrayMax()90 unsigned int HiSysEvent::GetArrayMax()
91 {
92 return MAX_ARRAY_SIZE;
93 }
94
ExplainRetCode(HiSysEvent::EventBase & eventBase)95 void HiSysEvent::ExplainRetCode(HiSysEvent::EventBase &eventBase)
96 {
97 if (eventBase.retCode_ > SUCCESS) {
98 HiLog::Warn(LABEL, "some value of param discard as invalid data, error=%{public}d, message=%{public}s",
99 eventBase.retCode_, ERR_MSG_LEVEL1[eventBase.retCode_ - 1]);
100 } else if (eventBase.retCode_ < SUCCESS) {
101 HiLog::Error(LABEL, "discard data, error=%{public}d, message=%{public}s",
102 eventBase.retCode_, ERR_MSG_LEVEL0[-eventBase.retCode_ - 1]);
103 }
104 }
105
IsError(HiSysEvent::EventBase & eventBase)106 bool HiSysEvent::IsError(HiSysEvent::EventBase &eventBase)
107 {
108 return (eventBase.retCode_ < SUCCESS);
109 }
110
IsErrorAndUpdate(int retCode,HiSysEvent::EventBase & eventBase)111 bool HiSysEvent::IsErrorAndUpdate(int retCode, HiSysEvent::EventBase &eventBase)
112 {
113 if (retCode < SUCCESS) {
114 eventBase.retCode_ = retCode;
115 return true;
116 }
117 return false;
118 }
119
IsWarnAndUpdate(int retCode,EventBase & eventBase)120 bool HiSysEvent::IsWarnAndUpdate(int retCode, EventBase &eventBase)
121 {
122 if (retCode != SUCCESS) {
123 eventBase.retCode_ = retCode;
124 return true;
125 }
126 return false;
127 }
128
UpdateAndCheckKeyNumIsOver(HiSysEvent::EventBase & eventBase)129 bool HiSysEvent::UpdateAndCheckKeyNumIsOver(HiSysEvent::EventBase &eventBase)
130 {
131 eventBase.keyCnt_++;
132 if (eventBase.keyCnt_ > MAX_PARAM_NUMBER) {
133 eventBase.retCode_ = ERR_KEY_NUMBER_TOO_MUCH;
134 return true;
135 }
136 return false;
137 }
138
AppendValue(HiSysEvent::EventBase & eventBase,const std::string & item)139 void HiSysEvent::AppendValue(HiSysEvent::EventBase &eventBase, const std::string &item)
140 {
141 std::string text = item;
142 if (item.length() > MAX_STRING_LENGTH) {
143 text = item.substr(0, MAX_STRING_LENGTH);
144 eventBase.retCode_ = ERR_VALUE_LENGTH_TOO_LONG;
145 }
146 eventBase.jsonStr_ << "\"" << StringFilter::GetInstance().EscapeToRaw(text) << "\"";
147 }
148
AppendValue(HiSysEvent::EventBase & eventBase,const char item)149 void HiSysEvent::AppendValue(HiSysEvent::EventBase &eventBase, const char item)
150 {
151 eventBase.jsonStr_ << static_cast<short>(item);
152 }
153
AppendValue(EventBase & eventBase,const signed char item)154 void HiSysEvent::AppendValue(EventBase &eventBase, const signed char item)
155 {
156 eventBase.jsonStr_ << static_cast<short>(item);
157 }
158
AppendValue(HiSysEvent::EventBase & eventBase,const unsigned char item)159 void HiSysEvent::AppendValue(HiSysEvent::EventBase &eventBase, const unsigned char item)
160 {
161 eventBase.jsonStr_ << static_cast<unsigned short>(item);
162 }
163
InnerWrite(HiSysEvent::EventBase & eventBase)164 void HiSysEvent::InnerWrite(HiSysEvent::EventBase &eventBase)
165 {
166 if (eventBase.jsonStr_.tellp() != 0) {
167 eventBase.jsonStr_.seekp(-1, std::ios_base::end);
168 }
169 }
170
InnerWrite(EventBase & eventBase,HiSysEventParam params[],size_t size)171 void HiSysEvent::InnerWrite(EventBase &eventBase, HiSysEventParam params[], size_t size)
172 {
173 if (params == nullptr || size == 0) {
174 InnerWrite(eventBase);
175 return;
176 }
177
178 for (size_t i = 0; i < size; ++i) {
179 AppendParam(eventBase, params[i]);
180 }
181 InnerWrite(eventBase);
182 }
183
SendSysEvent(HiSysEvent::EventBase & eventBase)184 void HiSysEvent::SendSysEvent(HiSysEvent::EventBase &eventBase)
185 {
186 int r = Transport::GetInstance().SendData(eventBase.jsonStr_.str());
187 if (r != SUCCESS) {
188 eventBase.retCode_ = r;
189 ExplainRetCode(eventBase);
190 }
191 }
192
AppendHexData(HiSysEvent::EventBase & eventBase,const std::string & key,uint64_t value)193 void HiSysEvent::AppendHexData(HiSysEvent::EventBase &eventBase, const std::string &key, uint64_t value)
194 {
195 eventBase.jsonStr_ << "\"" << key << "\":\"" << std::hex << value << "\"," << std::dec;
196 }
197
WritebaseInfo(HiSysEvent::EventBase & eventBase)198 void HiSysEvent::WritebaseInfo(HiSysEvent::EventBase &eventBase)
199 {
200 if (!StringFilter::GetInstance().IsValidName(eventBase.domain_, MAX_DOMAIN_LENGTH)) {
201 eventBase.retCode_ = ERR_DOMAIN_NAME_INVALID;
202 return;
203 }
204 if (!StringFilter::GetInstance().IsValidName(eventBase.eventName_, MAX_EVENT_NAME_LENGTH)) {
205 eventBase.retCode_ = ERR_EVENT_NAME_INVALID;
206 return;
207 }
208 AppendData(eventBase, "domain_", eventBase.domain_);
209 AppendData(eventBase, "name_", eventBase.eventName_);
210 AppendData(eventBase, "type_", eventBase.type_);
211 AppendData(eventBase, "time_", GetMilliseconds());
212 AppendData(eventBase, "tz_", GetTimeZone());
213 AppendData(eventBase, "pid_", getpid());
214 AppendData(eventBase, "tid_", gettid());
215 AppendData(eventBase, "uid_", getuid());
216 HiTraceId hitraceId = HiTraceChain::GetId();
217 if (!hitraceId.IsValid()) {
218 eventBase.keyCnt_ = 0;
219 return;
220 }
221 AppendHexData(eventBase, "traceid_", hitraceId.GetChainId());
222 AppendHexData(eventBase, "spanid_", hitraceId.GetSpanId());
223 AppendHexData(eventBase, "pspanid_", hitraceId.GetParentSpanId());
224 AppendData(eventBase, "trace_flag_", hitraceId.GetFlags());
225 eventBase.keyCnt_ = 0;
226 }
227
AppendInvalidParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)228 void HiSysEvent::AppendInvalidParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
229 {
230 eventBase.retCode_ = ERR_VALUE_INVALID;
231 }
232
AppendBoolParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)233 void HiSysEvent::AppendBoolParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
234 {
235 AppendData<bool>(eventBase, param.name, param.v.b);
236 }
237
AppendInt8Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)238 void HiSysEvent::AppendInt8Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
239 {
240 AppendData<int8_t>(eventBase, param.name, param.v.i8);
241 }
242
AppendUint8Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)243 void HiSysEvent::AppendUint8Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
244 {
245 AppendData<uint8_t>(eventBase, param.name, param.v.ui8);
246 }
247
AppendInt16Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)248 void HiSysEvent::AppendInt16Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
249 {
250 AppendData<int16_t>(eventBase, param.name, param.v.i16);
251 }
252
AppendUint16Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)253 void HiSysEvent::AppendUint16Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
254 {
255 AppendData<uint16_t>(eventBase, param.name, param.v.ui16);
256 }
257
AppendInt32Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)258 void HiSysEvent::AppendInt32Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
259 {
260 AppendData<int32_t>(eventBase, param.name, param.v.i32);
261 }
262
AppendUint32Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)263 void HiSysEvent::AppendUint32Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
264 {
265 AppendData<uint32_t>(eventBase, param.name, param.v.ui32);
266 }
267
AppendInt64Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)268 void HiSysEvent::AppendInt64Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
269 {
270 AppendData<int64_t>(eventBase, param.name, param.v.i64);
271 }
272
AppendUint64Param(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)273 void HiSysEvent::AppendUint64Param(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
274 {
275 AppendData<uint64_t>(eventBase, param.name, param.v.ui64);
276 }
277
AppendFloatParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)278 void HiSysEvent::AppendFloatParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
279 {
280 AppendData<float>(eventBase, param.name, param.v.f);
281 }
282
AppendDoubleParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)283 void HiSysEvent::AppendDoubleParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
284 {
285 AppendData<double>(eventBase, param.name, param.v.d);
286 }
287
AppendStringParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)288 void HiSysEvent::AppendStringParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
289 {
290 if (param.v.s == nullptr) {
291 eventBase.retCode_ = ERR_VALUE_INVALID;
292 return;
293 }
294 AppendData(eventBase, param.name, std::string(param.v.s));
295 }
296
297 template<typename T>
AppendArrayParam(HiSysEvent::EventBase & eventBase,const std::string & key,const T * array,size_t arraySize)298 void HiSysEvent::AppendArrayParam(HiSysEvent::EventBase &eventBase, const std::string &key,
299 const T *array, size_t arraySize)
300 {
301 if (array == nullptr) {
302 eventBase.retCode_ = ERR_VALUE_INVALID;
303 return;
304 }
305 std::vector<T> value(array, array + arraySize);
306 HiSysEvent::AppendArrayData<T>(eventBase, key, value);
307 }
308
AppendBoolArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)309 void HiSysEvent::AppendBoolArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
310 {
311 AppendArrayParam<bool>(eventBase, param.name, reinterpret_cast<bool*>(param.v.array), param.arraySize);
312 }
313
AppendInt8ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)314 void HiSysEvent::AppendInt8ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
315 {
316 AppendArrayParam<int8_t>(eventBase, param.name, reinterpret_cast<int8_t*>(param.v.array), param.arraySize);
317 }
318
AppendUint8ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)319 void HiSysEvent::AppendUint8ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
320 {
321 AppendArrayParam<uint8_t>(eventBase, param.name, reinterpret_cast<uint8_t*>(param.v.array), param.arraySize);
322 }
323
AppendInt16ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)324 void HiSysEvent::AppendInt16ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
325 {
326 AppendArrayParam<int16_t>(eventBase, param.name, reinterpret_cast<int16_t*>(param.v.array), param.arraySize);
327 }
328
AppendUint16ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)329 void HiSysEvent::AppendUint16ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
330 {
331 AppendArrayParam<uint16_t>(eventBase, param.name, reinterpret_cast<uint16_t*>(param.v.array), param.arraySize);
332 }
333
AppendInt32ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)334 void HiSysEvent::AppendInt32ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
335 {
336 AppendArrayParam<int32_t>(eventBase, param.name, reinterpret_cast<int32_t*>(param.v.array), param.arraySize);
337 }
338
AppendUint32ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)339 void HiSysEvent::AppendUint32ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
340 {
341 AppendArrayParam<uint32_t>(eventBase, param.name, reinterpret_cast<uint32_t*>(param.v.array), param.arraySize);
342 }
343
AppendInt64ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)344 void HiSysEvent::AppendInt64ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
345 {
346 AppendArrayParam<int64_t>(eventBase, param.name, reinterpret_cast<int64_t*>(param.v.array), param.arraySize);
347 }
348
AppendUint64ArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)349 void HiSysEvent::AppendUint64ArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
350 {
351 AppendArrayParam<uint64_t>(eventBase, param.name, reinterpret_cast<uint64_t*>(param.v.array), param.arraySize);
352 }
353
AppendFloatArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)354 void HiSysEvent::AppendFloatArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
355 {
356 AppendArrayParam<float>(eventBase, param.name, reinterpret_cast<float*>(param.v.array), param.arraySize);
357 }
358
AppendDoubleArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)359 void HiSysEvent::AppendDoubleArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
360 {
361 AppendArrayParam<double>(eventBase, param.name, reinterpret_cast<double*>(param.v.array), param.arraySize);
362 }
363
AppendStringArrayParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)364 void HiSysEvent::AppendStringArrayParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
365 {
366 auto array = reinterpret_cast<char**>(param.v.array);
367 if (array == nullptr) {
368 eventBase.retCode_ = ERR_VALUE_INVALID;
369 return;
370 }
371 for (size_t i = 0; i < param.arraySize; ++i) {
372 if (auto temp = array + i; *temp == nullptr) {
373 eventBase.retCode_ = ERR_VALUE_INVALID;
374 return;
375 }
376 }
377 std::vector<std::string> value(array, array + param.arraySize);
378 HiSysEvent::AppendArrayData<std::string>(eventBase, param.name, value);
379 }
380
AppendParam(HiSysEvent::EventBase & eventBase,const HiSysEventParam & param)381 void HiSysEvent::AppendParam(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m)
382 {
383 using AppendParamFunc = void (*)(HiSysEvent::EventBase &eventBase, const HiSysEventParam ¶m);
384 constexpr int totalAppendFuncSize = 25;
385 const AppendParamFunc appendFuncs[totalAppendFuncSize] = {
386 &HiSysEvent::AppendInvalidParam,
387 &HiSysEvent::AppendBoolParam,
388 &HiSysEvent::AppendInt8Param,
389 &HiSysEvent::AppendUint8Param,
390 &HiSysEvent::AppendInt16Param,
391 &HiSysEvent::AppendUint16Param,
392 &HiSysEvent::AppendInt32Param,
393 &HiSysEvent::AppendUint32Param,
394 &HiSysEvent::AppendInt64Param,
395 &HiSysEvent::AppendUint64Param,
396 &HiSysEvent::AppendFloatParam,
397 &HiSysEvent::AppendDoubleParam,
398 &HiSysEvent::AppendStringParam,
399 &HiSysEvent::AppendBoolArrayParam,
400 &HiSysEvent::AppendInt8ArrayParam,
401 &HiSysEvent::AppendUint8ArrayParam,
402 &HiSysEvent::AppendInt16ArrayParam,
403 &HiSysEvent::AppendUint16ArrayParam,
404 &HiSysEvent::AppendInt32ArrayParam,
405 &HiSysEvent::AppendUint32ArrayParam,
406 &HiSysEvent::AppendInt64ArrayParam,
407 &HiSysEvent::AppendUint64ArrayParam,
408 &HiSysEvent::AppendFloatArrayParam,
409 &HiSysEvent::AppendDoubleArrayParam,
410 &HiSysEvent::AppendStringArrayParam,
411 };
412 if (size_t paramType = param.t; paramType < totalAppendFuncSize) {
413 appendFuncs[paramType](eventBase, param);
414 } else {
415 eventBase.retCode_ = ERR_VALUE_INVALID;
416 }
417 }
418 } // namespace HiviewDFX
419 } // namespace OHOS
420
421