1 /*
2  * Copyright (c) 2023-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 
16 #include "trace_collector_impl.h"
17 
18 #include <climits>
19 #include <memory>
20 #include <mutex>
21 
22 #include "hiview_logger.h"
23 #include "parameter_ex.h"
24 #include "trace_decorator.h"
25 #include "trace_flow_controller.h"
26 #include "trace_manager.h"
27 #include "trace_utils.h"
28 
29 using namespace OHOS::HiviewDFX;
30 using OHOS::HiviewDFX::TraceFlowController;
31 using namespace OHOS::HiviewDFX::Hitrace;
32 using namespace OHOS::HiviewDFX::UCollectUtil;
33 using namespace OHOS::HiviewDFX::UCollect;
34 
35 namespace OHOS {
36 namespace HiviewDFX {
37 namespace UCollectUtil {
38 namespace {
39 DEFINE_LOG_TAG("UCollectUtil-TraceCollector");
40 std::mutex g_dumpTraceMutex;
41 constexpr int32_t FULL_TRACE_DURATION = -1;
42 }
43 
Create()44 std::shared_ptr<TraceCollector> TraceCollector::Create()
45 {
46     return std::make_shared<TraceDecorator>(std::make_shared<TraceCollectorImpl>());
47 }
48 
DumpTraceWithDuration(UCollect::TraceCaller & caller,uint32_t timeLimit)49 CollectResult<std::vector<std::string>> TraceCollectorImpl::DumpTraceWithDuration(
50     UCollect::TraceCaller &caller, uint32_t timeLimit)
51 {
52     if (timeLimit > INT32_MAX) {
53         return StartDumpTrace(caller, INT32_MAX);
54     }
55     return StartDumpTrace(caller, static_cast<int32_t>(timeLimit));
56 }
57 
DumpTrace(UCollect::TraceCaller & caller)58 CollectResult<std::vector<std::string>> TraceCollectorImpl::DumpTrace(UCollect::TraceCaller &caller)
59 {
60     return StartDumpTrace(caller, FULL_TRACE_DURATION);
61 }
62 
StartDumpTrace(UCollect::TraceCaller & caller,int32_t timeLimit)63 CollectResult<std::vector<std::string>> TraceCollectorImpl::StartDumpTrace(UCollect::TraceCaller &caller,
64     int32_t timeLimit)
65 {
66     HIVIEW_LOGI("trace caller is %{public}s.", EnumToString(caller).c_str());
67     CollectResult<std::vector<std::string>> result;
68     if (!Parameter::IsBetaVersion() && !Parameter::IsUCollectionSwitchOn()) {
69         result.retCode = UcError::UNSUPPORT;
70         HIVIEW_LOGI("hitrace service not permitted to load on current version");
71         return result;
72     }
73     std::lock_guard<std::mutex> lock(g_dumpTraceMutex);
74     std::shared_ptr<TraceFlowController> controlPolicy = std::make_shared<TraceFlowController>(caller);
75     // check 1, judge whether need to dump
76     if (!controlPolicy->NeedDump()) {
77         result.retCode = UcError::TRACE_OVER_FLOW;
78         HIVIEW_LOGI("trace is over flow, can not dump.");
79         return result;
80     }
81 
82     TraceRetInfo traceRetInfo;
83     if (timeLimit == FULL_TRACE_DURATION) {
84         traceRetInfo = OHOS::HiviewDFX::Hitrace::DumpTrace();
85     } else {
86         traceRetInfo = OHOS::HiviewDFX::Hitrace::DumpTrace(timeLimit);
87     }
88     // check 2, judge whether to upload or not
89     if (!controlPolicy->NeedUpload(traceRetInfo)) {
90         result.retCode = UcError::TRACE_OVER_FLOW;
91         HIVIEW_LOGI("trace is over flow, can not upload.");
92         return result;
93     }
94     if (traceRetInfo.errorCode == TraceErrorCode::SUCCESS) {
95         if (caller == UCollect::TraceCaller::DEVELOP) {
96             result.data = traceRetInfo.outputFiles;
97         } else {
98             std::vector<std::string> outputFiles = GetUnifiedFiles(traceRetInfo, caller);
99             result.data = outputFiles;
100         }
101     }
102 
103     result.retCode = TransCodeToUcError(traceRetInfo.errorCode);
104     // step3: update db
105     controlPolicy->StoreDb();
106     HIVIEW_LOGI("DumpTrace, retCode = %{public}d, data.size = %{public}zu.", result.retCode, result.data.size());
107     return result;
108 }
109 
TraceOn()110 CollectResult<int32_t> TraceCollectorImpl::TraceOn()
111 {
112     CollectResult<int32_t> result;
113     TraceErrorCode ret = OHOS::HiviewDFX::Hitrace::DumpTraceOn();
114     result.retCode = TransCodeToUcError(ret);
115     HIVIEW_LOGI("TraceOn, ret = %{public}d.", result.retCode);
116     return result;
117 }
118 
TraceOff()119 CollectResult<std::vector<std::string>> TraceCollectorImpl::TraceOff()
120 {
121     CollectResult<std::vector<std::string>> result;
122     TraceRetInfo ret = OHOS::HiviewDFX::Hitrace::DumpTraceOff();
123     if (ret.errorCode == TraceErrorCode::SUCCESS) {
124         result.data = ret.outputFiles;
125     }
126     result.retCode = TransCodeToUcError(ret.errorCode);
127     HIVIEW_LOGI("TraceOff, ret = %{public}d, data.size = %{public}zu.", result.retCode, result.data.size());
128     return result;
129 }
130 } // UCollectUtil
131 } // HiViewDFX
132 } // OHOS
133