1 /*
2 * Copyright (c) 2023-2025 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 "trace_utils.h"
16
17 #include <algorithm>
18 #include <chrono>
19
20 #include "file_util.h"
21 #include "hiview_logger.h"
22 #include "parameter_ex.h"
23 #include "string_util.h"
24 #include "cpu_collector.h"
25 #include "ffrt.h"
26
27 using namespace std::chrono_literals;
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 DEFINE_LOG_TAG("UCollectUtil-TraceCollector");
32 const double CPU_LOAD_THRESHOLD = 0.03;
33 const uint32_t MAX_TRY_COUNT = 6;
34
35 const std::map<TraceErrorCode, UcError> CODE_MAP = {
36 {TraceErrorCode::SUCCESS, UcError::SUCCESS},
37 {TraceErrorCode::TRACE_NOT_SUPPORTED, UcError::UNSUPPORT},
38 {TraceErrorCode::TRACE_IS_OCCUPIED, UcError::TRACE_IS_OCCUPIED},
39 {TraceErrorCode::TAG_ERROR, UcError::TRACE_TAG_ERROR},
40 {TraceErrorCode::FILE_ERROR, UcError::TRACE_FILE_ERROR},
41 {TraceErrorCode::WRITE_TRACE_INFO_ERROR, UcError::TRACE_WRITE_ERROR},
42 {TraceErrorCode::WRONG_TRACE_MODE, UcError::TRACE_WRONG_MODE},
43 {TraceErrorCode::OUT_OF_TIME, UcError::TRACE_OUT_OF_TIME},
44 {TraceErrorCode::FORK_ERROR, UcError::TRACE_FORK_ERROR},
45 {TraceErrorCode::EPOLL_WAIT_ERROR, UcError::TRACE_EPOLL_WAIT_ERROR},
46 {TraceErrorCode::INVALID_MAX_DURATION, UcError::TRACE_INVALID_MAX_DURATION},
47 {TraceErrorCode::ASYNC_DUMP, UcError::ASYNC_DUMP},
48 {TraceErrorCode::TRACE_TASK_SUBMIT_ERROR, UcError::TRACE_TASK_SUBMIT_ERROR},
49 {TraceErrorCode::TRACE_TASK_DUMP_TIMEOUT, UcError::TRACE_TASK_DUMP_TIMEOUT},
50 };
51
52 const std::map<TraceStateCode, UcError> TRACE_STATE_MAP = {
53 {TraceStateCode::SUCCESS, UcError::SUCCESS},
54 {TraceStateCode::FAIL, UcError::TRACE_STATE_ERROR},
55 {TraceStateCode::DENY, UcError::TRACE_OPEN_ERROR},
56 {TraceStateCode::POLICY_ERROR, UcError::TRACE_POLICY_ERROR},
57 {TraceStateCode::UPDATE_TIME, UcError::SUCCESS},
58 {TraceStateCode::NO_TRIGGER, UcError::TRACE_TELEMERTY_NO_TRIGER},
59 };
60
61 const std::map<TraceFlowCode, UcError> TRACE_FLOW_MAP = {
62 {TraceFlowCode::TRACE_ALLOW, UcError::SUCCESS},
63 {TraceFlowCode::TRACE_DUMP_DENY, UcError::TRACE_DUMP_OVER_FLOW},
64 {TraceFlowCode::TRACE_UPLOAD_DENY, UcError::TRACE_OVER_FLOW},
65 {TraceFlowCode::TRACE_HAS_CAPTURED_TRACE, UcError::HAD_CAPTURED_TRACE}
66 };
67 }
68
TransCodeToUcError(TraceErrorCode ret)69 UcError TransCodeToUcError(TraceErrorCode ret)
70 {
71 if (CODE_MAP.find(ret) == CODE_MAP.end()) {
72 HIVIEW_LOGE("ErrorCode is not exists.");
73 return UcError::UNSUPPORT;
74 }
75 return CODE_MAP.at(ret);
76 }
77
TransStateToUcError(TraceStateCode ret)78 UcError TransStateToUcError(TraceStateCode ret)
79 {
80 if (TRACE_STATE_MAP.find(ret) == TRACE_STATE_MAP.end()) {
81 HIVIEW_LOGE("ErrorCode is not exists.");
82 return UcError::UNSUPPORT;
83 }
84 return TRACE_STATE_MAP.at(ret);
85 }
86
TransFlowToUcError(TraceFlowCode ret)87 UcError TransFlowToUcError(TraceFlowCode ret)
88 {
89 if (TRACE_FLOW_MAP.find(ret) == TRACE_FLOW_MAP.end()) {
90 HIVIEW_LOGE("ErrorCode is not exists.");
91 return UcError::UNSUPPORT;
92 }
93 return TRACE_FLOW_MAP.at(ret);
94 }
95
ModuleToString(UCollect::TeleModule module)96 const std::string ModuleToString(UCollect::TeleModule module)
97 {
98 switch (module) {
99 case UCollect::TeleModule::XPERF:
100 return CallerName::XPERF;
101 case UCollect::TeleModule::XPOWER:
102 return CallerName::XPOWER;
103 case UCollect::TeleModule::RELIABILITY:
104 return CallerName::RELIABILITY;
105 default:
106 return "UNKNOWN";
107 }
108 }
109
EnumToString(UCollect::TraceCaller caller)110 const std::string EnumToString(UCollect::TraceCaller caller)
111 {
112 switch (caller) {
113 case UCollect::TraceCaller::RELIABILITY:
114 return CallerName::RELIABILITY;
115 case UCollect::TraceCaller::XPERF:
116 return CallerName::XPERF;
117 case UCollect::TraceCaller::XPOWER:
118 return CallerName::XPOWER;
119 case UCollect::TraceCaller::HIVIEW:
120 return CallerName::HIVIEW;
121 case UCollect::TraceCaller::OTHER:
122 return CallerName::OTHER;
123 case UCollect::TraceCaller::SCREEN:
124 return CallerName::SCREEN;
125 default:
126 return "UNKNOWN";
127 }
128 }
129
ClientToString(UCollect::TraceClient client)130 const std::string ClientToString(UCollect::TraceClient client)
131 {
132 switch (client) {
133 case UCollect::TraceClient::COMMAND:
134 return ClientName::COMMAND;
135 case UCollect::TraceClient::COMMON_DEV:
136 return ClientName::COMMON_DEV;
137 case UCollect::TraceClient::BETACLUB:
138 return ClientName::BETACLUB;
139 default:
140 return "UNKNOWN";
141 }
142 }
143
GetUcError(TraceRet ret)144 UcError GetUcError(TraceRet ret)
145 {
146 if (ret.stateError_ != TraceStateCode::SUCCESS && ret.stateError_ != TraceStateCode::UPDATE_TIME) {
147 return TransStateToUcError(ret.stateError_);
148 }
149 if (ret.codeError_!= TraceErrorCode::SUCCESS) {
150 return TransCodeToUcError(ret.codeError_);
151 }
152 if (ret.flowError_ != TraceFlowCode::TRACE_ALLOW) {
153 return TransFlowToUcError(ret.flowError_);
154 }
155 return UcError::SUCCESS;
156 }
157
AddVersionInfoToZipName(const std::string & srcZipPath)158 std::string AddVersionInfoToZipName(const std::string &srcZipPath)
159 {
160 std::string displayVersion = Parameter::GetDisplayVersionStr();
161 std::string versionStr = StringUtil::ReplaceStr(StringUtil::ReplaceStr(displayVersion, "_", "-"), " ", "_");
162 return StringUtil::ReplaceStr(srcZipPath, ".zip", "@" + versionStr + ".zip");
163 }
164
CheckCurrentCpuLoad()165 void CheckCurrentCpuLoad()
166 {
167 std::shared_ptr<UCollectUtil::CpuCollector> collector = UCollectUtil::CpuCollector::Create();
168 int32_t pid = getpid();
169 auto collectResult = collector->CollectProcessCpuStatInfo(pid);
170 HIVIEW_LOGI("first get cpu load %{public}f", collectResult.data.cpuLoad);
171 uint32_t retryTime = 0;
172 while (collectResult.data.cpuLoad > CPU_LOAD_THRESHOLD && retryTime < MAX_TRY_COUNT) {
173 ffrt::this_task::sleep_for(5s);
174 collectResult = collector->CollectProcessCpuStatInfo(pid);
175 HIVIEW_LOGI("retry get cpu load %{public}f", collectResult.data.cpuLoad);
176 retryTime++;
177 }
178 }
179 } // HiViewDFX
180 } // OHOS
181