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 #include "unified_collector.h"
16 
17 #include <memory>
18 
19 #include "app_caller_event.h"
20 #include "app_trace_context.h"
21 #include "collect_event.h"
22 #include "event_publish.h"
23 #include "ffrt.h"
24 #include "file_util.h"
25 #include "hitrace_dump.h"
26 #include "hiview_logger.h"
27 #include "io_collector.h"
28 #include "parameter_ex.h"
29 #include "plugin_factory.h"
30 #include "process_status.h"
31 #include "sys_event.h"
32 #include "time_util.h"
33 #include "trace_flow_controller.h"
34 #include "trace_manager.h"
35 #include "uc_observer_mgr.h"
36 #include "unified_collection_stat.h"
37 
38 namespace OHOS {
39 namespace HiviewDFX {
40 REGISTER(UnifiedCollector);
41 DEFINE_LOG_TAG("HiView-UnifiedCollector");
42 using namespace OHOS::HiviewDFX::UCollectUtil;
43 using namespace std::literals::chrono_literals;
44 using namespace OHOS::HiviewDFX::Hitrace;
45 namespace {
46 std::mutex g_traceLock;
47 const std::string HIPERF_LOG_PATH = "/data/log/hiperf";
48 const std::string COLLECTION_IO_PATH = "/data/log/hiview/unified_collection/io/";
49 const std::string UNIFIED_SPECIAL_PATH = "/data/log/hiview/unified_collection/trace/special/";
50 const std::string DEVELOPER_MODE_TRACE_ARGS = "tags:sched, freq, disk, sync, binder, mmc, membus, load, pagecache, \
51     workq, ipa, hdf, virse, net, dsched, graphic, multimodalinput, dinput, ark, ace, window, zaudio, daudio, zmedia, \
52     dcamera, zcamera, dhfwk, app, gresource, ability, power, samgr, ffrt clockType:boot1 bufferSize:1024 overwrite:0 \
53     fileLimit:20 fileSize:102400";
54 const std::string OTHER = "Other";
55 const std::string HIVIEW_UCOLLECTION_STATE_TRUE = "true";
56 const std::string HIVIEW_UCOLLECTION_STATE_FALSE = "false";
57 const std::string DEVELOP_TRACE_RECORDER_TRUE = "true";
58 const std::string DEVELOP_TRACE_RECORDER_FALSE = "false";
59 const std::string HIVIEW_UCOLLECTION_TEST_APP_TRACE_STATE_TRUE = "true";
60 
61 const int8_t STATE_COUNT = 2;
62 const int8_t COML_STATE = 0;
63 // [coml:0][is remote log][is trace recorder]
64 // [beta:1][is remote log][is trace recorder]
65 const bool DYNAMIC_TRACE_FSM[STATE_COUNT][STATE_COUNT][STATE_COUNT] = {
66     {{true,  false}, {false, false}},
67     {{false, false}, {false, false}},
68 };
69 
70 // [dev mode:0][test app trace state]
71 // [dev mode:1][test app trace state]
72 const bool CHECK_DYNAMIC_TRACE_FSM[STATE_COUNT][STATE_COUNT] = {
73     {true, true}, {false, true}
74 };
75 
76 #if PC_APP_STATE_COLLECT_ENABLE
77 const std::string RSS_APP_STATE_EVENT = "APP_CGROUP_CHANGE";
78 const int NAP_BACKGROUND_GROUP = 11;
79 
GetProcessStateByGroup(SysEvent & sysEvent)80 ProcessState GetProcessStateByGroup(SysEvent& sysEvent)
81 {
82     if (sysEvent.GetEventName() != RSS_APP_STATE_EVENT) {
83         return INVALID;
84     }
85     int32_t procGroup = sysEvent.GetEventIntValue("PROCESS_NEWGROUP");
86     if (procGroup == NAP_BACKGROUND_GROUP) {
87         return BACKGROUND;
88     }
89     // else - The app is in the foreground group
90     return FOREGROUND;
91 }
92 #endif // PC_APP_STATE_COLLECT_ENABLE
93 
OnTestAppTraceStateChanged(const char * key,const char * value,void * context)94 void OnTestAppTraceStateChanged(const char* key, const char* value, void* context)
95 {
96     if (key == nullptr || value == nullptr) {
97         return;
98     }
99 
100     if (!(std::string(HIVIEW_UCOLLECTION_TEST_APP_TRACE_STATE) == key)) {
101         return;
102     }
103 
104     bool isBetaVersion = Parameter::IsBetaVersion();
105     bool isUCollectionSwitchOn = Parameter::IsUCollectionSwitchOn();
106     bool isTraceCollectionSwitchOn = Parameter::IsTraceCollectionSwitchOn();
107 
108     bool isDeveloperMode = Parameter::IsDeveloperMode();
109     bool isTraceStateActive = std::string(HIVIEW_UCOLLECTION_TEST_APP_TRACE_STATE_TRUE) == value;
110     AppCallerEvent::enableDynamicTrace_ = CHECK_DYNAMIC_TRACE_FSM[isDeveloperMode][isTraceStateActive] &&
111         DYNAMIC_TRACE_FSM[isBetaVersion][isUCollectionSwitchOn][isTraceCollectionSwitchOn];
112     HIVIEW_LOGI("dynamic trace change to:%{public}d as test trace state", AppCallerEvent::enableDynamicTrace_);
113 }
114 
InitDynamicTrace()115 void InitDynamicTrace()
116 {
117     bool isBetaVersion = Parameter::IsBetaVersion();
118     bool isUCollectionSwitchOn = Parameter::IsUCollectionSwitchOn();
119     bool isTraceCollectionSwitchOn = Parameter::IsTraceCollectionSwitchOn();
120     HIVIEW_LOGI("IsBetaVersion=%{public}d, IsUCollectionSwitchOn=%{public}d, IsTraceCollectionSwitchOn=%{public}d",
121         isBetaVersion, isUCollectionSwitchOn, isTraceCollectionSwitchOn);
122 
123     bool isDeveloperMode = Parameter::IsDeveloperMode();
124     bool isTestAppTraceOn = Parameter::IsTestAppTraceOn();
125     HIVIEW_LOGI("IsDeveloperMode=%{public}d, IsTestAppTraceOn=%{public}d", isDeveloperMode, isTestAppTraceOn);
126     AppCallerEvent::enableDynamicTrace_ = CHECK_DYNAMIC_TRACE_FSM[isDeveloperMode][isTestAppTraceOn] &&
127         DYNAMIC_TRACE_FSM[isBetaVersion][isUCollectionSwitchOn][isTraceCollectionSwitchOn];
128     HIVIEW_LOGI("dynamic trace open:%{public}d", AppCallerEvent::enableDynamicTrace_);
129 
130     int ret = Parameter::WatchParamChange(HIVIEW_UCOLLECTION_TEST_APP_TRACE_STATE, OnTestAppTraceStateChanged, nullptr);
131     HIVIEW_LOGI("add ucollection test app trace param watcher ret: %{public}d", ret);
132 }
133 
OnHiViewTraceRecorderChanged(const char * key,const char * value,void * context)134 void OnHiViewTraceRecorderChanged(const char* key, const char* value, void* context)
135 {
136     if (key == nullptr || value == nullptr) {
137         return;
138     }
139 
140     if (!(std::string(DEVELOP_HIVIEW_TRACE_RECORDER) == key)) {
141         return;
142     }
143 
144     bool isBetaVersion = Parameter::IsBetaVersion();
145     bool isUCollectionSwitchOn = Parameter::IsUCollectionSwitchOn();
146     bool isTraceCollectionSwitchOn = std::string(DEVELOP_TRACE_RECORDER_TRUE) == value;
147 
148     bool isDeveloperMode = Parameter::IsDeveloperMode();
149     bool isTestAppTraceOn = Parameter::IsTestAppTraceOn();
150     AppCallerEvent::enableDynamicTrace_ = CHECK_DYNAMIC_TRACE_FSM[isDeveloperMode][isTestAppTraceOn] &&
151         DYNAMIC_TRACE_FSM[isBetaVersion][isUCollectionSwitchOn][isTraceCollectionSwitchOn];
152     HIVIEW_LOGI("dynamic trace change to:%{public}d as trace recorder state", AppCallerEvent::enableDynamicTrace_);
153 }
154 
OnSwitchRecordTraceStateChanged(const char * key,const char * value,void * context)155 void OnSwitchRecordTraceStateChanged(const char* key, const char* value, void* context)
156 {
157     OnHiViewTraceRecorderChanged(key, value, context);
158     HIVIEW_LOGI("record trace state changed, ret: %{public}s", value);
159     if (key == nullptr || value == nullptr) {
160         HIVIEW_LOGE("record trace switch input ptr null");
161         return;
162     }
163     if (strncmp(key, DEVELOP_HIVIEW_TRACE_RECORDER, strlen(DEVELOP_HIVIEW_TRACE_RECORDER)) != 0) {
164         HIVIEW_LOGE("record trace switch param key error");
165         return;
166     }
167 
168     if (UnifiedCollector::IsEnableRecordTrace() == false && strncmp(value, "true", strlen("true")) == 0) {
169         UnifiedCollector::SetRecordTraceStatus(true);
170         TraceManager traceManager;
171         int32_t resultOpenTrace = traceManager.OpenRecordingTrace(DEVELOPER_MODE_TRACE_ARGS);
172         if (resultOpenTrace != 0) {
173             HIVIEW_LOGE("failed to start trace service");
174         }
175 
176         std::shared_ptr<UCollectUtil::TraceCollector> traceCollector = UCollectUtil::TraceCollector::Create();
177         CollectResult<int32_t> resultTraceOn = traceCollector->TraceOn();
178         if (resultTraceOn.retCode != UCollect::UcError::SUCCESS) {
179             HIVIEW_LOGE("failed to start collection trace");
180         }
181     } else if (UnifiedCollector::IsEnableRecordTrace() == true && strncmp(value, "false", strlen("false")) == 0) {
182         UnifiedCollector::SetRecordTraceStatus(false);
183         std::shared_ptr<UCollectUtil::TraceCollector> traceCollector = UCollectUtil::TraceCollector::Create();
184         CollectResult<std::vector<std::string>> resultTraceOff = traceCollector->TraceOff();
185         if (resultTraceOff.retCode != UCollect::UcError::SUCCESS) {
186             HIVIEW_LOGE("failed to stop collection trace");
187         }
188         TraceManager traceManager;
189         int32_t resultCloseTrace = traceManager.CloseTrace();
190         if (resultCloseTrace != 0) {
191             HIVIEW_LOGE("failed to stop trace service");
192         }
193     }
194 }
195 }
196 
197 bool UnifiedCollector::isEnableRecordTrace_ = false;
198 
OnLoad()199 void UnifiedCollector::OnLoad()
200 {
201     HIVIEW_LOGI("start to load UnifiedCollector plugin");
202     TraceManager::RecoverTmpTrace();
203     Init();
204 }
205 
OnUnload()206 void UnifiedCollector::OnUnload()
207 {
208     HIVIEW_LOGI("start to unload UnifiedCollector plugin");
209     UcObserverManager::GetInstance().UnregisterObservers();
210 }
211 
OnStartAppTrace(std::shared_ptr<AppCallerEvent> appCallerEvent)212 bool UnifiedCollector::OnStartAppTrace(std::shared_ptr<AppCallerEvent> appCallerEvent)
213 {
214     auto nextState = std::make_shared<StartTraceState>(appTraceContext_, appCallerEvent, shared_from_this());
215     return appTraceContext_->TransferTo(nextState) == 0;
216 }
217 
OnDumpAppTrace(std::shared_ptr<AppCallerEvent> appCallerEvent)218 bool UnifiedCollector::OnDumpAppTrace(std::shared_ptr<AppCallerEvent> appCallerEvent)
219 {
220     auto nextState = std::make_shared<DumpTraceState>(appTraceContext_, appCallerEvent, shared_from_this());
221     return appTraceContext_->TransferTo(nextState) == 0;
222 }
223 
OnStopAppTrace(std::shared_ptr<AppCallerEvent> appCallerEvent)224 bool UnifiedCollector::OnStopAppTrace(std::shared_ptr<AppCallerEvent> appCallerEvent)
225 {
226     auto nextState = std::make_shared<StopTraceState>(appTraceContext_, appCallerEvent);
227     return appTraceContext_->TransferTo(nextState) == 0;
228 }
229 
OnEvent(std::shared_ptr<Event> & event)230 bool UnifiedCollector::OnEvent(std::shared_ptr<Event>& event)
231 {
232     if (event == nullptr) {
233         return true;
234     }
235 
236     HIVIEW_LOGI("Receive Event %{public}s", event->GetEventName().c_str());
237     if (event->messageType_ == Event::MessageType::PLUGIN_MAINTENANCE) {
238         std::shared_ptr<AppCallerEvent> appCallerEvent = Event::DownCastTo<AppCallerEvent>(event);
239         if (event->eventName_ == UCollectUtil::START_APP_TRACE) {
240             return OnStartAppTrace(appCallerEvent);
241         }
242 
243         if (event->eventName_ == UCollectUtil::DUMP_APP_TRACE) {
244             return OnDumpAppTrace(appCallerEvent);
245         }
246 
247         if (event->eventName_ == UCollectUtil::STOP_APP_TRACE) {
248             return OnStopAppTrace(appCallerEvent);
249         }
250     }
251 
252     return true;
253 }
254 
OnMainThreadJank(SysEvent & sysEvent)255 void UnifiedCollector::OnMainThreadJank(SysEvent& sysEvent)
256 {
257     appTraceContext_->PublishStackEvent(sysEvent);
258 }
259 
OnEventListeningCallback(const Event & event)260 void UnifiedCollector::OnEventListeningCallback(const Event& event)
261 {
262     SysEvent& sysEvent = static_cast<SysEvent&>(const_cast<Event&>(event));
263     HIVIEW_LOGI("sysevent %{public}s", sysEvent.eventName_.c_str());
264 
265     if (sysEvent.eventName_ == UCollectUtil::MAIN_THREAD_JANK) {
266         OnMainThreadJank(sysEvent);
267         return;
268     }
269 #if PC_APP_STATE_COLLECT_ENABLE
270     int32_t procId = sysEvent.GetEventIntValue("APP_PID");
271     if (procId <= 0) {
272         HIVIEW_LOGW("invalid process id=%{public}d", procId);
273         return;
274     }
275     ProcessState procState = GetProcessStateByGroup(sysEvent);
276     if (procState == INVALID) {
277         HIVIEW_LOGD("invalid process state=%{public}d", procState);
278         return;
279     }
280     ProcessStatus::GetInstance().NotifyProcessState(procId, procState);
281 #endif // PC_APP_STATE_COLLECT_ENABLE
282 }
283 
Dump(int fd,const std::vector<std::string> & cmds)284 void UnifiedCollector::Dump(int fd, const std::vector<std::string>& cmds)
285 {
286     dprintf(fd, "device beta state is %s.\n", Parameter::IsBetaVersion() ? "beta" : "is not beta");
287 
288     std::string remoteLogState = Parameter::GetString(HIVIEW_UCOLLECTION_STATE, HIVIEW_UCOLLECTION_STATE_FALSE);
289     dprintf(fd, "remote log state is %s.\n", remoteLogState.c_str());
290 
291     std::string traceRecorderState = Parameter::GetString(DEVELOP_HIVIEW_TRACE_RECORDER, DEVELOP_TRACE_RECORDER_FALSE);
292     dprintf(fd, "trace recorder state is %s.\n", traceRecorderState.c_str());
293 
294     dprintf(fd, "develop state is %s.\n", Parameter::IsDeveloperMode() ? "true" : "false");
295     dprintf(fd, "test app trace state is %s.\n", Parameter::IsTestAppTraceOn() ? "true" : "false");
296 
297     dprintf(fd, "dynamic trace state is %s.\n", AppCallerEvent::enableDynamicTrace_ ? "true" : "false");
298 
299     TraceManager traceManager;
300     dprintf(fd, "trace mode is %d.\n", traceManager.GetTraceMode());
301 }
302 
Init()303 void UnifiedCollector::Init()
304 {
305     if (GetHiviewContext() == nullptr) {
306         HIVIEW_LOGE("hiview context is null");
307         return;
308     }
309 
310     appTraceContext_ = std::make_shared<AppTraceContext>(std::make_shared<StopTraceState>(nullptr, nullptr));
311 
312     InitWorkLoop();
313     InitWorkPath();
314     bool isAllowCollect = Parameter::IsBetaVersion() || Parameter::IsUCollectionSwitchOn();
315     if (isAllowCollect) {
316         RunIoCollectionTask();
317         RunUCollectionStatTask();
318         LoadHitraceService();
319     }
320     if (isAllowCollect || Parameter::IsDeveloperMode()) {
321         RunCpuCollectionTask();
322     }
323     if (!Parameter::IsBetaVersion()) {
324         int ret = Parameter::WatchParamChange(HIVIEW_UCOLLECTION_STATE, OnSwitchStateChanged, this);
325         HIVIEW_LOGI("add ucollection switch param watcher ret: %{public}d", ret);
326     }
327     UcObserverManager::GetInstance().RegisterObservers();
328 
329     InitDynamicTrace();
330 
331     if (Parameter::IsDeveloperMode()) {
332         RunRecordTraceTask();
333     }
334 }
335 
CleanDataFiles()336 void UnifiedCollector::CleanDataFiles()
337 {
338     std::vector<std::string> files;
339     FileUtil::GetDirFiles(UNIFIED_SPECIAL_PATH, files);
340     for (const auto& file : files) {
341         if (file.find(OTHER) != std::string::npos) {
342             FileUtil::RemoveFile(file);
343         }
344     }
345     FileUtil::ForceRemoveDirectory(COLLECTION_IO_PATH, false);
346     FileUtil::ForceRemoveDirectory(HIPERF_LOG_PATH, false);
347 }
348 
OnSwitchStateChanged(const char * key,const char * value,void * context)349 void UnifiedCollector::OnSwitchStateChanged(const char* key, const char* value, void* context)
350 {
351     if (context == nullptr || key == nullptr || value == nullptr) {
352         HIVIEW_LOGE("input ptr null");
353         return;
354     }
355     if (strncmp(key, HIVIEW_UCOLLECTION_STATE, strlen(HIVIEW_UCOLLECTION_STATE)) != 0) {
356         HIVIEW_LOGE("param key error");
357         return;
358     }
359     HIVIEW_LOGI("ucollection switch state changed, ret: %{public}s", value);
360     UnifiedCollector* unifiedCollectorPtr = static_cast<UnifiedCollector*>(context);
361     if (unifiedCollectorPtr == nullptr) {
362         HIVIEW_LOGE("unifiedCollectorPtr is null");
363         return;
364     }
365 
366     bool isUCollectionSwitchOn;
367     if (value == HIVIEW_UCOLLECTION_STATE_TRUE) {
368         isUCollectionSwitchOn = true;
369         unifiedCollectorPtr->RunCpuCollectionTask();
370         unifiedCollectorPtr->RunIoCollectionTask();
371         unifiedCollectorPtr->RunUCollectionStatTask();
372         unifiedCollectorPtr->LoadHitraceService();
373     } else {
374         isUCollectionSwitchOn = false;
375         if (!Parameter::IsDeveloperMode()) {
376             unifiedCollectorPtr->isCpuTaskRunning_ = false;
377         }
378         for (const auto &it : unifiedCollectorPtr->taskList_) {
379             unifiedCollectorPtr->workLoop_->RemoveEvent(it);
380         }
381         unifiedCollectorPtr->taskList_.clear();
382         unifiedCollectorPtr->ExitHitraceService();
383         unifiedCollectorPtr->CleanDataFiles();
384     }
385 
386     bool isTraceCollectionSwitchOn = Parameter::IsTraceCollectionSwitchOn();
387 
388     bool isDeveloperMode = Parameter::IsDeveloperMode();
389     bool isTestAppTraceOn = Parameter::IsTestAppTraceOn();
390     AppCallerEvent::enableDynamicTrace_ = CHECK_DYNAMIC_TRACE_FSM[isDeveloperMode][isTestAppTraceOn] &&
391         DYNAMIC_TRACE_FSM[COML_STATE][isUCollectionSwitchOn][isTraceCollectionSwitchOn];
392 }
393 
LoadHitraceService()394 void UnifiedCollector::LoadHitraceService()
395 {
396     std::lock_guard<std::mutex> lock(g_traceLock);
397     HIVIEW_LOGI("start to load hitrace service.");
398     uint8_t mode = GetTraceMode();
399     if (mode != TraceMode::CLOSE) {
400         HIVIEW_LOGE("service is running, mode=%{public}u.", mode);
401         return;
402     }
403     const std::vector<std::string> tagGroups = {"scene_performance"};
404     TraceErrorCode ret = OpenTrace(tagGroups);
405     if (ret != TraceErrorCode::SUCCESS) {
406         HIVIEW_LOGE("OpenTrace fail.");
407     }
408 }
409 
ExitHitraceService()410 void UnifiedCollector::ExitHitraceService()
411 {
412     std::lock_guard<std::mutex> lock(g_traceLock);
413     HIVIEW_LOGI("exit hitrace service.");
414     uint8_t mode = GetTraceMode();
415     if (mode == TraceMode::CLOSE) {
416         HIVIEW_LOGE("service is close mode.");
417         return;
418     }
419     CloseTrace();
420 }
421 
InitWorkLoop()422 void UnifiedCollector::InitWorkLoop()
423 {
424     workLoop_ = GetHiviewContext()->GetSharedWorkLoop();
425 }
426 
InitWorkPath()427 void UnifiedCollector::InitWorkPath()
428 {
429     std::string hiviewWorkDir = GetHiviewContext()->GetHiViewDirectory(HiviewContext::DirectoryType::WORK_DIRECTORY);
430     const std::string uCollectionDirName = "unified_collection";
431     std::string tempWorkPath = FileUtil::IncludeTrailingPathDelimiter(hiviewWorkDir.append(uCollectionDirName));
432     if (!FileUtil::IsDirectory(tempWorkPath) && !FileUtil::ForceCreateDirectory(tempWorkPath)) {
433         HIVIEW_LOGE("failed to create dir=%{public}s", tempWorkPath.c_str());
434         return;
435     }
436     workPath_ = tempWorkPath;
437 }
438 
RunCpuCollectionTask()439 void UnifiedCollector::RunCpuCollectionTask()
440 {
441     if (workPath_.empty() || isCpuTaskRunning_) {
442         HIVIEW_LOGE("workPath is null or task is running");
443         return;
444     }
445     isCpuTaskRunning_ = true;
446     auto task = [this] { this->CpuCollectionFfrtTask(); };
447     ffrt::submit(task, {}, {}, ffrt::task_attr().name("dft_uc_cpu").qos(ffrt::qos_default));
448 }
449 
CpuCollectionFfrtTask()450 void UnifiedCollector::CpuCollectionFfrtTask()
451 {
452     cpuCollectionTask_ = std::make_shared<CpuCollectionTask>(workPath_);
453     while (true) {
454         if (!isCpuTaskRunning_) {
455             HIVIEW_LOGE("exit cpucollection task");
456             break;
457         }
458         ffrt::this_task::sleep_for(10s); // 10s: collect period
459         cpuCollectionTask_->Collect();
460     }
461 }
462 
RunIoCollectionTask()463 void UnifiedCollector::RunIoCollectionTask()
464 {
465     if (workLoop_ == nullptr) {
466         HIVIEW_LOGE("workLoop is null");
467         return;
468     }
469     auto ioCollectionTask = [this] { this->IoCollectionTask(); };
470     const uint64_t taskInterval = 30; // 30s
471     auto ioSeqId = workLoop_->AddTimerEvent(nullptr, nullptr, ioCollectionTask, taskInterval, true);
472     taskList_.push_back(ioSeqId);
473 }
474 
IoCollectionTask()475 void UnifiedCollector::IoCollectionTask()
476 {
477     auto ioCollector = UCollectUtil::IoCollector::Create();
478     (void)ioCollector->CollectDiskStats([](const DiskStats &stats) { return false; }, true);
479     (void)ioCollector->CollectAllProcIoStats(true);
480 }
481 
RunUCollectionStatTask()482 void UnifiedCollector::RunUCollectionStatTask()
483 {
484     if (workLoop_ == nullptr) {
485         HIVIEW_LOGE("workLoop is null");
486         return;
487     }
488     auto statTask = [this] { this->UCollectionStatTask(); };
489     const uint64_t taskInterval = 600; // 600s
490     auto statSeqId = workLoop_->AddTimerEvent(nullptr, nullptr, statTask, taskInterval, true);
491     taskList_.push_back(statSeqId);
492 }
493 
UCollectionStatTask()494 void UnifiedCollector::UCollectionStatTask()
495 {
496     UnifiedCollectionStat stat;
497     stat.Report();
498 }
499 
RunRecordTraceTask()500 void UnifiedCollector::RunRecordTraceTask()
501 {
502     if (IsEnableRecordTrace() == false && Parameter::IsTraceCollectionSwitchOn()) {
503         SetRecordTraceStatus(true);
504         TraceManager traceManager;
505         int32_t resultOpenTrace = traceManager.OpenRecordingTrace(DEVELOPER_MODE_TRACE_ARGS);
506         if (resultOpenTrace != 0) {
507             HIVIEW_LOGE("failed to start trace service");
508         }
509 
510         std::shared_ptr<UCollectUtil::TraceCollector> traceCollector = UCollectUtil::TraceCollector::Create();
511         CollectResult<int32_t> resultTraceOn = traceCollector->TraceOn();
512         if (resultTraceOn.retCode != UCollect::UcError::SUCCESS) {
513             HIVIEW_LOGE("failed to start collection trace");
514         }
515     }
516     int ret = Parameter::WatchParamChange(DEVELOP_HIVIEW_TRACE_RECORDER, OnSwitchRecordTraceStateChanged, this);
517     HIVIEW_LOGI("add ucollection trace switch param watcher ret: %{public}d", ret);
518 }
519 } // namespace HiviewDFX
520 } // namespace OHOS
521