• 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     ffrt::submit([] {
39             using namespace HiAppEvent;
40             ReportConfig config;
41             config.name = "ha_app_event";
42             config.configName = "SDK_OCG";
43             processId_ = AppEventProcessorMgr::AddProcessor(config);
44             if (processId_ < 0) {
45                 HILOG_ERROR(LOG_CORE, "failed to init processor and ret: %{public}" PRId64, processId_);
46             }
47         }, {}, {});
48 }
49 
GetInstance()50 SingleRecordReporter& SingleRecordReporter::GetInstance()
51 {
52     static SingleRecordReporter singleRecordReporter;
53     return singleRecordReporter;
54 }
55 
ReportRecord(const std::string & apiName,int errorCode,int64_t beginTime,int64_t endTime)56 void SingleRecordReporter::ReportRecord(const std::string& apiName, int errorCode, int64_t beginTime, int64_t endTime)
57 {
58     if (processId_ < 0) {
59         return;
60     }
61     auto task = [apiName, errorCode, beginTime, endTime] {
62         HiAppEvent::Event event("api_diagnostic", "api_exec_end", HiAppEvent::BEHAVIOR);
63         event.AddParam("trans_id", std::string("transId_") + std::to_string(beginTime));
64         event.AddParam("api_name", apiName);
65         event.AddParam("sdk_name", std::string("PerformanceAnalysisKit"));
66         event.AddParam("begin_time", beginTime);
67         event.AddParam("end_time", endTime);
68         event.AddParam("result", errorCode ? 1 : 0);
69         event.AddParam("error_code", errorCode);
70         Write(event);
71     };
72     ffrt::submit(task, {}, {});
73 }
74 
MultipleRecordReporter(uint32_t timeout,uint32_t limitValue)75 MultipleRecordReporter::MultipleRecordReporter(uint32_t timeout, uint32_t limitValue) : timeout_(timeout),
76     limitValue_(limitValue) {}
77 
ReportRecord(const std::string & apiName,int errorCode,int64_t beginTime,int64_t endTime)78 void MultipleRecordReporter::ReportRecord(const std::string& apiName, int errorCode, int64_t beginTime, int64_t endTime)
79 {
80     if (processId_ < 0) {
81         return;
82     }
83     std::unique_lock<std::mutex> lock(mutex_);
84     records_.emplace_back(errorCode);
85     const int64_t costTime = endTime - beginTime;
86     maxCostTime_ = std::max(maxCostTime_, costTime);
87     minCostTime_ = std::min(minCostTime_, costTime);
88     totalCostTime_ += costTime;
89     constexpr int64_t secondToNanosecond = 1 * 1000 * 1000 * 1000;
90     if (records_.size() >= limitValue_ ||
91         lastReportTime_ + timeout_ * secondToNanosecond < GetElapsedNanoSecondsSinceBoot()) {
92         UploadRecordData(apiName);
93         lastReportTime_ = GetElapsedNanoSecondsSinceBoot();
94         records_.assign({});
95         minCostTime_ = std::numeric_limits<int64_t>::max();
96         maxCostTime_ = std::numeric_limits<int64_t>::min();
97         totalCostTime_ = 0;
98     }
99 }
100 
UploadRecordData(const std::string & apiName) const101 void MultipleRecordReporter::UploadRecordData(const std::string& apiName) const
102 {
103     auto maxCostTime = maxCostTime_;
104     auto minCostTime = minCostTime_;
105     auto totalCostTime = totalCostTime_;
106     auto task = [apiName, records = std::move(records_), maxCostTime, minCostTime, totalCostTime] {
107         HiAppEvent::Event event("api_diagnostic", "api_called_stat_cnt", HiAppEvent::BEHAVIOR);
108         event.AddParam("api_name", apiName);
109         event.AddParam("sdk_name", std::string("PerformanceAnalysisKit"));
110         event.AddParam("call_times", static_cast<int32_t>(records.size()));
111         event.AddParam("error_code_num", records);
112         int32_t successTime = 0;
113         for (const auto& errCode : records) {
114             if (errCode == 0) {
115                 successTime++;
116             }
117         }
118         event.AddParam("success_times", successTime);
119         event.AddParam("max_cost_time", maxCostTime);
120         event.AddParam("min_cost_time", minCostTime);
121         event.AddParam("total_cost_time", totalCostTime);
122         Write(event);
123     };
124     ffrt::submit(task, {}, {});
125 }
126 
ApiInvokeRecorder(std::string apiName,ApiRecordReporter & reporter)127 ApiInvokeRecorder::ApiInvokeRecorder(std::string apiName, ApiRecordReporter& reporter) : apiName_(std::move(apiName)),
128     beginTime_(GetElapsedNanoSecondsSinceBoot()), reporter_(reporter) {}
129 
~ApiInvokeRecorder()130 ApiInvokeRecorder::~ApiInvokeRecorder()
131 {
132     if (beginTime_ < 0) {
133         return;
134     }
135     const int64_t costTime = GetElapsedNanoSecondsSinceBoot() - beginTime_;
136     if (costTime < 0) {
137         return;
138     }
139     int64_t realEndTime = GetRealNanoSecondsTimestamp();
140     int64_t realBeginTime = realEndTime - costTime;
141     if (realBeginTime < 0 || realEndTime < 0) {
142         return;
143     }
144     constexpr int milliSecondsToNanoseconds = 1000 * 1000;
145     reporter_.ReportRecord(apiName_, errorCode_,
146         realBeginTime / milliSecondsToNanoseconds, realEndTime / milliSecondsToNanoseconds);
147 }
148 
SetErrorCode(int errorCode)149 void ApiInvokeRecorder::SetErrorCode(int errorCode)
150 {
151     errorCode_ = errorCode;
152 }
153 }
154 }