• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "ffrt.h"
18 #include "file_util.h"
19 #include "io_collector.h"
20 #include "logger.h"
21 #include "plugin_factory.h"
22 #include "process_status.h"
23 #include "sys_event.h"
24 #include "unified_collection_stat.h"
25 
26 namespace OHOS {
27 namespace HiviewDFX {
28 REGISTER(UnifiedCollector);
29 DEFINE_LOG_TAG("HiView-UnifiedCollector");
30 using namespace OHOS::HiviewDFX::UCollectUtil;
31 using namespace std::literals::chrono_literals;
32 namespace {
33 const std::unordered_map<std::string, ProcessState> APP_STATES = {
34     {"APP_FOREGROUND", FOREGROUND},
35     {"APP_BACKGROUND", BACKGROUND},
36 };
37 
GetProcessStateByEvent(const SysEvent & sysEvent)38 ProcessState GetProcessStateByEvent(const SysEvent& sysEvent)
39 {
40     std::string eventName = sysEvent.GetEventName();
41     if (APP_STATES.find(eventName) != APP_STATES.end()) {
42         return APP_STATES.at(eventName);
43     }
44     HIVIEW_LOGW("invalid event name=%{public}s", eventName.c_str());
45     return INVALID;
46 }
47 }
48 
OnLoad()49 void UnifiedCollector::OnLoad()
50 {
51     HIVIEW_LOGI("start to load UnifiedCollector plugin");
52     Init();
53 }
54 
OnUnload()55 void UnifiedCollector::OnUnload()
56 {
57     HIVIEW_LOGI("start to unload UnifiedCollector plugin");
58 }
59 
OnEventListeningCallback(const Event & event)60 void UnifiedCollector::OnEventListeningCallback(const Event& event)
61 {
62     SysEvent& sysEvent = static_cast<SysEvent&>(const_cast<Event&>(event));
63     int32_t procId = sysEvent.GetEventIntValue("APP_PID");
64     if (procId <= 0) {
65         HIVIEW_LOGW("invalid process id=%{public}d", procId);
66         return;
67     }
68     ProcessState procState = GetProcessStateByEvent(sysEvent);
69     if (procState == INVALID) {
70         HIVIEW_LOGW("invalid process state=%{public}d", procState);
71         return;
72     }
73     ProcessStatus::GetInstance().NotifyProcessState(procId, procState);
74 }
75 
Init()76 void UnifiedCollector::Init()
77 {
78     if (GetHiviewContext() == nullptr) {
79         HIVIEW_LOGE("hiview context is null");
80         return;
81     }
82     InitWorkLoop();
83     InitWorkPath();
84     RunCpuCollectionTask();
85     RunIoCollectionTask();
86     RunUCollectionStatTask();
87 }
88 
InitWorkLoop()89 void UnifiedCollector::InitWorkLoop()
90 {
91     workLoop_ = GetHiviewContext()->GetSharedWorkLoop();
92 }
93 
InitWorkPath()94 void UnifiedCollector::InitWorkPath()
95 {
96     std::string hiviewWorkDir = GetHiviewContext()->GetHiViewDirectory(HiviewContext::DirectoryType::WORK_DIRECTORY);
97     const std::string uCollectionDirName = "unified_collection";
98     std::string tempWorkPath = FileUtil::IncludeTrailingPathDelimiter(hiviewWorkDir.append(uCollectionDirName));
99     if (!FileUtil::IsDirectory(tempWorkPath) && !FileUtil::ForceCreateDirectory(tempWorkPath)) {
100         HIVIEW_LOGE("failed to create dir=%{public}s", tempWorkPath.c_str());
101         return;
102     }
103     workPath_ = tempWorkPath;
104 }
105 
RunCpuCollectionTask()106 void UnifiedCollector::RunCpuCollectionTask()
107 {
108     if (workPath_.empty()) {
109         HIVIEW_LOGE("workPath is null");
110         return;
111     }
112     auto task = std::bind(&UnifiedCollector::CpuCollectionFfrtTask, this);
113     ffrt::submit(task, {}, {}, ffrt::task_attr().name("UC_CPU").qos(ffrt::qos_default));
114 }
115 
CpuCollectionFfrtTask()116 void UnifiedCollector::CpuCollectionFfrtTask()
117 {
118     cpuCollectionTask_ = std::make_shared<CpuCollectionTask>(workPath_);
119     while (true) {
120         ffrt::this_task::sleep_for(10s); // 10s: collect period
121         cpuCollectionTask_->Collect();
122     }
123 }
124 
RunIoCollectionTask()125 void UnifiedCollector::RunIoCollectionTask()
126 {
127     if (workLoop_ == nullptr) {
128         HIVIEW_LOGE("workLoop is null");
129         return;
130     }
131     auto ioCollectionTask = std::bind(&UnifiedCollector::IoCollectionTask, this);
132     const uint64_t taskInterval = 30; // 30s
133     workLoop_->AddTimerEvent(nullptr, nullptr, ioCollectionTask, taskInterval, true);
134 }
135 
IoCollectionTask()136 void UnifiedCollector::IoCollectionTask()
137 {
138     auto ioCollector = UCollectUtil::IoCollector::Create();
139     (void)ioCollector->CollectDiskStats([](const DiskStats &stats) { return false; }, true);
140     (void)ioCollector->CollectAllProcIoStats(true);
141 }
142 
RunUCollectionStatTask()143 void UnifiedCollector::RunUCollectionStatTask()
144 {
145     if (workLoop_ == nullptr) {
146         HIVIEW_LOGE("workLoop is null");
147         return;
148     }
149     auto statTask = std::bind(&UnifiedCollector::UCollectionStatTask, this);
150     const uint64_t taskInterval = 600; // 600s
151     workLoop_->AddTimerEvent(nullptr, nullptr, statTask, taskInterval, true);
152 }
153 
UCollectionStatTask()154 void UnifiedCollector::UCollectionStatTask()
155 {
156     UnifiedCollectionStat stat;
157     stat.Report();
158 }
159 } // namespace HiviewDFX
160 } // namespace OHOS
161