• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "hiappevent_util.h"
16 
17 #include <cinttypes>
18 #include <utility>
19 
20 #include "app_event.h"
21 #include "app_event_processor_mgr.h"
22 #include "ffrt.h"
23 #include "hidebug_util.h"
24 #include "hilog/log.h"
25 
26 namespace OHOS {
27 namespace HiviewDFX {
28 
29 #undef LOG_DOMAIN
30 #define LOG_DOMAIN 0xD002D0A
31 #undef LOG_TAG
32 #define LOG_TAG "HIAPPEVENT_UTIL"
33 
34 int64_t ApiRecordReporter::processId_ = -1;
35 
InitProcessor()36 void ApiRecordReporter::InitProcessor()
37 {
38     using namespace HiAppEvent;
39     ReportConfig config;
40     config.name = "ha_app_event";
41     config.appId = "com_huawei_hmos_sdk_ocg";
42     config.routeInfo = "AUTO";
43     constexpr int triggerTimeOut = 90;
44     config.triggerCond.timeout = triggerTimeOut;
45     constexpr int triggerRow = 30;
46     config.triggerCond.row = triggerRow;
47     config.eventConfigs.clear();
48     config.eventConfigs.push_back({
49         .domain = "api_diagnostic",
50         .name = "api_exec_end",
51         .isRealTime = false,
52     });
53     config.eventConfigs.push_back({
54         .domain = "api_diagnostic",
55         .name = "api_called_stat",
56         .isRealTime = true,
57     });
58     config.eventConfigs.push_back({
59         .domain = "api_diagnostic",
60         .name = "api_called_stat_cnt",
61         .isRealTime = true,
62     });
63     processId_ = AppEventProcessorMgr::AddProcessor(config);
64     if (processId_ < 0) {
65         HILOG_ERROR(LOG_CORE, "failed to init processor and ret: %{public}" PRId64, processId_);
66     }
67 }
68 
GetInstance()69 SingleRecordReporter& SingleRecordReporter::GetInstance()
70 {
71     static SingleRecordReporter singleRecordReporter;
72     return singleRecordReporter;
73 }
74 
ReportRecord(const std::string & apiName,int errorCode,int64_t beginTime,int64_t endTime)75 void SingleRecordReporter::ReportRecord(const std::string& apiName, int errorCode, int64_t beginTime, int64_t endTime)
76 {
77     if (processId_ < 0) {
78         return;
79     }
80     auto task = [apiName, errorCode, beginTime, endTime] {
81         HiAppEvent::Event event("api_diagnostic", "api_exec_end", HiAppEvent::BEHAVIOR);
82         event.AddParam("trans_id", std::string("transId_") + std::to_string(beginTime));
83         event.AddParam("api_name", apiName);
84         event.AddParam("sdk_name", std::string("PerformanceAnalysisKit"));
85         event.AddParam("begin_time", beginTime);
86         event.AddParam("end_time", endTime);
87         event.AddParam("result", static_cast<int>(errorCode == 0));
88         event.AddParam("error_code", errorCode);
89         Write(event);
90     };
91     ffrt::submit(task, {}, {});
92 }
93 
MultipleRecordReporter(uint32_t timeout,uint32_t limitValue)94 MultipleRecordReporter::MultipleRecordReporter(uint32_t timeout, uint32_t limitValue) : timeout_(timeout),
95     limitValue_(limitValue) {}
96 
ReportRecord(const std::string & apiName,int errorCode,int64_t beginTime,int64_t endTime)97 void MultipleRecordReporter::ReportRecord(const std::string& apiName, int errorCode, int64_t beginTime, int64_t endTime)
98 {
99     if (processId_ < 0) {
100         return;
101     }
102     std::unique_lock<std::mutex> lock(mutex_);
103     records_.emplace_back(errorCode);
104     const int64_t costTime = endTime - beginTime;
105     maxCostTime_ = std::max(maxCostTime_, costTime);
106     minCostTime_ = std::min(minCostTime_, costTime);
107     totalCostTime_ += costTime;
108     constexpr int64_t secondToNanosecond = 1 * 1000 * 1000 * 1000;
109     if (records_.size() >= limitValue_ ||
110         lastReportTime_ + timeout_ * secondToNanosecond < GetElapsedNanoSecondsSinceBoot()) {
111         UploadRecordData(apiName);
112         lastReportTime_ = GetElapsedNanoSecondsSinceBoot();
113         records_.assign({});
114         minCostTime_ = std::numeric_limits<int64_t>::max();
115         maxCostTime_ = std::numeric_limits<int64_t>::min();
116         totalCostTime_ = 0;
117     }
118 }
119 
UploadRecordData(const std::string & apiName) const120 void MultipleRecordReporter::UploadRecordData(const std::string& apiName) const
121 {
122     auto maxCostTime = maxCostTime_;
123     auto minCostTime = minCostTime_;
124     auto totalCostTime = totalCostTime_;
125     auto task = [apiName, records = std::move(records_), maxCostTime, minCostTime, totalCostTime] {
126         HiAppEvent::Event event("api_diagnostic", "api_called_stat_cnt", HiAppEvent::BEHAVIOR);
127         event.AddParam("api_name", apiName);
128         event.AddParam("sdk_name", std::string("PerformanceAnalysisKit"));
129         event.AddParam("call_times", static_cast<int32_t>(records.size()));
130         event.AddParam("error_code_num", records);
131         int32_t successTime = 0;
132         for (const auto& errCode : records) {
133             if (errCode == 0) {
134                 successTime++;
135             }
136         }
137         event.AddParam("success_times", successTime);
138         event.AddParam("max_cost_time", maxCostTime);
139         event.AddParam("min_cost_time", minCostTime);
140         event.AddParam("total_cost_time", totalCostTime);
141         Write(event);
142     };
143     ffrt::submit(task, {}, {});
144 }
145 
ApiInvokeRecorder(std::string apiName,ApiRecordReporter & reporter)146 ApiInvokeRecorder::ApiInvokeRecorder(std::string apiName, ApiRecordReporter& reporter) : apiName_(std::move(apiName)),
147     beginTime_(GetElapsedNanoSecondsSinceBoot()), reporter_(reporter) {}
148 
~ApiInvokeRecorder()149 ApiInvokeRecorder::~ApiInvokeRecorder()
150 {
151     if (beginTime_ < 0) {
152         return;
153     }
154     const int64_t costTime = GetElapsedNanoSecondsSinceBoot() - beginTime_;
155     if (costTime < 0) {
156         return;
157     }
158     int64_t realEndTime = GetRealNanoSecondsTimestamp();
159     int64_t realBeginTime = realEndTime - costTime;
160     if (realBeginTime < 0 || realEndTime < 0) {
161         return;
162     }
163     constexpr int milliSecondsToNanoseconds = 1000 * 1000;
164     reporter_.ReportRecord(apiName_, errorCode_,
165         realBeginTime / milliSecondsToNanoseconds, realEndTime / milliSecondsToNanoseconds);
166 }
167 
SetErrorCode(int errorCode)168 void ApiInvokeRecorder::SetErrorCode(int errorCode)
169 {
170     errorCode_ = errorCode;
171 }
172 }
173 }