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