• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <ctime>
18 #include <memory>
19 
20 #include "collect_event.h"
21 #include "ffrt.h"
22 #include "file_util.h"
23 #include "hiview_logger.h"
24 #include "io_collector.h"
25 #include "memory_collector.h"
26 #include "parameter_ex.h"
27 #include "plugin_factory.h"
28 #include "process_status.h"
29 #include "sys_event.h"
30 #include "time_util.h"
31 #include "uc_observer_mgr.h"
32 #include "unified_collection_stat.h"
33 #ifdef UNIFIED_COLLECTOR_TRACE_ENABLE
34 #include "app_caller_event.h"
35 #include "event_publish.h"
36 #include "hisysevent.h"
37 #include "trace_utils.h"
38 #include "trace_state_machine.h"
39 #include "trace_flow_controller.h"
40 #include "uc_telemetry_listener.h"
41 #include "unified_common.h"
42 #endif
43 
44 namespace OHOS {
45 namespace HiviewDFX {
46 REGISTER(UnifiedCollector);
47 DEFINE_LOG_TAG("HiView-UnifiedCollector");
48 using namespace OHOS::HiviewDFX::UCollectUtil;
49 using namespace std::literals::chrono_literals;
50 namespace {
51 const std::string HIPERF_LOG_PATH = "/data/log/hiperf";
52 const std::string COLLECTION_IO_PATH = "/data/log/hiview/unified_collection/io/";
53 const std::string HIVIEW_UCOLLECTION_STATE_TRUE = "true";
54 const std::string HIVIEW_UCOLLECTION_STATE_FALSE = "false";
55 #ifdef UNIFIED_COLLECTOR_TRACE_ENABLE
56 const std::string UNIFIED_SHARE_PATH = "/data/log/hiview/unified_collection/trace/share/";
57 const std::string UNIFIED_SPECIAL_PATH = "/data/log/hiview/unified_collection/trace/special/";
58 const std::string UNIFIED_TELEMETRY_PATH = "/data/log/hiview/unified_collection/trace/telemetry/";
59 const std::string UNIFIED_SHARE_TEMP_PATH = UNIFIED_SHARE_PATH + "temp/";
60 const std::string DEVELOP_TRACE_RECORDER_FALSE = "false";
61 constexpr char KEY_FREEZE_DETECTOR_STATE[] = "persist.hiview.freeze_detector";
62 const std::string OTHER = "Other";
63 using namespace OHOS::HiviewDFX::Hitrace;
64 constexpr int32_t DURATION_TRACE = 10; // unit second
65 
CreateTracePathInner(const std::string & filePath)66 void CreateTracePathInner(const std::string &filePath)
67 {
68     if (FileUtil::FileExists(filePath)) {
69         return;
70     }
71     if (!CreateMultiDirectory(filePath)) {
72         HIVIEW_LOGE("failed to create multidirectory %{public}s.", filePath.c_str());
73         return;
74     }
75 }
76 
CreateTracePath()77 void CreateTracePath()
78 {
79     CreateTracePathInner(UNIFIED_SHARE_PATH);
80     CreateTracePathInner(UNIFIED_SPECIAL_PATH);
81     CreateTracePathInner(UNIFIED_TELEMETRY_PATH);
82 }
83 #endif
84 }
85 
OnLoad()86 void UnifiedCollector::OnLoad()
87 {
88     HIVIEW_LOGI("start to load UnifiedCollector plugin");
89     Init();
90 }
91 
OnUnload()92 void UnifiedCollector::OnUnload()
93 {
94     HIVIEW_LOGI("start to unload UnifiedCollector plugin");
95     UcObserverManager::GetInstance().UnregisterObservers();
96 }
97 
98 #ifdef UNIFIED_COLLECTOR_TRACE_ENABLE
OnFreezeDetectorParamChanged(const char * key,const char * value,void * context)99 void UnifiedCollector::OnFreezeDetectorParamChanged(const char* key, const char* value, void* context)
100 {
101     if (key == nullptr || value == nullptr) {
102         HIVIEW_LOGW("key or value is null");
103         return;
104     }
105     if (strncmp(key, KEY_FREEZE_DETECTOR_STATE, strlen(KEY_FREEZE_DETECTOR_STATE)) != 0) {
106         HIVIEW_LOGW("key is not wanted, key: %{public}s", key);
107         return;
108     }
109     HIVIEW_LOGI("freeze detector param changed, value: %{public}s", value);
110     if (strncmp(value, "true", strlen("true")) == 0) {
111         TraceStateMachine::GetInstance().SetTraceSwitchFreezeOn();
112     } else {
113         TraceStateMachine::GetInstance().SetTraceSwitchFreezeOff();
114     }
115 }
116 
OnSwitchRecordTraceStateChanged(const char * key,const char * value,void * context)117 void UnifiedCollector::OnSwitchRecordTraceStateChanged(const char* key, const char* value, void* context)
118 {
119     if (key == nullptr || value == nullptr) {
120         HIVIEW_LOGE("record trace switch input ptr null");
121         return;
122     }
123     if (strncmp(key, DEVELOP_HIVIEW_TRACE_RECORDER, strlen(DEVELOP_HIVIEW_TRACE_RECORDER)) != 0) {
124         HIVIEW_LOGE("record trace switch param key error");
125         return;
126     }
127     if (strncmp(value, "true", strlen("true")) == 0) {
128         TraceStateMachine::GetInstance().SetTraceSwitchDevOn();
129     } else {
130         TraceStateMachine::GetInstance().SetTraceSwitchDevOff();
131     }
132 }
133 
LoadTraceSwitch()134 void UnifiedCollector::LoadTraceSwitch()
135 {
136     if (Parameter::IsBetaVersion()) {
137         TraceStateMachine::GetInstance().SetTraceVersionBeta();
138     } else {
139         int watchFreezeRet = Parameter::WatchParamChange(KEY_FREEZE_DETECTOR_STATE,
140             OnFreezeDetectorParamChanged, nullptr);
141         HIVIEW_LOGI("watchFreezeRet:%{public}d", watchFreezeRet);
142     }
143     if (Parameter::IsUCollectionSwitchOn()) {
144         TraceStateMachine::GetInstance().SetTraceSwitchUcOn();
145     }
146     if (Parameter::GetBoolean(KEY_FREEZE_DETECTOR_STATE, false)) {
147         TraceStateMachine::GetInstance().SetTraceSwitchFreezeOn();
148     }
149     if (Parameter::IsDeveloperMode()) {
150         if (Parameter::IsTraceCollectionSwitchOn()) {
151             TraceStateMachine::GetInstance().SetTraceSwitchDevOn();
152         }
153         int ret = Parameter::WatchParamChange(DEVELOP_HIVIEW_TRACE_RECORDER, OnSwitchRecordTraceStateChanged, this);
154         HIVIEW_LOGI("add ucollection trace switch param watcher ret: %{public}d", ret);
155     }
156 }
157 
OnMainThreadJank(SysEvent & sysEvent)158 void UnifiedCollector::OnMainThreadJank(SysEvent& sysEvent)
159 {
160     if (sysEvent.GetEventIntValue(UCollectUtil::SYS_EVENT_PARAM_JANK_LEVEL) <
161         UCollectUtil::SYS_EVENT_JANK_LEVEL_VALUE_TRACE) {
162         // hicollie capture stack in application process, only need to share app event to application by hiview
163         Json::Value eventJson;
164         eventJson[UCollectUtil::APP_EVENT_PARAM_UID] = sysEvent.GetUid();
165         eventJson[UCollectUtil::APP_EVENT_PARAM_PID] = sysEvent.GetPid();
166         eventJson[UCollectUtil::APP_EVENT_PARAM_TIME] = sysEvent.happenTime_;
167         eventJson[UCollectUtil::APP_EVENT_PARAM_BUNDLE_NAME] = sysEvent.GetEventValue(
168             UCollectUtil::SYS_EVENT_PARAM_BUNDLE_NAME);
169         eventJson[UCollectUtil::APP_EVENT_PARAM_BUNDLE_VERSION] = sysEvent.GetEventValue(
170             UCollectUtil::SYS_EVENT_PARAM_BUNDLE_VERSION);
171         eventJson[UCollectUtil::APP_EVENT_PARAM_BEGIN_TIME] = sysEvent.GetEventIntValue(
172             UCollectUtil::SYS_EVENT_PARAM_BEGIN_TIME);
173         eventJson[UCollectUtil::APP_EVENT_PARAM_END_TIME] = sysEvent.GetEventIntValue(
174             UCollectUtil::SYS_EVENT_PARAM_END_TIME);
175         eventJson[UCollectUtil::APP_EVENT_PARAM_APP_START_JIFFIES_TIME] = sysEvent.GetEventIntValue(
176             UCollectUtil::SYS_EVENT_PARAM_APP_START_JIFFIES_TIME);
177         eventJson[UCollectUtil::APP_EVENT_PARAM_HEAVIEST_STACK] = sysEvent.GetEventValue(
178             UCollectUtil::SYS_EVENT_PARAM_HEAVIEST_STACK);
179         Json::Value externalLog;
180         externalLog.append(sysEvent.GetEventValue(UCollectUtil::SYS_EVENT_PARAM_EXTERNAL_LOG));
181         eventJson[UCollectUtil::APP_EVENT_PARAM_EXTERNAL_LOG] = externalLog;
182         std::string param = Json::FastWriter().write(eventJson);
183 
184         HIVIEW_LOGI("send as stack trigger for uid=%{public}d pid=%{public}d", sysEvent.GetUid(), sysEvent.GetPid());
185         EventPublish::GetInstance().PushEvent(sysEvent.GetUid(), UCollectUtil::MAIN_THREAD_JANK,
186                                               HiSysEvent::EventType::FAULT, param);
187     }
188 }
189 
OnEvent(std::shared_ptr<Event> & event)190 bool UnifiedCollector::OnEvent(std::shared_ptr<Event>& event)
191 {
192     if (event == nullptr || workLoop_ == nullptr) {
193         return true;
194     }
195     HIVIEW_LOGI("Receive Event %{public}s", event->GetEventName().c_str());
196     if (event->eventName_ == UCollectUtil::START_APP_TRACE) {
197         event->eventName_ = UCollectUtil::STOP_APP_TRACE;
198         DelayProcessEvent(event, DURATION_TRACE);
199         return true;
200     }
201     if (event->eventName_ == UCollectUtil::STOP_APP_TRACE) {
202         auto ret = TraceStateMachine::GetInstance().CloseTrace(TraceScenario::TRACE_DYNAMIC);
203         if (!ret.IsSuccess()) {
204             HIVIEW_LOGW("CloseTrace app trace fail");
205         }
206         return true;
207     }
208     if (event->eventName_ == TelemetryEvent::TELEMETRY_START) {
209         HandleTeleMetryStart(event);
210         return true;
211     }
212     if (event->eventName_ == TelemetryEvent::TELEMETRY_STOP) {
213         HandleTeleMetryStop();
214         return true;
215     }
216     if (event->eventName_ == TelemetryEvent::TELEMETRY_TIMEOUT) {
217         HandleTeleMetryTimeout();
218         return true;
219     }
220     return true;
221 }
222 
HandleTeleMetryStart(std::shared_ptr<Event> & event)223 void UnifiedCollector::HandleTeleMetryStart(std::shared_ptr<Event> &event)
224 {
225     int32_t delay = event->GetIntValue(Telemetry::KEY_DELAY_TIME);
226     if (delay > 0) {
227         HIVIEW_LOGI("delay:%{public}d", delay);
228         event->SetValue(Telemetry::KEY_DELAY_TIME, 0);
229         auto seqId = workLoop_->AddTimerEvent(shared_from_this(), event, nullptr, static_cast<uint64_t>(delay), false);
230         telemetryList_.push_back(seqId);
231         return;
232     }
233     std::string tag = event->GetValue(Telemetry::KEY_TELEMETRY_TRACE_TAG);
234     int32_t traceDuration = event->GetIntValue(Telemetry::KEY_REMAIN_TIME);
235     std::string telemetryId = event->GetValue(Telemetry::KEY_ID);
236     std::string bundleName = event->GetValue(Telemetry::KEY_BUNDLE_NAME);
237     if (traceDuration <= 0) {
238         HIVIEW_LOGE("system error traceDuration:%{public}d", traceDuration);
239         return;
240     }
241     auto ret = TraceStateMachine::GetInstance().OpenTelemetryTrace(tag);
242     HiSysEventWrite(Telemetry::TELEMETRY_DOMAIN, "TASK_INFO", HiSysEvent::EventType::STATISTIC,
243         "ID", telemetryId,
244         "STAGE", "TRACE_BEGIN",
245         "ERROR", std::to_string(GetUcError(ret)),
246         "BUNDLE_NAME", bundleName);
247     event->eventName_ = TelemetryEvent::TELEMETRY_TIMEOUT;
248     if (ret.IsSuccess()) {
249         bool isSuccess = TraceStateMachine::GetInstance().RegisterTelemetryCallback([telemetryId, bundleName]() {
250             HiSysEventWrite(Telemetry::TELEMETRY_DOMAIN, "TASK_INFO", HiSysEvent::EventType::STATISTIC,
251                 "ID", telemetryId,
252                 "STAGE", "TRACE_END",
253                 "ERROR", 0,
254                 "BUNDLE_NAME", bundleName);
255         });
256         HIVIEW_LOGE("RegisterTelemetryCallback:%{public}d", isSuccess);
257     }
258     auto seqId = workLoop_->AddTimerEvent(shared_from_this(), event, nullptr, static_cast<uint64_t>(traceDuration),
259         false);
260     telemetryList_.push_back(seqId);
261 }
262 
HandleTeleMetryStop()263 void UnifiedCollector::HandleTeleMetryStop()
264 {
265     TraceStateMachine::GetInstance().CloseTrace(TraceScenario::TRACE_TELEMETRY);
266     TraceFlowController controller(BusinessName::TELEMETRY);
267     controller.ClearTelemetryData();
268     for (auto it : telemetryList_) {
269         workLoop_->RemoveEvent(it);
270     }
271     telemetryList_.clear();
272 }
273 
HandleTeleMetryTimeout()274 void UnifiedCollector::HandleTeleMetryTimeout()
275 {
276     TraceStateMachine::GetInstance().CloseTrace(TraceScenario::TRACE_TELEMETRY);
277 }
278 
OnEventListeningCallback(const Event & event)279 void UnifiedCollector::OnEventListeningCallback(const Event& event)
280 {
281     SysEvent& sysEvent = static_cast<SysEvent&>(const_cast<Event&>(event));
282     HIVIEW_LOGI("sysevent %{public}s", sysEvent.eventName_.c_str());
283 
284     if (sysEvent.eventName_ == UCollectUtil::MAIN_THREAD_JANK) {
285         OnMainThreadJank(sysEvent);
286         return;
287     }
288 }
289 
Dump(int fd,const std::vector<std::string> & cmds)290 void UnifiedCollector::Dump(int fd, const std::vector<std::string>& cmds)
291 {
292     dprintf(fd, "device beta state is %s.\n", Parameter::IsBetaVersion() ? "beta" : "is not beta");
293 
294     std::string remoteLogState = Parameter::GetString(HIVIEW_UCOLLECTION_STATE, HIVIEW_UCOLLECTION_STATE_FALSE);
295     dprintf(fd, "remote log state is %s.\n", remoteLogState.c_str());
296 
297     std::string traceRecorderState = Parameter::GetString(DEVELOP_HIVIEW_TRACE_RECORDER, DEVELOP_TRACE_RECORDER_FALSE);
298     dprintf(fd, "trace recorder state is %s.\n", traceRecorderState.c_str());
299 
300     dprintf(fd, "develop state is %s.\n", Parameter::IsDeveloperMode() ? "true" : "false");
301 }
302 
303 #ifdef HIVIEW_LOW_MEM_THRESHOLD
RunCacheMonitorLoop()304 void UnifiedCollector::RunCacheMonitorLoop()
305 {
306     if (traceCacheMonitor_ == nullptr) {
307         traceCacheMonitor_ = std::make_shared<TraceCacheMonitor>();
308     }
309     traceCacheMonitor_->RunMonitorLoop();
310 }
311 
ExitCacheMonitorLoop()312 void UnifiedCollector::ExitCacheMonitorLoop()
313 {
314     if (traceCacheMonitor_ != nullptr) {
315         traceCacheMonitor_->ExitMonitorLoop();
316     }
317 }
318 #endif
319 #endif
320 
Init()321 void UnifiedCollector::Init()
322 {
323     auto context = GetHiviewContext();
324     if (context == nullptr) {
325         HIVIEW_LOGE("hiview context is null");
326         return;
327     }
328     workLoop_ = context->GetSharedWorkLoop();
329     if (workLoop_ == nullptr) {
330         HIVIEW_LOGE("workLoop is null");
331         return;
332     }
333     InitWorkPath();
334 #ifdef UNIFIED_COLLECTOR_TRACE_ENABLE
335     CreateTracePath();
336     LoadTraceSwitch();
337     telemetryListener_ = std::make_shared<TelemetryListener>(shared_from_this());
338     context->AddListenerInfo(Event::MessageType::TELEMETRY_EVENT, telemetryListener_->GetListenerName());
339     context->RegisterUnorderedEventListener(telemetryListener_);
340     RecoverTmpTrace();
341 #endif
342     if (Parameter::IsBetaVersion() || Parameter::IsUCollectionSwitchOn()) {
343         RunIoCollectionTask();
344         RunUCollectionStatTask();
345     }
346     if (Parameter::IsBetaVersion() || Parameter::IsUCollectionSwitchOn() || Parameter::IsDeveloperMode()) {
347         RunCpuCollectionTask();
348 #ifdef HIVIEW_LOW_MEM_THRESHOLD
349         RunCacheMonitorLoop();
350 #endif
351     }
352     if (!Parameter::IsBetaVersion()) {
353         int watchUcollectionRet = Parameter::WatchParamChange(HIVIEW_UCOLLECTION_STATE, OnSwitchStateChanged, this);
354         HIVIEW_LOGI("watchUcollectionRet:%{public}d", watchUcollectionRet);
355     }
356     UcObserverManager::GetInstance().RegisterObservers();
357 }
358 
CleanDataFiles()359 void UnifiedCollector::CleanDataFiles()
360 {
361 #ifdef UNIFIED_COLLECTOR_TRACE_ENABLE
362     std::vector<std::string> files;
363     FileUtil::GetDirFiles(UNIFIED_SPECIAL_PATH, files);
364     for (const auto& file : files) {
365         if (file.find(OTHER) != std::string::npos) {
366             FileUtil::RemoveFile(file);
367         }
368     }
369 #endif
370     FileUtil::ForceRemoveDirectory(COLLECTION_IO_PATH, false);
371     FileUtil::ForceRemoveDirectory(HIPERF_LOG_PATH, false);
372 }
373 
OnSwitchStateChanged(const char * key,const char * value,void * context)374 void UnifiedCollector::OnSwitchStateChanged(const char* key, const char* value, void* context)
375 {
376     if (context == nullptr || key == nullptr || value == nullptr) {
377         HIVIEW_LOGE("input ptr null");
378         return;
379     }
380     if (strncmp(key, HIVIEW_UCOLLECTION_STATE, strlen(HIVIEW_UCOLLECTION_STATE)) != 0) {
381         HIVIEW_LOGE("param key error");
382         return;
383     }
384     HIVIEW_LOGI("ucollection switch state changed, ret: %{public}s", value);
385     auto* unifiedCollectorPtr = static_cast<UnifiedCollector*>(context);
386     if (unifiedCollectorPtr == nullptr) {
387         HIVIEW_LOGE("unifiedCollectorPtr is null");
388         return;
389     }
390     if (value == HIVIEW_UCOLLECTION_STATE_TRUE) {
391         unifiedCollectorPtr->RunCpuCollectionTask();
392         unifiedCollectorPtr->RunIoCollectionTask();
393         unifiedCollectorPtr->RunUCollectionStatTask();
394 #ifdef UNIFIED_COLLECTOR_TRACE_ENABLE
395         TraceStateMachine::GetInstance().SetTraceSwitchUcOn();
396 #ifdef HIVIEW_LOW_MEM_THRESHOLD
397         unifiedCollectorPtr->RunCacheMonitorLoop();
398 #endif
399 #endif
400     } else {
401         if (!Parameter::IsDeveloperMode()) {
402             unifiedCollectorPtr->isCpuTaskRunning_ = false;
403         }
404         for (const auto &it : unifiedCollectorPtr->taskList_) {
405             unifiedCollectorPtr->workLoop_->RemoveEvent(it);
406         }
407         unifiedCollectorPtr->taskList_.clear();
408 #ifdef UNIFIED_COLLECTOR_TRACE_ENABLE
409         TraceStateMachine::GetInstance().SetTraceSwitchUcOff();
410 #ifdef HIVIEW_LOW_MEM_THRESHOLD
411         unifiedCollectorPtr->ExitCacheMonitorLoop();
412 #endif
413 #endif
414         unifiedCollectorPtr->CleanDataFiles();
415     }
416 }
417 
InitWorkPath()418 void UnifiedCollector::InitWorkPath()
419 {
420     std::string hiviewWorkDir = GetHiviewContext()->GetHiViewDirectory(HiviewContext::DirectoryType::WORK_DIRECTORY);
421     const std::string uCollectionDirName = "unified_collection";
422     std::string tempWorkPath = FileUtil::IncludeTrailingPathDelimiter(hiviewWorkDir.append(uCollectionDirName));
423     if (!FileUtil::IsDirectory(tempWorkPath) && !FileUtil::ForceCreateDirectory(tempWorkPath)) {
424         HIVIEW_LOGE("failed to create dir=%{public}s", tempWorkPath.c_str());
425         return;
426     }
427     workPath_ = tempWorkPath;
428 }
429 
RunCpuCollectionTask()430 void UnifiedCollector::RunCpuCollectionTask()
431 {
432     if (workPath_.empty() || isCpuTaskRunning_) {
433         HIVIEW_LOGE("workPath is null or task is running");
434         return;
435     }
436     isCpuTaskRunning_ = true;
437     auto task = [this] { this->CpuCollectionFfrtTask(); };
438     ffrt::submit(task, {}, {}, ffrt::task_attr().name("dft_uc_cpu").qos(ffrt::qos_default));
439 }
440 
CpuCollectionFfrtTask()441 void UnifiedCollector::CpuCollectionFfrtTask()
442 {
443     cpuCollectionTask_ = std::make_shared<CpuCollectionTask>(workPath_);
444     while (true) {
445         if (!isCpuTaskRunning_) {
446             HIVIEW_LOGE("exit cpucollection task");
447             break;
448         }
449         ffrt::this_task::sleep_for(10s); // 10s: collect period
450         cpuCollectionTask_->Collect();
451     }
452 }
453 
RunIoCollectionTask()454 void UnifiedCollector::RunIoCollectionTask()
455 {
456     if (workLoop_ == nullptr) {
457         HIVIEW_LOGE("workLoop is null");
458         return;
459     }
460     auto ioCollectionTask = [this] { this->IoCollectionTask(); };
461     const uint64_t taskInterval = 30; // 30s
462     auto ioSeqId = workLoop_->AddTimerEvent(nullptr, nullptr, ioCollectionTask, taskInterval, true);
463     taskList_.push_back(ioSeqId);
464 }
465 
IoCollectionTask()466 void UnifiedCollector::IoCollectionTask()
467 {
468     auto ioCollector = UCollectUtil::IoCollector::Create();
469     (void)ioCollector->CollectDiskStats([](const DiskStats &stats) { return false; }, true);
470     (void)ioCollector->CollectAllProcIoStats(true);
471 }
472 
RunUCollectionStatTask()473 void UnifiedCollector::RunUCollectionStatTask()
474 {
475     if (workLoop_ == nullptr) {
476         HIVIEW_LOGE("workLoop is null");
477         return;
478     }
479     auto statTask = [this] { this->UCollectionStatTask(); };
480     const uint64_t taskInterval = 600; // 600s
481     auto statSeqId = workLoop_->AddTimerEvent(nullptr, nullptr, statTask, taskInterval, true);
482     taskList_.push_back(statSeqId);
483 }
484 
UCollectionStatTask()485 void UnifiedCollector::UCollectionStatTask()
486 {
487     UnifiedCollectionStat stat;
488     stat.Report();
489 }
490 } // namespace HiviewDFX
491 } // namespace OHOS
492