• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "trace_decorator.h"
17 
18 #include "file_util.h"
19 #include "string_util.h"
20 #include "trace_utils.h"
21 #include "decorator_util.h"
22 
23 namespace OHOS {
24 namespace HiviewDFX {
25 namespace UCollectUtil {
26 constexpr char UC_HITRACE_API_STAT_TITLE[] = "Hitrace API detail statistics:";
27 constexpr char UC_HITRACE_API_STAT_ITEM[] =
28     "Caller FailCall OverCall TotalCall AvgLatency(us) MaxLatency(us) TotalTimeSpent(us)";
29 constexpr char UC_HITRACE_TRAFFIC_TITLE[] = "Hitrace Traffic statistics:";
30 constexpr char UC_HITRACE_TRAFFIC_ITEM[] =
31     "Caller TraceFile RawSize(b) ZipSize(b) HandleTime(us)";
32 constexpr char TRACE_TRAFFIC_LOG_PATH[] = "/data/log/hiview/unified_collection/ucollection_trace_traffic.log";
33 
34 TraceStatWrapper TraceDecorator::traceStatWrapper_;
35 
GetRawTraceSize(const std::string & file)36 uint64_t GetRawTraceSize(const std::string &file)
37 {
38     std::string originTracePath;
39     if (StringUtil::EndWith(file, ".zip")) {
40         std::string fileNameWithoutVersion = StringUtil::GetRleftSubstr(FileUtil::ExtractFileName(file), "@");
41         originTracePath = "/data/log/hitrace/" + fileNameWithoutVersion + ".sys";
42     } else {
43         std::string fileNameWithoutPrefix = StringUtil::GetRightSubstr(FileUtil::ExtractFileName(file), "_");
44         originTracePath = "/data/log/hitrace/" + fileNameWithoutPrefix;
45     }
46     std::string realPath;
47     if (!FileUtil::PathToRealPath(originTracePath, realPath)) {
48         return 0;
49     }
50     return FileUtil::GetFileSize(realPath);
51 }
52 
DumpTrace(UCollect::TraceCaller caller)53 CollectResult<std::vector<std::string>> TraceDecorator::DumpTrace(UCollect::TraceCaller caller)
54 {
55     auto task = [this, &caller] { return traceCollector_->DumpTrace(caller); };
56     return Invoke(task, caller);
57 }
58 
DumpTraceWithDuration(UCollect::TraceCaller caller,uint32_t timeLimit,uint64_t happenTime)59 CollectResult<std::vector<std::string>> TraceDecorator::DumpTraceWithDuration(UCollect::TraceCaller caller,
60     uint32_t timeLimit, uint64_t happenTime)
61 {
62     auto task = [this, &caller, &timeLimit, &happenTime] {
63         return traceCollector_->DumpTraceWithDuration(caller, timeLimit, happenTime);
64     };
65     return Invoke(task, caller);
66 }
67 
DumpTraceWithFilter(UCollect::TeleModule module,uint32_t timeLimit,uint64_t happenTime)68 CollectResult<std::vector<std::string>> TraceDecorator::DumpTraceWithFilter(UCollect::TeleModule module,
69     uint32_t timeLimit, uint64_t happenTime)
70 {
71     return traceCollector_->DumpTraceWithFilter(module, timeLimit, happenTime);
72 }
73 
FilterTraceOn(UCollect::TeleModule module,uint64_t postTime)74 CollectResult<int32_t> TraceDecorator::FilterTraceOn(UCollect::TeleModule module, uint64_t postTime)
75 {
76     return traceCollector_->FilterTraceOn(module, postTime);
77 }
78 
FilterTraceOff(UCollect::TeleModule module)79 CollectResult<int32_t> TraceDecorator::FilterTraceOff(UCollect::TeleModule module)
80 {
81     return traceCollector_->FilterTraceOff(module);
82 }
83 
RecoverTmpTrace()84 bool TraceDecorator::RecoverTmpTrace()
85 {
86     return traceCollector_->RecoverTmpTrace();
87 }
88 
SaveStatSpecialInfo()89 void TraceDecorator::SaveStatSpecialInfo()
90 {
91     WriteLinesToFile({""}, false, UC_STAT_LOG_PATH); // a blank line after common stat info
92     std::map<std::string, TraceStatInfo> traceStatInfo = traceStatWrapper_.GetTraceStatInfo();
93     std::list<std::string> traceFormattedStatInfo = {UC_HITRACE_API_STAT_TITLE, UC_HITRACE_API_STAT_ITEM};
94     for (const auto& record : traceStatInfo) {
95         traceFormattedStatInfo.push_back(record.second.ToString());
96     }
97     WriteLinesToFile(traceFormattedStatInfo, true, UC_STAT_LOG_PATH);
98 }
99 
ResetStatInfo()100 void TraceDecorator::ResetStatInfo()
101 {
102     traceStatWrapper_.ResetStatInfo();
103 }
104 
WriteTrafficAfterHandle(const TraceTrafficInfo & trace_traffic)105 void TraceDecorator::WriteTrafficAfterHandle(const TraceTrafficInfo& trace_traffic)
106 {
107     if (!Parameter::IsBetaVersion() && !Parameter::IsUCollectionSwitchOn()) {
108         return;
109     }
110     static std::mutex mtx;
111     std::lock_guard<std::mutex> lock(mtx);
112     traceStatWrapper_.WriteTrafficToLogFile(trace_traffic.ToString());
113 }
114 
UpdateTraceStatInfo(uint64_t startTime,uint64_t endTime,UCollect::TraceCaller & caller,const CollectResult<std::vector<std::string>> & result)115 void TraceStatWrapper::UpdateTraceStatInfo(uint64_t startTime, uint64_t endTime, UCollect::TraceCaller& caller,
116     const CollectResult<std::vector<std::string>>& result)
117 {
118     bool isCallSucc = (result.retCode == UCollect::UcError::SUCCESS);
119     bool isOverCall = (result.retCode == UCollect::UcError::TRACE_OVER_FLOW);
120     uint64_t latency = (endTime - startTime > 0) ? (endTime - startTime) : 0;
121     std::string callerStr = EnumToString(caller);
122     TraceStatItem item = {.caller = callerStr, .isCallSucc = isCallSucc,
123         .isOverCall = isOverCall, .latency = latency};
124     UpdateAPIStatInfo(item);
125 }
126 
UpdateAPIStatInfo(const TraceStatItem & item)127 void TraceStatWrapper::UpdateAPIStatInfo(const TraceStatItem& item)
128 {
129     std::lock_guard<std::mutex> lock(traceMutex_);
130     if (traceStatInfos_.find(item.caller) == traceStatInfos_.end()) {
131         TraceStatInfo statInfo = {
132             .caller = item.caller,
133             .failCall = (item.isCallSucc || item.isOverCall) ? 0 : 1,
134             .overCall = item.isOverCall ? 1 : 0,
135             .totalCall = 1,
136             .avgLatency = item.latency,
137             .maxLatency = item.latency,
138             .totalTimeSpend = item.latency,
139         };
140         traceStatInfos_.insert(std::make_pair(item.caller, statInfo));
141         return;
142     }
143 
144     TraceStatInfo& statInfo = traceStatInfos_[item.caller];
145     statInfo.totalCall += 1;
146     statInfo.failCall += ((item.isCallSucc || item.isOverCall) ? 0 : 1);
147     statInfo.overCall += (item.isOverCall ? 1 : 0);
148     statInfo.totalTimeSpend += item.latency;
149     if (statInfo.maxLatency < item.latency) {
150         statInfo.maxLatency = item.latency;
151     }
152     uint32_t succCall = statInfo.totalCall;
153     if (succCall > 0) {
154         statInfo.avgLatency = statInfo.totalTimeSpend / succCall;
155     }
156 }
157 
GetTraceStatInfo()158 std::map<std::string, TraceStatInfo> TraceStatWrapper::GetTraceStatInfo()
159 {
160     std::lock_guard<std::mutex> lock(traceMutex_);
161     return traceStatInfos_;
162 }
163 
WriteTrafficToLogFile(const std::string & trafficInfo)164 void TraceStatWrapper::WriteTrafficToLogFile(const std::string& trafficInfo)
165 {
166     std::list<std::string> trafficFormattedInfo;
167     if (date_ != GetCurrentDate() || !FileUtil::FileExists(TRACE_TRAFFIC_LOG_PATH)) {
168         WriteLinesToFile({""}, false, TRACE_TRAFFIC_LOG_PATH);
169         date_ = GetCurrentDate();
170         WriteLinesToFile({UC_STAT_DATE, date_}, true, TRACE_TRAFFIC_LOG_PATH);
171         trafficFormattedInfo = {UC_HITRACE_TRAFFIC_TITLE, UC_HITRACE_TRAFFIC_ITEM};
172     }
173     trafficFormattedInfo.push_back(trafficInfo);
174     WriteLinesToFile(trafficFormattedInfo, false, TRACE_TRAFFIC_LOG_PATH);
175 }
176 
ResetStatInfo()177 void TraceStatWrapper::ResetStatInfo()
178 {
179     std::lock_guard<std::mutex> lock(traceMutex_);
180     traceStatInfos_.clear();
181 }
182 } // namespace UCollectUtil
183 } // namespace HiviewDFX
184 } // namespace OHOS
185