• 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 #define LOG_TAG "HiViewAdapter"
17 
18 #include "hiview_adapter.h"
19 #include <thread>
20 #include <unistd.h>
21 #include "log_print.h"
22 
23 namespace OHOS {
24 namespace DistributedDataDfx {
25 using namespace DistributedKv;
26 namespace {
27 // fault key
28 constexpr const char *FAULT_TYPE = "FAULT_TYPE";
29 constexpr const char *MODULE_NAME = "MODULE_NAME";
30 constexpr const char *INTERFACE_NAME = "INTERFACE_NAME";
31 constexpr const char *ERROR_TYPE = "ERROR_TYPE";
32 constexpr const char *SYNC_ERROR_INFO = "SYNC_ERROR_INFO";
33 // Database statistic
34 constexpr const char *USER_ID = "ANONYMOUS_UID";
35 constexpr const char *APP_ID = "APP_ID";
36 constexpr const char *STORE_ID = "STORE_ID";
37 constexpr const char *DB_SIZE = "DB_SIZE";
38 // interface visit statistic
39 constexpr const char *TIMES = "TIMES";
40 constexpr const char *DEVICE_ID = "ANONYMOUS_DID";
41 constexpr const char *SEND_SIZE = "SEND_SIZE";
42 constexpr const char *RECEIVED_SIZE = "RECEIVED_SIZE";
43 constexpr const char *AVERAGE_TIMES = "AVERAGE_TIME";
44 constexpr const char *WORST_TIMES = "WORST_TIME";
45 constexpr const char *INTERFACES = "INTERFACES";
46 constexpr const char *TAG = "TAG";
47 constexpr const char *POWERSTATS = "PowerStats";
48 // behaviour key
49 constexpr const char *BEHAVIOUR_INFO = "BEHAVIOUR_INFO";
50 constexpr const char *CHANNEL = "CHANNEL";
51 constexpr const char *DATA_SIZE = "DATA_SIZE";
52 constexpr const char *DATA_TYPE = "DATA_TYPE";
53 constexpr const char *OPERATION = "OPERATION";
54 constexpr const char *RESULT = "RESULT";
55 
56 const std::map<int, std::string> EVENT_COVERT_TABLE = {
57     { DfxCodeConstant::SERVICE_FAULT, "SERVICE_FAULT" },
58     { DfxCodeConstant::RUNTIME_FAULT, "RUNTIME_FAULT" },
59     { DfxCodeConstant::DATABASE_FAULT, "DATABASE_FAULT" },
60     { DfxCodeConstant::COMMUNICATION_FAULT, "COMMUNICATION_FAULT" },
61     { DfxCodeConstant::DATABASE_STATISTIC, "DATABASE_STATISTIC}" },
62     { DfxCodeConstant::VISIT_STATISTIC, "VISIT_STATISTIC" },
63     { DfxCodeConstant::TRAFFIC_STATISTIC, "VISIT_STATISTIC" },
64     { DfxCodeConstant::DATABASE_PERFORMANCE_STATISTIC, "DATABASE_PERFORMANCE_STATISTIC" },
65     { DfxCodeConstant::API_PERFORMANCE_STATISTIC, "API_PERFORMANCE_STATISTIC" },
66     { DfxCodeConstant::API_PERFORMANCE_INTERFACE, "API_PERFORMANCE_STATISTIC" },
67     { DfxCodeConstant::DATABASE_SYNC_FAILED, "DATABASE_SYNC_FAILED" },
68     { DfxCodeConstant::DATABASE_CORRUPTED_FAILED, "DATABASE_CORRUPTED_FAILED" },
69     { DfxCodeConstant::DATABASE_REKEY_FAILED, "DATABASE_REKEY_FAILED" },
70     { DfxCodeConstant::DATABASE_BEHAVIOUR, "DATABASE_BEHAVIOUR" },
71     { DfxCodeConstant::UDMF_DATA_BEHAVIOR, "UDMF_DATA_BEHAVIOR" },
72 };
73 }
74 using OHOS::HiviewDFX::HiSysEvent;
75 std::mutex HiViewAdapter::visitMutex_;
76 std::map<std::string, StatisticWrap<VisitStat>> HiViewAdapter::visitStat_;
77 
78 std::mutex HiViewAdapter::trafficMutex_;
79 std::map<std::string, StatisticWrap<TrafficStat>> HiViewAdapter::trafficStat_;
80 
81 std::mutex HiViewAdapter::dbMutex_;
82 std::map<std::string, StatisticWrap<DbStat>> HiViewAdapter::dbStat_;
83 
84 std::mutex HiViewAdapter::apiPerformanceMutex_;
85 std::map<std::string, StatisticWrap<ApiPerformanceStat>> HiViewAdapter::apiPerformanceStat_;
86 
87 bool HiViewAdapter::running_ = false;
88 std::mutex HiViewAdapter::runMutex_;
89 
ReportFault(int dfxCode,const FaultMsg & msg,std::shared_ptr<ExecutorPool> executors)90 void HiViewAdapter::ReportFault(int dfxCode, const FaultMsg &msg, std::shared_ptr<ExecutorPool> executors)
91 {
92     ExecutorPool::Task task([dfxCode, msg]() {
93         HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
94             CoverEventID(dfxCode),
95             HiSysEvent::EventType::FAULT,
96             FAULT_TYPE, static_cast<int>(msg.faultType),
97             MODULE_NAME, msg.moduleName,
98             INTERFACE_NAME, msg.interfaceName,
99             ERROR_TYPE, static_cast<int>(msg.errorType));
100     });
101     executors->Execute(std::move(task));
102 }
103 
ReportDBFault(int dfxCode,const DBFaultMsg & msg,std::shared_ptr<ExecutorPool> executors)104 void HiViewAdapter::ReportDBFault(int dfxCode, const DBFaultMsg &msg, std::shared_ptr<ExecutorPool> executors)
105 {
106     ExecutorPool::Task task([dfxCode, msg]() {
107         HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
108             CoverEventID(dfxCode),
109             HiSysEvent::EventType::FAULT,
110             APP_ID, msg.appId,
111             STORE_ID, msg.storeId,
112             MODULE_NAME, msg.moduleName,
113             ERROR_TYPE, static_cast<int>(msg.errorType));
114     });
115     executors->Execute(std::move(task));
116 }
117 
ReportCommFault(int dfxCode,const CommFaultMsg & msg,std::shared_ptr<ExecutorPool> executors)118 void HiViewAdapter::ReportCommFault(int dfxCode, const CommFaultMsg &msg, std::shared_ptr<ExecutorPool> executors)
119 {
120     ExecutorPool ::Task task([dfxCode, msg]() {
121         std::string message;
122         for (size_t i = 0; i < msg.deviceId.size(); i++) {
123             message.append("No: ").append(std::to_string(i))
124             .append(" sync to device: ").append(msg.deviceId[i])
125             .append(" has error, errCode:").append(std::to_string(msg.errorCode[i])).append(". ");
126         }
127         HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
128             CoverEventID(dfxCode),
129             HiSysEvent::EventType::FAULT,
130             USER_ID, msg.userId,
131             APP_ID, msg.appId,
132             STORE_ID, msg.storeId,
133             SYNC_ERROR_INFO, message);
134     });
135     executors->Execute(std::move(task));
136 }
137 
ReportBehaviour(int dfxCode,const BehaviourMsg & msg,std::shared_ptr<ExecutorPool> executors)138 void HiViewAdapter::ReportBehaviour(int dfxCode, const BehaviourMsg &msg, std::shared_ptr<ExecutorPool> executors)
139 {
140     ExecutorPool::Task task([dfxCode, msg]() {
141         std::string message;
142         message.append("Behaviour type : ").append(std::to_string(static_cast<int>(msg.behaviourType)))
143             .append(" behaviour info : ").append(msg.extensionInfo);
144         HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
145             CoverEventID(dfxCode),
146             HiSysEvent::EventType::BEHAVIOR,
147             USER_ID, msg.userId,
148             APP_ID, msg.appId,
149             STORE_ID, msg.storeId,
150             BEHAVIOUR_INFO, message);
151     });
152     executors->Execute(std::move(task));
153 }
154 
ReportDatabaseStatistic(int dfxCode,const DbStat & stat,std::shared_ptr<ExecutorPool> executors)155 void HiViewAdapter::ReportDatabaseStatistic(int dfxCode, const DbStat &stat, std::shared_ptr<ExecutorPool> executors)
156 {
157     ExecutorPool::Task task([dfxCode, stat]() {
158         std::lock_guard<std::mutex> lock(dbMutex_);
159         if (!dbStat_.count(stat.GetKey())) {
160             dbStat_.insert({stat.GetKey(), {stat, 0, dfxCode}});
161         }
162     });
163     executors->Execute(std::move(task));
164     StartTimerThread(executors);
165 }
166 
ReportDbSize(const StatisticWrap<DbStat> & stat)167 void HiViewAdapter::ReportDbSize(const StatisticWrap<DbStat> &stat)
168 {
169     uint64_t dbSize;
170     if (!stat.val.delegate->GetKvStoreDiskSize(stat.val.storeId, dbSize)) {
171         return;
172     }
173 
174     ValueHash vh;
175     std::string userId;
176     if (!vh.CalcValueHash(stat.val.userId, userId)) {
177         return;
178     }
179 
180     HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
181         CoverEventID(stat.code),
182         HiSysEvent::EventType::STATISTIC,
183         USER_ID, userId, APP_ID, stat.val.appId, STORE_ID, stat.val.storeId, DB_SIZE, dbSize);
184 }
185 
InvokeDbSize()186 void HiViewAdapter::InvokeDbSize()
187 {
188     std::lock_guard<std::mutex> lock(dbMutex_);
189     for (auto const &kv : dbStat_) {
190         if (kv.second.val.delegate == nullptr) {
191             continue;
192         }
193         // device coordinate for single version database
194         if (!kv.second.val.storeId.empty()) {
195             ReportDbSize(kv.second);
196             continue;
197         }
198         // below codes for multiple version database
199         std::vector<StoreInfo> storeInfos;
200         kv.second.val.delegate->GetKvStoreKeys(storeInfos);
201         if (storeInfos.empty()) {
202             continue;
203         }
204         for (auto const &storeInfo : storeInfos) {
205             ReportDbSize({{storeInfo.userId, storeInfo.appId, storeInfo.storeId, 0,
206                 kv.second.val.delegate}, 0, kv.second.code});
207         }
208     }
209     dbStat_.clear();
210 }
211 
ReportTrafficStatistic(int dfxCode,const TrafficStat & stat,std::shared_ptr<ExecutorPool> executors)212 void HiViewAdapter::ReportTrafficStatistic(int dfxCode, const TrafficStat &stat,
213     std::shared_ptr<ExecutorPool> executors)
214 {
215     ExecutorPool::Task task([dfxCode, stat]() {
216         std::lock_guard<std::mutex> lock(trafficMutex_);
217         auto it = trafficStat_.find(stat.GetKey());
218         if (it != trafficStat_.end()) {
219             it->second.val.receivedSize += stat.receivedSize;
220             it->second.val.sendSize += stat.sendSize;
221         } else {
222             trafficStat_.insert({stat.GetKey(), {stat, 0, dfxCode}});
223         }
224     });
225     executors->Execute(std::move(task));
226     StartTimerThread(executors);
227 }
228 
InvokeTraffic()229 void HiViewAdapter::InvokeTraffic()
230 {
231     std::lock_guard<std::mutex> lock(trafficMutex_);
232     ValueHash vh;
233     for (auto const &kv : trafficStat_) {
234         std::string deviceId;
235         if (!vh.CalcValueHash(kv.second.val.deviceId, deviceId)) {
236             continue;
237         }
238 
239         HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
240             CoverEventID(kv.second.code),
241             HiSysEvent::EventType::STATISTIC,
242             TAG, POWERSTATS,
243             APP_ID, kv.second.val.appId,
244             DEVICE_ID, deviceId,
245             SEND_SIZE, kv.second.val.sendSize,
246             RECEIVED_SIZE, kv.second.val.receivedSize);
247     }
248     trafficStat_.clear();
249 }
250 
ReportVisitStatistic(int dfxCode,const VisitStat & stat,std::shared_ptr<ExecutorPool> executors)251 void HiViewAdapter::ReportVisitStatistic(int dfxCode, const VisitStat &stat, std::shared_ptr<ExecutorPool> executors)
252 {
253     ExecutorPool::Task task([dfxCode, stat]() {
254         std::lock_guard<std::mutex> lock(visitMutex_);
255         auto it = visitStat_.find(stat.GetKey());
256         if (it == visitStat_.end()) {
257             visitStat_.insert({stat.GetKey(), {stat, 1, dfxCode}});
258         } else {
259             it->second.times++;
260         }
261     });
262     executors->Execute(std::move(task));
263     StartTimerThread(executors);
264 }
265 
InvokeVisit()266 void HiViewAdapter::InvokeVisit()
267 {
268     std::lock_guard<std::mutex> lock(visitMutex_);
269     for (auto const &kv : visitStat_) {
270         HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
271             CoverEventID(kv.second.code),
272             HiSysEvent::EventType::STATISTIC,
273             TAG, POWERSTATS,
274             APP_ID, kv.second.val.appId,
275             INTERFACE_NAME, kv.second.val.interfaceName,
276             TIMES, kv.second.times);
277     }
278     visitStat_.clear();
279 }
280 
ReportApiPerformanceStatistic(int dfxCode,const ApiPerformanceStat & stat,std::shared_ptr<ExecutorPool> executors)281 void HiViewAdapter::ReportApiPerformanceStatistic(int dfxCode, const ApiPerformanceStat &stat,
282     std::shared_ptr<ExecutorPool> executors)
283 {
284     ExecutorPool::Task task([dfxCode, stat]() {
285         std::lock_guard<std::mutex> lock(apiPerformanceMutex_);
286         auto it = apiPerformanceStat_.find(stat.GetKey());
287         if (it == apiPerformanceStat_.end()) {
288             apiPerformanceStat_.insert({stat.GetKey(), {stat, 1, dfxCode}}); // the init value of times is 1
289         } else {
290             it->second.times++;
291             it->second.val.costTime = stat.costTime;
292             if (it->second.times > 0) {
293                 it->second.val.averageTime =
294                     (it->second.val.averageTime * static_cast<uint64_t>(it->second.times - 1) + stat.costTime)
295                     / it->second.times;
296             }
297             if (stat.costTime > it->second.val.worstTime) {
298                 it->second.val.worstTime = stat.costTime;
299             }
300         }
301     });
302 
303     executors->Execute(std::move(task));
304     StartTimerThread(executors);
305 }
306 
ReportUdmfBehaviour(int dfxCode,const UdmfBehaviourMsg & msg,std::shared_ptr<ExecutorPool> executors)307 void HiViewAdapter::ReportUdmfBehaviour(
308     int dfxCode, const UdmfBehaviourMsg &msg, std::shared_ptr<ExecutorPool> executors)
309 {
310     if (executors == nullptr) {
311         ZLOGI("report udmf behavior failed");
312         return;
313     }
314     ExecutorPool::Task task([dfxCode, msg]() {
315         HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
316             CoverEventID(dfxCode),
317             HiSysEvent::EventType::BEHAVIOR,
318             APP_ID, msg.appId,
319             CHANNEL, msg.channel,
320             DATA_SIZE, msg.dataSize,
321             DATA_TYPE, msg.dataType,
322             OPERATION, msg.operation,
323             RESULT, msg.result);
324     });
325     executors->Execute(std::move(task));
326 }
327 
InvokeApiPerformance()328 void HiViewAdapter::InvokeApiPerformance()
329 {
330     std::string message;
331     message.append("[");
332     std::lock_guard<std::mutex> lock(apiPerformanceMutex_);
333     for (auto const &kv : apiPerformanceStat_) {
334         message.append("{\"CODE\":\"").append(std::to_string(kv.second.code)).append("\",")
335         .append("\"").append(INTERFACE_NAME).append("\":\"").append(kv.second.val.interfaceName).append("\",")
336         .append("\"").append(TIMES).append("\":").append(std::to_string(kv.second.times)).append(",")
337         .append("\"").append(AVERAGE_TIMES).append("\":").append(std::to_string(kv.second.val.averageTime)).append(",")
338         .append("\"").append(WORST_TIMES).append("\":").append(std::to_string(kv.second.val.worstTime)).append("}");
339     }
340     message.append("]");
341     HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR,
342         CoverEventID(DfxCodeConstant::API_PERFORMANCE_STATISTIC),
343         HiSysEvent::EventType::STATISTIC,
344         INTERFACES, message);
345     apiPerformanceStat_.clear();
346     ZLOGI("DdsTrace interface: clean");
347 }
348 
StartTimerThread(std::shared_ptr<ExecutorPool> executors)349 void HiViewAdapter::StartTimerThread(std::shared_ptr<ExecutorPool> executors)
350 {
351     if (running_) {
352         return;
353     }
354     std::lock_guard<std::mutex> lock(runMutex_);
355     if (running_) {
356         return;
357     }
358     running_ = true;
359     auto interval = std::chrono::seconds(WAIT_TIME);
360     auto fun = []() {
361         time_t current = time(nullptr);
362         tm localTime = { 0 };
363         tm *result = localtime_r(&current, &localTime);
364         if ((result != nullptr) && (localTime.tm_hour == DAILY_REPORT_TIME)) {
365             InvokeDbSize();
366             InvokeApiPerformance();
367         }
368         InvokeTraffic();
369         InvokeVisit();
370     };
371     executors->Schedule(fun, interval);
372 }
373 
CoverEventID(int dfxCode)374 std::string HiViewAdapter::CoverEventID(int dfxCode)
375 {
376     std::string sysEventID = "";
377     auto operatorIter = EVENT_COVERT_TABLE.find(dfxCode);
378     if (operatorIter != EVENT_COVERT_TABLE.end()) {
379         sysEventID = operatorIter->second;
380     }
381     return sysEventID;
382 }
383 } // namespace DistributedDataDfx
384 } // namespace OHOS
385