• 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 
16 #include "hisysevent.h"
17 
18 #include <chrono>
19 #include <iomanip>
20 #include <sstream>
21 #include <sys/time.h>
22 #include <unistd.h>
23 
24 #include "def.h"
25 #include "hilog/log.h"
26 #include "hitrace/hitraceid.h"
27 #include "hitrace/trace.h"
28 #include "stringfilter.h"
29 #include "transport.h"
30 
31 namespace OHOS {
32 namespace HiviewDFX {
33 namespace {
34 constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D08, "HISYSEVENT" };
35 constexpr int SECS_IN_MINUTE = 60;
36 constexpr int SECS_IN_HOUR = 3600;
37 }
38 
GetMilliseconds()39 static inline uint64_t GetMilliseconds()
40 {
41     auto now = std::chrono::system_clock::now();
42     auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
43     return millisecs.count();
44 }
45 
GetTimeZone()46 static std::string GetTimeZone()
47 {
48     struct timeval tv;
49     if (gettimeofday(&tv, NULL) != 0) {
50         HiLog::Error(LABEL, "can not get tz");
51         return "";
52     }
53     time_t sysSec = tv.tv_sec;
54     struct tm tmLocal;
55     if (localtime_r(&sysSec, &tmLocal) == nullptr) {
56         HiLog::Error(LABEL, "failed to get local time.");
57         return "";
58     }
59     struct tm tmUtc;
60     if (gmtime_r(&sysSec, &tmUtc) == nullptr) {
61         HiLog::Error(LABEL, "failed to get GMT time.");
62         return "";
63     }
64     time_t diffSec = mktime(&tmLocal) - mktime(&tmUtc);
65     int tzHour = std::abs(diffSec) / SECS_IN_HOUR;
66     if (tzHour > 12) { // max time zone is 12
67         HiLog::Error(LABEL, "failed to get hours for time zone, set to 0.");
68         tzHour = 0;
69     }
70     int tzMin = (std::abs(diffSec) % SECS_IN_HOUR) / SECS_IN_MINUTE;
71     std::stringstream ss;
72     ss << ((diffSec < 0) ? "-" : "+");
73     ss << std::setw(2) << std::setfill('0') << tzHour; // the number of digits in the hour is 2
74     ss << std::setw(2) << std::setfill('0') << tzMin; // the number of digits in the min is 2
75     return ss.str();
76 }
77 
CheckKey(const std::string & key)78 int HiSysEvent::CheckKey(const std::string &key)
79 {
80     if (!StringFilter::GetInstance().IsValidName(key, MAX_PARAM_NAME_LENGTH)) {
81         return ERR_KEY_NAME_INVALID;
82     }
83     return SUCCESS;
84 }
85 
CheckValue(const std::string & value)86 int HiSysEvent::CheckValue(const std::string &value)
87 {
88     if (value.length() > MAX_STRING_LENGTH) {
89         return ERR_VALUE_LENGTH_TOO_LONG;
90     }
91     return SUCCESS;
92 }
93 
CheckArraySize(unsigned long size)94 int HiSysEvent::CheckArraySize(unsigned long size)
95 {
96     if (size > MAX_ARRAY_SIZE) {
97         return ERR_ARRAY_TOO_MUCH;
98     }
99     return SUCCESS;
100 }
101 
GetArrayMax()102 unsigned int HiSysEvent::GetArrayMax()
103 {
104     return MAX_ARRAY_SIZE;
105 }
106 
ExplainRetCode(HiSysEvent::EventBase & eventBase)107 void HiSysEvent::ExplainRetCode(HiSysEvent::EventBase &eventBase)
108 {
109     if (eventBase.retCode_ > SUCCESS) {
110         HiLog::Warn(LABEL, "some value of param discard as invalid data, error=%{public}d, message=%{public}s",
111             eventBase.retCode_, ERR_MSG_LEVEL1[eventBase.retCode_ - 1]);
112     } else if (eventBase.retCode_ < SUCCESS) {
113         HiLog::Error(LABEL, "discard data, error=%{public}d, message=%{public}s",
114             eventBase.retCode_, ERR_MSG_LEVEL0[-eventBase.retCode_ - 1]);
115     }
116 }
117 
IsError(HiSysEvent::EventBase & eventBase)118 bool HiSysEvent::IsError(HiSysEvent::EventBase &eventBase)
119 {
120     if (eventBase.retCode_ < SUCCESS) {
121         return true;
122     }
123     return false;
124 }
125 
IsErrorAndUpdate(int retCode,HiSysEvent::EventBase & eventBase)126 bool HiSysEvent::IsErrorAndUpdate(int retCode, HiSysEvent::EventBase &eventBase)
127 {
128     if (retCode < SUCCESS) {
129         eventBase.retCode_ = retCode;
130         return true;
131     }
132     return false;
133 }
134 
IsWarnAndUpdate(int retCode,EventBase & eventBase)135 bool HiSysEvent::IsWarnAndUpdate(int retCode, EventBase &eventBase)
136 {
137     if (retCode != SUCCESS) {
138         eventBase.retCode_ = retCode;
139         return true;
140     }
141     return false;
142 }
143 
UpdateAndCheckKeyNumIsOver(HiSysEvent::EventBase & eventBase)144 bool HiSysEvent::UpdateAndCheckKeyNumIsOver(HiSysEvent::EventBase &eventBase)
145 {
146     eventBase.keyCnt_++;
147     if (eventBase.keyCnt_ > MAX_PARAM_NUMBER) {
148         eventBase.retCode_ = ERR_KEY_NUMBER_TOO_MUCH;
149         return true;
150     }
151     return false;
152 }
153 
AppendValue(HiSysEvent::EventBase & eventBase,const std::string & item)154 void HiSysEvent::AppendValue(HiSysEvent::EventBase &eventBase, const std::string &item)
155 {
156     std::string text = item;
157     if (item.length() > MAX_STRING_LENGTH) {
158         text = item.substr(0, MAX_STRING_LENGTH);
159         eventBase.retCode_ = ERR_VALUE_LENGTH_TOO_LONG;
160     }
161     eventBase.jsonStr_ << "\"" << StringFilter::GetInstance().EscapeToRaw(text) << "\"";
162 }
163 
AppendValue(HiSysEvent::EventBase & eventBase,const char item)164 void HiSysEvent::AppendValue(HiSysEvent::EventBase &eventBase, const char item)
165 {
166     eventBase.jsonStr_ << static_cast<short>(item);
167 }
168 
AppendValue(HiSysEvent::EventBase & eventBase,const unsigned char item)169 void HiSysEvent::AppendValue(HiSysEvent::EventBase &eventBase, const unsigned char item)
170 {
171     eventBase.jsonStr_ << static_cast<unsigned short>(item);
172 }
173 
InnerWrite(HiSysEvent::EventBase & eventBase)174 void HiSysEvent::InnerWrite(HiSysEvent::EventBase &eventBase)
175 {
176     if (eventBase.jsonStr_.tellp() != 0) {
177         eventBase.jsonStr_.seekp(-1, std::ios_base::end);
178     }
179 }
180 
SendSysEvent(HiSysEvent::EventBase & eventBase)181 void HiSysEvent::SendSysEvent(HiSysEvent::EventBase &eventBase)
182 {
183     int r = Transport::GetInstance().SendData(eventBase.jsonStr_.str());
184     if (r != SUCCESS) {
185         eventBase.retCode_ = r;
186         ExplainRetCode(eventBase);
187     }
188 }
189 
AppendHexData(HiSysEvent::EventBase & eventBase,const std::string & key,uint64_t value)190 void HiSysEvent::AppendHexData(HiSysEvent::EventBase &eventBase, const std::string &key, uint64_t value)
191 {
192     eventBase.jsonStr_ << "\"" << key << "\":\"" << std::hex << value << "\"," << std::dec;
193 }
194 
WritebaseInfo(HiSysEvent::EventBase & eventBase)195 void HiSysEvent::WritebaseInfo(HiSysEvent::EventBase &eventBase)
196 {
197     if (!StringFilter::GetInstance().IsValidName(eventBase.domain_, MAX_DOMAIN_LENGTH)) {
198         eventBase.retCode_ = ERR_DOMAIN_NAME_INVALID;
199         return;
200     }
201     if (!StringFilter::GetInstance().IsValidName(eventBase.eventName_, MAX_EVENT_NAME_LENGTH)) {
202         eventBase.retCode_ = ERR_EVENT_NAME_INVALID;
203         return;
204     }
205     AppendData(eventBase, "domain_", eventBase.domain_);
206     AppendData(eventBase, "name_", eventBase.eventName_);
207     AppendData(eventBase, "type_", eventBase.type_);
208     AppendData(eventBase, "time_", GetMilliseconds());
209     AppendData(eventBase, "tz_", GetTimeZone());
210     AppendData(eventBase, "pid_", getpid());
211     AppendData(eventBase, "tid_", gettid());
212     AppendData(eventBase, "uid_", getuid());
213     HiTraceId hitraceId = HiTrace::GetId();
214     if (!hitraceId.IsValid()) {
215         eventBase.keyCnt_ = 0;
216         return;
217     }
218     AppendHexData(eventBase, "traceid_", hitraceId.GetChainId());
219     AppendHexData(eventBase, "spanid_", hitraceId.GetSpanId());
220     AppendHexData(eventBase, "pspanid_", hitraceId.GetParentSpanId());
221     AppendData(eventBase, "trace_flag_", hitraceId.GetFlags());
222     eventBase.keyCnt_ = 0;
223 }
224 } // namespace HiviewDFX
225 } // namespace OHOS
226