1 /*
2 * Copyright (c) 2023 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 "inner_writer.h"
17
18 #include <cctype>
19 #include <chrono>
20 #include <iomanip>
21 #include <sys/time.h>
22 #include <unistd.h>
23
24 #include "def.h"
25 #include "hilog/log.h"
26 #include "hitrace/trace.h"
27 #include "transport.h"
28
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace {
32 constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D08, "HiSysEvent-InnerWriter" };
GetMilliseconds()33 inline uint64_t GetMilliseconds()
34 {
35 auto now = std::chrono::system_clock::now();
36 auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
37 return millisecs.count();
38 }
39
GetTimeZone()40 std::string GetTimeZone()
41 {
42 struct timeval tv;
43 if (gettimeofday(&tv, nullptr) != 0) {
44 HiLog::Error(LABEL, "can not get tz");
45 return "";
46 }
47 time_t sysSec = tv.tv_sec;
48 struct tm tmLocal;
49 if (localtime_r(&sysSec, &tmLocal) == nullptr) {
50 HiLog::Error(LABEL, "failed to get local time.");
51 return "";
52 }
53 int timeZoneBufSize = 20;
54 char timeZone[timeZoneBufSize];
55 auto ret = strftime(timeZone, timeZoneBufSize, "%z", &tmLocal);
56 if (ret > 0) {
57 return std::string(timeZone);
58 }
59 return std::string("+0000");
60 }
61 }
62
EventBase(const std::string & domain,const std::string & eventName,int type)63 InnerWriter::EventBase::EventBase(const std::string& domain, const std::string& eventName, int type)
64 {
65 retCode_ = 0;
66 builder_ = RawDataBuilder(domain, eventName, type);
67 }
68
GetEventBuilder()69 RawDataBuilder& InnerWriter::EventBase::GetEventBuilder()
70 {
71 return builder_;
72 }
73
GetRetCode()74 int InnerWriter::EventBase::GetRetCode()
75 {
76 return retCode_;
77 }
78
SetRetCode(int retCode)79 void InnerWriter::EventBase::SetRetCode(int retCode)
80 {
81 retCode_ = retCode;
82 }
83
GetParamCnt()84 size_t InnerWriter::EventBase::GetParamCnt()
85 {
86 return builder_.GetParamCnt();
87 }
88
GetEventRawData()89 std::shared_ptr<RawData> InnerWriter::EventBase::GetEventRawData()
90 {
91 return builder_.Build();
92 }
93
CheckKey(const std::string & key)94 int InnerWriter::CheckKey(const std::string& key)
95 {
96 if (!StringFilter::GetInstance().IsValidName(key, MAX_PARAM_NAME_LENGTH)) {
97 return ERR_KEY_NAME_INVALID;
98 }
99 return SUCCESS;
100 }
101
CheckValue(const std::string & value)102 int InnerWriter::CheckValue(const std::string& value)
103 {
104 if (value.length() > MAX_STRING_LENGTH) {
105 return ERR_VALUE_LENGTH_TOO_LONG;
106 }
107 return SUCCESS;
108 }
109
CheckArraySize(const size_t size)110 int InnerWriter::CheckArraySize(const size_t size)
111 {
112 if (size > MAX_ARRAY_SIZE) {
113 return ERR_ARRAY_TOO_MUCH;
114 }
115 return SUCCESS;
116 }
117
ExplainRetCode(EventBase & eventBase)118 void InnerWriter::ExplainRetCode(EventBase& eventBase)
119 {
120 auto retCode = eventBase.GetRetCode();
121 if (retCode > SUCCESS) {
122 HiLog::Warn(LABEL, "some value of param discard as invalid data, error=%{public}d, message=%{public}s",
123 retCode, ERR_MSG_LEVEL1[retCode - 1]);
124 } else if (retCode < SUCCESS) {
125 HiLog::Error(LABEL, "discard data, error=%{public}d, message=%{public}s",
126 retCode, ERR_MSG_LEVEL0[-retCode - 1]);
127 }
128 }
129
IsError(EventBase & eventBase)130 bool InnerWriter::IsError(EventBase& eventBase)
131 {
132 return (eventBase.GetRetCode() < SUCCESS);
133 }
134
IsErrorAndUpdate(int retCode,EventBase & eventBase)135 bool InnerWriter::IsErrorAndUpdate(int retCode, EventBase& eventBase)
136 {
137 if (retCode < SUCCESS) {
138 eventBase.SetRetCode(retCode);
139 return true;
140 }
141 return false;
142 }
143
IsWarnAndUpdate(int retCode,EventBase & eventBase)144 bool InnerWriter::IsWarnAndUpdate(int retCode, EventBase& eventBase)
145 {
146 if (retCode != SUCCESS) {
147 eventBase.SetRetCode(retCode);
148 return true;
149 }
150 return false;
151 }
152
UpdateAndCheckKeyNumIsOver(EventBase & eventBase)153 bool InnerWriter::UpdateAndCheckKeyNumIsOver(EventBase& eventBase)
154 {
155 if (eventBase.GetParamCnt() >= MAX_PARAM_NUMBER) {
156 eventBase.SetRetCode(ERR_KEY_NUMBER_TOO_MUCH);
157 return true;
158 }
159 return false;
160 }
161
SendSysEvent(EventBase & eventBase)162 void InnerWriter::SendSysEvent(EventBase& eventBase)
163 {
164 auto rawData = *(eventBase.GetEventRawData());
165 int r = Transport::GetInstance().SendData(rawData);
166 if (r != SUCCESS) {
167 eventBase.SetRetCode(r);
168 ExplainRetCode(eventBase);
169 }
170 }
171
AppendHexData(EventBase & eventBase,const std::string & key,uint64_t value)172 void InnerWriter::AppendHexData(EventBase& eventBase, const std::string& key, uint64_t value)
173 {
174 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedParam<uint64_t>>(key, value));
175 }
176
WritebaseInfo(EventBase & eventBase)177 void InnerWriter::WritebaseInfo(EventBase& eventBase)
178 {
179 if (!StringFilter::GetInstance().IsValidName(eventBase.GetEventBuilder().GetDomain(), MAX_DOMAIN_LENGTH)) {
180 eventBase.SetRetCode(ERR_DOMAIN_NAME_INVALID);
181 return;
182 }
183 if (!StringFilter::GetInstance().IsValidName(eventBase.GetEventBuilder().GetName(), MAX_EVENT_NAME_LENGTH)) {
184 eventBase.SetRetCode(ERR_EVENT_NAME_INVALID);
185 return;
186 }
187 eventBase.GetEventBuilder().AppendTimeStamp(GetMilliseconds()).AppendTimeZone(GetTimeZone())
188 .AppendPid(getpid()).AppendTid(gettid()).AppendUid(getuid());
189
190 HiTraceId hitraceId = HiTraceChain::GetId();
191 if (!hitraceId.IsValid()) {
192 return;
193 }
194 eventBase.GetEventBuilder().AppendTraceInfo(hitraceId.GetChainId(), hitraceId.GetSpanId(),
195 hitraceId.GetParentSpanId(), hitraceId.GetFlags());
196 }
197
AppendInvalidParam(EventBase & eventBase,const HiSysEventParam & param)198 void InnerWriter::AppendInvalidParam(EventBase& eventBase, const HiSysEventParam& param)
199 {
200 eventBase.SetRetCode(ERR_VALUE_INVALID);
201 }
202
AppendBoolParam(EventBase & eventBase,const HiSysEventParam & param)203 void InnerWriter::AppendBoolParam(EventBase& eventBase, const HiSysEventParam& param)
204 {
205 if (CheckParamValidity(eventBase, param.name)) {
206 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedParam<bool>>(param.name,
207 param.v.b));
208 }
209 }
210
AppendInt8Param(EventBase & eventBase,const HiSysEventParam & param)211 void InnerWriter::AppendInt8Param(EventBase& eventBase, const HiSysEventParam& param)
212 {
213 if (CheckParamValidity(eventBase, param.name)) {
214 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedParam<int8_t>>(param.name,
215 param.v.i8));
216 }
217 }
218
AppendUint8Param(EventBase & eventBase,const HiSysEventParam & param)219 void InnerWriter::AppendUint8Param(EventBase& eventBase, const HiSysEventParam& param)
220 {
221 if (CheckParamValidity(eventBase, param.name)) {
222 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedParam<uint8_t>>(param.name,
223 param.v.ui8));
224 }
225 }
226
AppendInt16Param(EventBase & eventBase,const HiSysEventParam & param)227 void InnerWriter::AppendInt16Param(EventBase& eventBase, const HiSysEventParam& param)
228 {
229 if (CheckParamValidity(eventBase, param.name)) {
230 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedParam<int16_t>>(param.name,
231 param.v.i16));
232 }
233 }
234
AppendUint16Param(EventBase & eventBase,const HiSysEventParam & param)235 void InnerWriter::AppendUint16Param(EventBase& eventBase, const HiSysEventParam& param)
236 {
237 if (CheckParamValidity(eventBase, param.name)) {
238 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedParam<uint16_t>>(param.name,
239 param.v.ui16));
240 }
241 }
242
AppendInt32Param(EventBase & eventBase,const HiSysEventParam & param)243 void InnerWriter::AppendInt32Param(EventBase& eventBase, const HiSysEventParam& param)
244 {
245 if (CheckParamValidity(eventBase, param.name)) {
246 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedParam<int32_t>>(param.name,
247 param.v.i32));
248 }
249 }
250
AppendUint32Param(EventBase & eventBase,const HiSysEventParam & param)251 void InnerWriter::AppendUint32Param(EventBase& eventBase, const HiSysEventParam& param)
252 {
253 if (CheckParamValidity(eventBase, param.name)) {
254 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedParam<uint32_t>>(param.name,
255 param.v.ui32));
256 }
257 }
258
AppendInt64Param(EventBase & eventBase,const HiSysEventParam & param)259 void InnerWriter::AppendInt64Param(EventBase& eventBase, const HiSysEventParam& param)
260 {
261 if (CheckParamValidity(eventBase, param.name)) {
262 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedParam<int64_t>>(param.name,
263 param.v.i64));
264 }
265 }
266
AppendUint64Param(EventBase & eventBase,const HiSysEventParam & param)267 void InnerWriter::AppendUint64Param(EventBase& eventBase, const HiSysEventParam& param)
268 {
269 if (CheckParamValidity(eventBase, param.name)) {
270 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedParam<uint64_t>>(param.name,
271 param.v.ui64));
272 }
273 }
274
AppendFloatParam(EventBase & eventBase,const HiSysEventParam & param)275 void InnerWriter::AppendFloatParam(EventBase& eventBase, const HiSysEventParam& param)
276 {
277 if (CheckParamValidity(eventBase, param.name)) {
278 eventBase.GetEventBuilder().AppendValue(std::make_shared<FloatingNumberEncodedParam<float>>(param.name,
279 param.v.f));
280 }
281 }
282
AppendDoubleParam(EventBase & eventBase,const HiSysEventParam & param)283 void InnerWriter::AppendDoubleParam(EventBase& eventBase, const HiSysEventParam& param)
284 {
285 if (CheckParamValidity(eventBase, param.name)) {
286 eventBase.GetEventBuilder().AppendValue(std::make_shared<FloatingNumberEncodedParam<double>>(param.name,
287 param.v.d));
288 }
289 }
290
AppendStringParam(EventBase & eventBase,const HiSysEventParam & param)291 void InnerWriter::AppendStringParam(EventBase& eventBase, const HiSysEventParam& param)
292 {
293 if (param.v.s == nullptr) {
294 eventBase.SetRetCode(ERR_VALUE_INVALID);
295 return;
296 }
297 if (CheckParamValidity(eventBase, param.name)) {
298 IsWarnAndUpdate(CheckValue(std::string(param.v.s)), eventBase);
299 auto rawStr = StringFilter::GetInstance().EscapeToRaw(std::string(param.v.s));
300 eventBase.GetEventBuilder().AppendValue(std::make_shared<StringEncodedParam>(param.name, rawStr));
301 }
302 }
303
AppendBoolArrayParam(EventBase & eventBase,const HiSysEventParam & param)304 void InnerWriter::AppendBoolArrayParam(EventBase& eventBase, const HiSysEventParam& param)
305 {
306 bool* array = reinterpret_cast<bool*>(param.v.array);
307 if (CheckArrayValidity(eventBase, array)) {
308 std::vector<bool> value(array, array + param.arraySize);
309 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
310 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedArrayParam<bool>>(
311 param.name, value));
312 }
313 }
314 }
315
AppendInt8ArrayParam(EventBase & eventBase,const HiSysEventParam & param)316 void InnerWriter::AppendInt8ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
317 {
318 int8_t* array = reinterpret_cast<int8_t*>(param.v.array);
319 if (CheckArrayValidity(eventBase, array)) {
320 std::vector<int8_t> value(array, array + param.arraySize);
321 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
322 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedArrayParam<int8_t>>(
323 param.name, value));
324 }
325 }
326 }
327
AppendUint8ArrayParam(EventBase & eventBase,const HiSysEventParam & param)328 void InnerWriter::AppendUint8ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
329 {
330 uint8_t* array = reinterpret_cast<uint8_t*>(param.v.array);
331 if (CheckArrayValidity(eventBase, array)) {
332 std::vector<uint8_t> value(array, array + param.arraySize);
333 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
334 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedArrayParam<uint8_t>>(
335 param.name, value));
336 }
337 }
338 }
339
AppendInt16ArrayParam(EventBase & eventBase,const HiSysEventParam & param)340 void InnerWriter::AppendInt16ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
341 {
342 int16_t* array = reinterpret_cast<int16_t*>(param.v.array);
343 if (CheckArrayValidity(eventBase, array)) {
344 std::vector<int16_t> value(array, array + param.arraySize);
345 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
346 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedArrayParam<int16_t>>(
347 param.name, value));
348 }
349 }
350 }
351
AppendUint16ArrayParam(EventBase & eventBase,const HiSysEventParam & param)352 void InnerWriter::AppendUint16ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
353 {
354 uint16_t* array = reinterpret_cast<uint16_t*>(param.v.array);
355 if (CheckArrayValidity(eventBase, array)) {
356 std::vector<uint16_t> value(array, array + param.arraySize);
357 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
358 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedArrayParam<uint16_t>>(
359 param.name, value));
360 }
361 }
362 }
363
AppendInt32ArrayParam(EventBase & eventBase,const HiSysEventParam & param)364 void InnerWriter::AppendInt32ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
365 {
366 int32_t* array = reinterpret_cast<int32_t*>(param.v.array);
367 if (CheckArrayValidity(eventBase, array)) {
368 std::vector<int32_t> value(array, array + param.arraySize);
369 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
370 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedArrayParam<int32_t>>(
371 param.name, value));
372 }
373 }
374 }
375
AppendUint32ArrayParam(EventBase & eventBase,const HiSysEventParam & param)376 void InnerWriter::AppendUint32ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
377 {
378 uint32_t* array = reinterpret_cast<uint32_t*>(param.v.array);
379 if (CheckArrayValidity(eventBase, array)) {
380 std::vector<uint32_t> value(array, array + param.arraySize);
381 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
382 eventBase.GetEventBuilder().AppendValue(std::make_shared<UnsignedVarintEncodedArrayParam<uint32_t>>(
383 param.name, value));
384 }
385 }
386 }
387
AppendInt64ArrayParam(EventBase & eventBase,const HiSysEventParam & param)388 void InnerWriter::AppendInt64ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
389 {
390 int64_t* array = reinterpret_cast<int64_t*>(param.v.array);
391 if (CheckArrayValidity(eventBase, array)) {
392 std::vector<int64_t> value(array, array + param.arraySize);
393 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
394 eventBase.GetEventBuilder().AppendValue(std::make_shared<SignedVarintEncodedArrayParam<int64_t>>(
395 param.name, value));
396 }
397 }
398 }
399
AppendUint64ArrayParam(EventBase & eventBase,const HiSysEventParam & param)400 void InnerWriter::AppendUint64ArrayParam(EventBase& eventBase, const HiSysEventParam& param)
401 {
402 uint64_t* array = reinterpret_cast<uint64_t*>(param.v.array);
403 if (CheckArrayValidity(eventBase, array)) {
404 std::vector<uint64_t> value(array, array + param.arraySize);
405 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
406 eventBase.GetEventBuilder().AppendValue(
407 std::make_shared<UnsignedVarintEncodedArrayParam<uint64_t>>(param.name, value));
408 }
409 }
410 }
411
AppendFloatArrayParam(EventBase & eventBase,const HiSysEventParam & param)412 void InnerWriter::AppendFloatArrayParam(EventBase& eventBase, const HiSysEventParam& param)
413 {
414 float* array = reinterpret_cast<float*>(param.v.array);
415 if (CheckArrayValidity(eventBase, array)) {
416 std::vector<float> value(array, array + param.arraySize);
417 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
418 eventBase.GetEventBuilder().AppendValue(std::make_shared<FloatingNumberEncodedArrayParam<float>>(
419 param.name, value));
420 }
421 }
422 }
423
AppendDoubleArrayParam(EventBase & eventBase,const HiSysEventParam & param)424 void InnerWriter::AppendDoubleArrayParam(EventBase& eventBase, const HiSysEventParam& param)
425 {
426 double* array = reinterpret_cast<double*>(param.v.array);
427 if (CheckArrayValidity(eventBase, array)) {
428 std::vector<double> value(array, array + param.arraySize);
429 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
430 eventBase.GetEventBuilder().AppendValue(std::make_shared<FloatingNumberEncodedArrayParam<double>>(
431 param.name, value));
432 }
433 }
434 }
435
AppendStringArrayParam(EventBase & eventBase,const HiSysEventParam & param)436 void InnerWriter::AppendStringArrayParam(EventBase& eventBase, const HiSysEventParam& param)
437 {
438 auto array = reinterpret_cast<char**>(param.v.array);
439 if (array == nullptr) {
440 eventBase.SetRetCode(ERR_VALUE_INVALID);
441 return;
442 }
443 for (size_t i = 0; i < param.arraySize; ++i) {
444 if (auto temp = array + i; *temp == nullptr) {
445 eventBase.SetRetCode(ERR_VALUE_INVALID);
446 return;
447 }
448 }
449 std::vector<std::string> value(array, array + param.arraySize);
450 if (CheckArrayParamsValidity(eventBase, param.name, value)) {
451 std::vector<std::string> rawStrs;
452 for (auto& item : value) {
453 IsWarnAndUpdate(CheckValue(item), eventBase);
454 rawStrs.emplace_back(StringFilter::GetInstance().EscapeToRaw(item));
455 }
456 eventBase.GetEventBuilder().AppendValue(std::make_shared<StringEncodedArrayParam>(param.name, rawStrs));
457 }
458 }
459
InnerWrite(EventBase & eventBase)460 void InnerWriter::InnerWrite(EventBase& eventBase)
461 {
462 // do nothing.
463 HiLog::Debug(LABEL, "hisysevent inner writer result: %{public}d.", eventBase.GetRetCode());
464 }
465
InnerWrite(EventBase & eventBase,const HiSysEventParam params[],size_t size)466 void InnerWriter::InnerWrite(EventBase& eventBase, const HiSysEventParam params[], size_t size)
467 {
468 if (params == nullptr || size == 0) {
469 return;
470 }
471 for (size_t i = 0; i < size; ++i) {
472 AppendParam(eventBase, params[i]);
473 }
474 }
475
AppendParam(EventBase & eventBase,const HiSysEventParam & param)476 void InnerWriter::AppendParam(EventBase& eventBase, const HiSysEventParam& param)
477 {
478 using AppendParamFunc = void (*)(EventBase&, const HiSysEventParam&);
479 constexpr int totalAppendFuncSize = 25;
480 const AppendParamFunc appendFuncs[totalAppendFuncSize] = {
481 &AppendInvalidParam, &AppendBoolParam, &AppendInt8Param, &AppendUint8Param,
482 &AppendInt16Param, &AppendUint16Param, &AppendInt32Param, &AppendUint32Param,
483 &AppendInt64Param, &AppendUint64Param, &AppendFloatParam, &AppendDoubleParam,
484 &AppendStringParam, &AppendBoolArrayParam, &AppendInt8ArrayParam, &AppendUint8ArrayParam,
485 &AppendInt16ArrayParam, &AppendUint16ArrayParam, &AppendInt32ArrayParam, &AppendUint32ArrayParam,
486 &AppendInt64ArrayParam, &AppendUint64ArrayParam, &AppendFloatArrayParam, &AppendDoubleArrayParam,
487 &AppendStringArrayParam,
488 };
489 if (size_t paramType = param.t; paramType < totalAppendFuncSize) {
490 appendFuncs[paramType](eventBase, param);
491 } else {
492 eventBase.SetRetCode(ERR_VALUE_INVALID);
493 }
494 }
495 } // namespace HiviewDFX
496 } // OHOS