1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci#include "platform_monitor.h" 16020a203aSopenharmony_ci 17020a203aSopenharmony_ci#include <algorithm> 18020a203aSopenharmony_ci#include <cinttypes> 19020a203aSopenharmony_ci#include <map> 20020a203aSopenharmony_ci#include <memory> 21020a203aSopenharmony_ci#include <mutex> 22020a203aSopenharmony_ci#include <vector> 23020a203aSopenharmony_ci 24020a203aSopenharmony_ci#include "hisysevent.h" 25020a203aSopenharmony_ci#include "hiview_global.h" 26020a203aSopenharmony_ci#include "hiview_logger.h" 27020a203aSopenharmony_ci#include "pipeline.h" 28020a203aSopenharmony_ci#include "sys_event_dao.h" 29020a203aSopenharmony_ci#include "sys_event.h" 30020a203aSopenharmony_ci#include "time_util.h" 31020a203aSopenharmony_ci#include "monitor_config.h" 32020a203aSopenharmony_ci 33020a203aSopenharmony_cinamespace OHOS { 34020a203aSopenharmony_cinamespace HiviewDFX { 35020a203aSopenharmony_ciDEFINE_LOG_TAG("HiView-Monitor"); 36020a203aSopenharmony_cinamespace { 37020a203aSopenharmony_ciconstexpr uint8_t SLEEP_TEN_SECONDS = 10; 38020a203aSopenharmony_ci}; 39020a203aSopenharmony_ci 40020a203aSopenharmony_civoid PlatformMonitor::AccumulateTimeInterval(uint64_t costTime, std::map<int8_t, uint32_t> &stat) 41020a203aSopenharmony_ci{ 42020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(statMutex_); 43020a203aSopenharmony_ci auto it = std::lower_bound(intervals_, intervals_ + sizeof(intervals_) / sizeof(intervals_[0]), costTime); 44020a203aSopenharmony_ci int index = it - intervals_; 45020a203aSopenharmony_ci stat[index] += 1; 46020a203aSopenharmony_ci} 47020a203aSopenharmony_ci 48020a203aSopenharmony_civoid PlatformMonitor::CollectEvent(std::shared_ptr<PipelineEvent> event) 49020a203aSopenharmony_ci{ 50020a203aSopenharmony_ci if (event == nullptr) { 51020a203aSopenharmony_ci return; 52020a203aSopenharmony_ci } 53020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(topMutex_); 54020a203aSopenharmony_ci topDomains_[event->domain_]++; 55020a203aSopenharmony_ci topEvents_[event->eventName_]++; 56020a203aSopenharmony_ci} 57020a203aSopenharmony_ci 58020a203aSopenharmony_civoid PlatformMonitor::CollectCostTime(PipelineEvent *event) 59020a203aSopenharmony_ci{ 60020a203aSopenharmony_ci // collect data after event destory 61020a203aSopenharmony_ci if (event == nullptr) { 62020a203aSopenharmony_ci return; 63020a203aSopenharmony_ci } 64020a203aSopenharmony_ci onceTotalCnt_++; 65020a203aSopenharmony_ci onceTotalRealTime_ += event->realtime_; 66020a203aSopenharmony_ci onceTotalProcTime_ += event->processTime_; 67020a203aSopenharmony_ci uint64_t waitTime = event->processTime_ > event->realtime_ ? (event->processTime_ - event->realtime_) : 0; 68020a203aSopenharmony_ci onceTotalWaitTime_ += waitTime; 69020a203aSopenharmony_ci AccumulateTimeInterval(event->realtime_, realStat_); 70020a203aSopenharmony_ci AccumulateTimeInterval(event->processTime_, processStat_); 71020a203aSopenharmony_ci AccumulateTimeInterval(waitTime, waitTimeStat_); 72020a203aSopenharmony_ci if (event->realtime_ > realTimeBenchMark_) { 73020a203aSopenharmony_ci overRealTotalCount_++; 74020a203aSopenharmony_ci } 75020a203aSopenharmony_ci if (event->processTime_ > processTimeBenchMark_) { 76020a203aSopenharmony_ci overProcessTotalCount_++; 77020a203aSopenharmony_ci } 78020a203aSopenharmony_ci finishedCount_++; 79020a203aSopenharmony_ci HIVIEW_LOGD("onceTotalCnt_=%{public}u, onceTotalRealTime_=%{public}u, onceTotalProcTime_=%{public}u, " 80020a203aSopenharmony_ci "onceTotalWaitTime_=%{public}u, overRealTotalCount_=%{public}u, overProcessTotalCount_=%{public}u, " 81020a203aSopenharmony_ci "finishedCount_=%{public}u", 82020a203aSopenharmony_ci onceTotalCnt_, onceTotalRealTime_, onceTotalProcTime_, 83020a203aSopenharmony_ci onceTotalWaitTime_, overRealTotalCount_, overProcessTotalCount_, 84020a203aSopenharmony_ci finishedCount_); 85020a203aSopenharmony_ci} 86020a203aSopenharmony_ci 87020a203aSopenharmony_civoid PlatformMonitor::CollectPerfProfiler() 88020a203aSopenharmony_ci{ 89020a203aSopenharmony_ci HIVIEW_LOGI("collect performance profiler"); 90020a203aSopenharmony_ci // collect data every 5 minute 91020a203aSopenharmony_ci // collect event max size and max count 92020a203aSopenharmony_ci if (maxTotalCount_ < SysEvent::totalCount_) { 93020a203aSopenharmony_ci maxTotalCount_.store(SysEvent::totalCount_); 94020a203aSopenharmony_ci } 95020a203aSopenharmony_ci if (maxTotalSize_ < SysEvent::totalSize_) { 96020a203aSopenharmony_ci maxTotalSize_.store(SysEvent::totalSize_); 97020a203aSopenharmony_ci } 98020a203aSopenharmony_ci // total count, total size 99020a203aSopenharmony_ci totalCount_ = SysEvent::totalCount_; 100020a203aSopenharmony_ci totalSize_ = static_cast<uint32_t>(SysEvent::totalSize_); 101020a203aSopenharmony_ci // min speed, max speed 102020a203aSopenharmony_ci uint32_t onceTotalRealTime = onceTotalRealTime_; 103020a203aSopenharmony_ci uint32_t onceTotalProcTime = onceTotalProcTime_; 104020a203aSopenharmony_ci uint32_t onceTotalWaitTime = onceTotalWaitTime_; 105020a203aSopenharmony_ci uint32_t onceTotalCnt = onceTotalCnt_; 106020a203aSopenharmony_ci onceTotalRealTime_ = 0; 107020a203aSopenharmony_ci onceTotalProcTime_ = 0; 108020a203aSopenharmony_ci onceTotalWaitTime_ = 0; 109020a203aSopenharmony_ci onceTotalCnt_ = 0; 110020a203aSopenharmony_ci if (onceTotalRealTime > 0) { 111020a203aSopenharmony_ci curRealSpeed_ = (TimeUtil::SEC_TO_MICROSEC * onceTotalCnt) / onceTotalRealTime; 112020a203aSopenharmony_ci if (minSpeed_ == 0 || (minSpeed_ > curRealSpeed_)) { 113020a203aSopenharmony_ci minSpeed_ = curRealSpeed_; 114020a203aSopenharmony_ci } 115020a203aSopenharmony_ci if (curRealSpeed_ > maxSpeed_) { 116020a203aSopenharmony_ci maxSpeed_ = curRealSpeed_; 117020a203aSopenharmony_ci } 118020a203aSopenharmony_ci } else { 119020a203aSopenharmony_ci minSpeed_ = 0; 120020a203aSopenharmony_ci maxSpeed_ = 0; 121020a203aSopenharmony_ci curRealSpeed_ = 0; 122020a203aSopenharmony_ci } 123020a203aSopenharmony_ci if (onceTotalProcTime > 0) { 124020a203aSopenharmony_ci curProcSpeed_ = (TimeUtil::SEC_TO_MICROSEC * onceTotalCnt) / onceTotalProcTime; 125020a203aSopenharmony_ci } else { 126020a203aSopenharmony_ci curProcSpeed_ = 0; 127020a203aSopenharmony_ci } 128020a203aSopenharmony_ci if (onceTotalCnt > 0) { 129020a203aSopenharmony_ci avgRealTime_ = static_cast<double>(onceTotalRealTime) / onceTotalCnt; 130020a203aSopenharmony_ci avgProcessTime_ = static_cast<double>(onceTotalProcTime) / onceTotalCnt; 131020a203aSopenharmony_ci avgWaitTime_ = static_cast<double>(onceTotalWaitTime) / onceTotalCnt; 132020a203aSopenharmony_ci } 133020a203aSopenharmony_ci HIVIEW_LOGD("maxTotalCount_=%{public}u, maxTotalSize_=%{public}u, totalCount_=%{public}u, totalSize_=%{public}u, " 134020a203aSopenharmony_ci "onceTotalRealTime=%{public}u, onceTotalProcTime=%{public}u, onceTotalWaitTime=%{public}u, " 135020a203aSopenharmony_ci "onceTotalCnt=%{public}u, minSpeed_=%{public}u, maxSpeed_=%{public}u, " 136020a203aSopenharmony_ci "curRealSpeed_=%{public}u, curProcSpeed_=%{public}u, " 137020a203aSopenharmony_ci "avgRealTime_=%{public}f, avgProcessTime_=%{public}f, avgWaitTime_=%{public}f", 138020a203aSopenharmony_ci maxTotalCount_.load(), maxTotalSize_.load(), totalCount_, totalSize_, 139020a203aSopenharmony_ci onceTotalRealTime, onceTotalProcTime, onceTotalWaitTime, 140020a203aSopenharmony_ci onceTotalCnt, minSpeed_, maxSpeed_, 141020a203aSopenharmony_ci curRealSpeed_, curProcSpeed_, 142020a203aSopenharmony_ci avgRealTime_, avgProcessTime_, avgWaitTime_); 143020a203aSopenharmony_ci} 144020a203aSopenharmony_ci 145020a203aSopenharmony_civoid PlatformMonitor::GetDomainsStat(PerfMeasure &perfMeasure) 146020a203aSopenharmony_ci{ 147020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(topMutex_); 148020a203aSopenharmony_ci for (auto it = topDomains_.begin(); it != topDomains_.end(); it++) { 149020a203aSopenharmony_ci perfMeasure.domains.emplace_back(it->first); 150020a203aSopenharmony_ci perfMeasure.domainCounts.emplace_back(it->second); 151020a203aSopenharmony_ci } 152020a203aSopenharmony_ci topDomains_.clear(); 153020a203aSopenharmony_ci topEvents_.clear(); 154020a203aSopenharmony_ci} 155020a203aSopenharmony_ci 156020a203aSopenharmony_civoid PlatformMonitor::GetCostTimeInterval(PerfMeasure &perfMeasure) 157020a203aSopenharmony_ci{ 158020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(statMutex_); 159020a203aSopenharmony_ci for (int index = 0; index <= static_cast<int>(sizeof(intervals_) / sizeof(intervals_[0])); index++) { 160020a203aSopenharmony_ci uint32_t realCount = realStat_[index]; 161020a203aSopenharmony_ci perfMeasure.realCounts.emplace_back(realCount); 162020a203aSopenharmony_ci uint32_t processCount = processStat_[index]; 163020a203aSopenharmony_ci perfMeasure.processCounts.emplace_back(processCount); 164020a203aSopenharmony_ci uint32_t waitCount = waitTimeStat_[index]; 165020a203aSopenharmony_ci perfMeasure.waitCounts.emplace_back(waitCount); 166020a203aSopenharmony_ci } 167020a203aSopenharmony_ci realStat_.clear(); 168020a203aSopenharmony_ci processStat_.clear(); 169020a203aSopenharmony_ci waitTimeStat_.clear(); 170020a203aSopenharmony_ci} 171020a203aSopenharmony_ci 172020a203aSopenharmony_civoid PlatformMonitor::CalcOverBenckMarkPct(PerfMeasure &perfMeasure) 173020a203aSopenharmony_ci{ 174020a203aSopenharmony_ci perfMeasure.finishedCount = finishedCount_; 175020a203aSopenharmony_ci perfMeasure.overRealTotalCount = overRealTotalCount_; 176020a203aSopenharmony_ci perfMeasure.overProcessTotalCount = overProcessTotalCount_; 177020a203aSopenharmony_ci finishedCount_ = 0; 178020a203aSopenharmony_ci overRealTotalCount_ = 0; 179020a203aSopenharmony_ci overProcessTotalCount_ = 0; 180020a203aSopenharmony_ci 181020a203aSopenharmony_ci if (perfMeasure.finishedCount > 0) { 182020a203aSopenharmony_ci perfMeasure.realPercent = (PCT * perfMeasure.overRealTotalCount) / perfMeasure.finishedCount; 183020a203aSopenharmony_ci } else if (perfMeasure.overRealTotalCount > 0) { 184020a203aSopenharmony_ci perfMeasure.realPercent = PCT; 185020a203aSopenharmony_ci } 186020a203aSopenharmony_ci 187020a203aSopenharmony_ci if (perfMeasure.finishedCount > 0) { 188020a203aSopenharmony_ci perfMeasure.processpercent = (PCT * perfMeasure.overProcessTotalCount) / perfMeasure.finishedCount; 189020a203aSopenharmony_ci } else if (perfMeasure.overProcessTotalCount > 0) { 190020a203aSopenharmony_ci perfMeasure.processpercent = PCT; 191020a203aSopenharmony_ci } 192020a203aSopenharmony_ci} 193020a203aSopenharmony_ci 194020a203aSopenharmony_civoid PlatformMonitor::GetMaxTotalMeasure(PerfMeasure &perfMeasure) 195020a203aSopenharmony_ci{ 196020a203aSopenharmony_ci perfMeasure.maxTotalCount = maxTotalCount_.load(); 197020a203aSopenharmony_ci maxTotalCount_.store(0); 198020a203aSopenharmony_ci 199020a203aSopenharmony_ci perfMeasure.maxTotalSize = maxTotalSize_.load(); 200020a203aSopenharmony_ci maxTotalSize_.store(0); 201020a203aSopenharmony_ci} 202020a203aSopenharmony_ci 203020a203aSopenharmony_civoid PlatformMonitor::GetBreakStat(PerfMeasure &perfMeasure) 204020a203aSopenharmony_ci{ 205020a203aSopenharmony_ci perfMeasure.totalCount = totalCount_; 206020a203aSopenharmony_ci totalCount_ = 0; 207020a203aSopenharmony_ci 208020a203aSopenharmony_ci perfMeasure.totalSize = totalSize_; 209020a203aSopenharmony_ci totalSize_ = 0; 210020a203aSopenharmony_ci 211020a203aSopenharmony_ci perfMeasure.breakCount = breakCount_; 212020a203aSopenharmony_ci breakCount_ = 0; 213020a203aSopenharmony_ci 214020a203aSopenharmony_ci perfMeasure.breakDuration = breakDuration_; 215020a203aSopenharmony_ci breakDuration_ = 0; 216020a203aSopenharmony_ci} 217020a203aSopenharmony_ci 218020a203aSopenharmony_civoid PlatformMonitor::GetMaxSpeed(PerfMeasure &perfMeasure) const 219020a203aSopenharmony_ci{ 220020a203aSopenharmony_ci perfMeasure.minSpeed = minSpeed_; 221020a203aSopenharmony_ci perfMeasure.maxSpeed = maxSpeed_; 222020a203aSopenharmony_ci} 223020a203aSopenharmony_ci 224020a203aSopenharmony_civoid PlatformMonitor::ReportProfile(const PerfMeasure& perfMeasure) 225020a203aSopenharmony_ci{ 226020a203aSopenharmony_ci int ret = HiSysEventWrite(HiSysEvent::Domain::HIVIEWDFX, "PROFILE_STAT", HiSysEvent::EventType::STATISTIC, 227020a203aSopenharmony_ci "MAX_TOTAL_COUNT", perfMeasure.maxTotalCount, "MAX_TOTAL_SIZE", perfMeasure.maxTotalSize, 228020a203aSopenharmony_ci "DOMAINS", perfMeasure.domains, "DOMAIN_DETAIL", perfMeasure.domainCounts, 229020a203aSopenharmony_ci "TOTAL_COUNT", perfMeasure.totalCount, "TOTAL_SIZE", perfMeasure.totalSize, 230020a203aSopenharmony_ci "BREAK_COUNT", perfMeasure.breakCount, "BREAK_DURATION", perfMeasure.breakDuration, 231020a203aSopenharmony_ci "MIN_SPEED", perfMeasure.minSpeed, "MAX_SPEED", perfMeasure.maxSpeed, "REAL_COUNT", perfMeasure.realCounts, 232020a203aSopenharmony_ci "PROCESS_COUNT", perfMeasure.processCounts, "WAIT_COUNT", perfMeasure.waitCounts, 233020a203aSopenharmony_ci "FINISHED_COUNT", perfMeasure.finishedCount, "OVER_REAL_COUNT", perfMeasure.overRealTotalCount, 234020a203aSopenharmony_ci "OVER_REAL_PCT", perfMeasure.realPercent, "OVER_PROC_COUNT", perfMeasure.overProcessTotalCount, 235020a203aSopenharmony_ci "OVER_PROC_PCT", perfMeasure.processpercent); 236020a203aSopenharmony_ci if (ret != SUCCESS) { 237020a203aSopenharmony_ci HIVIEW_LOGE("failed to write PROFILE_STAT event, ret is %{public}d", ret); 238020a203aSopenharmony_ci } 239020a203aSopenharmony_ci} 240020a203aSopenharmony_ci 241020a203aSopenharmony_civoid PlatformMonitor::ReportCycleProfile() 242020a203aSopenharmony_ci{ 243020a203aSopenharmony_ci HIVIEW_LOGI("report performance profile"); 244020a203aSopenharmony_ci PerfMeasure perfMeasure; 245020a203aSopenharmony_ci // report max event size and count 246020a203aSopenharmony_ci GetMaxTotalMeasure(perfMeasure); 247020a203aSopenharmony_ci 248020a203aSopenharmony_ci // report event number of each domain 249020a203aSopenharmony_ci GetDomainsStat(perfMeasure); 250020a203aSopenharmony_ci 251020a203aSopenharmony_ci // report total number of event, time of break, duration of break 252020a203aSopenharmony_ci GetBreakStat(perfMeasure); 253020a203aSopenharmony_ci 254020a203aSopenharmony_ci // report min speed, max speed 255020a203aSopenharmony_ci GetMaxSpeed(perfMeasure); 256020a203aSopenharmony_ci 257020a203aSopenharmony_ci // report real time, process time, wait time of cost time interval 258020a203aSopenharmony_ci GetCostTimeInterval(perfMeasure); 259020a203aSopenharmony_ci 260020a203aSopenharmony_ci // report percent and total number of over benchmark 261020a203aSopenharmony_ci CalcOverBenckMarkPct(perfMeasure); 262020a203aSopenharmony_ci 263020a203aSopenharmony_ci ReportProfile(perfMeasure); 264020a203aSopenharmony_ci HIVIEW_LOGI("report performance profile have done"); 265020a203aSopenharmony_ci} 266020a203aSopenharmony_ci 267020a203aSopenharmony_civoid PlatformMonitor::GetTopDomains(std::vector<std::string> &domains, std::vector<uint32_t> &counts) 268020a203aSopenharmony_ci{ 269020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(topMutex_); 270020a203aSopenharmony_ci uint8_t topN = 3; // top n 271020a203aSopenharmony_ci if (topDomains_.size() <= topN) { 272020a203aSopenharmony_ci for (auto it = topDomains_.begin(); it != topDomains_.end(); it++) { 273020a203aSopenharmony_ci domains.emplace_back(it->first); 274020a203aSopenharmony_ci counts.emplace_back(it->second); 275020a203aSopenharmony_ci } 276020a203aSopenharmony_ci return; 277020a203aSopenharmony_ci } 278020a203aSopenharmony_ci 279020a203aSopenharmony_ci for (auto it = topDomains_.begin(); it != topDomains_.end(); it++) { 280020a203aSopenharmony_ci counts.emplace_back(it->second); 281020a203aSopenharmony_ci } 282020a203aSopenharmony_ci std::sort(counts.begin(), counts.end(), std::greater<int>()); 283020a203aSopenharmony_ci counts.resize(topN); 284020a203aSopenharmony_ci for (auto it = topDomains_.begin(); it != topDomains_.end(); it++) { 285020a203aSopenharmony_ci if (domains.size() >= topN) { 286020a203aSopenharmony_ci break; 287020a203aSopenharmony_ci } 288020a203aSopenharmony_ci if (std::find(counts.begin(), counts.end(), it->second) != counts.end()) { 289020a203aSopenharmony_ci domains.emplace_back(it->first); 290020a203aSopenharmony_ci } 291020a203aSopenharmony_ci } 292020a203aSopenharmony_ci return; 293020a203aSopenharmony_ci} 294020a203aSopenharmony_ci 295020a203aSopenharmony_civoid PlatformMonitor::GetTopEvents(std::vector<std::string> &events, std::vector<uint32_t> &counts) 296020a203aSopenharmony_ci{ 297020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(topMutex_); 298020a203aSopenharmony_ci uint8_t topN = 3; // top n 299020a203aSopenharmony_ci if (topEvents_.size() <= topN) { 300020a203aSopenharmony_ci for (auto it = topEvents_.begin(); it != topEvents_.end(); it++) { 301020a203aSopenharmony_ci events.emplace_back(it->first); 302020a203aSopenharmony_ci counts.emplace_back(it->second); 303020a203aSopenharmony_ci } 304020a203aSopenharmony_ci return; 305020a203aSopenharmony_ci } 306020a203aSopenharmony_ci 307020a203aSopenharmony_ci for (auto it = topEvents_.begin(); it != topEvents_.end(); it++) { 308020a203aSopenharmony_ci counts.emplace_back(it->second); 309020a203aSopenharmony_ci } 310020a203aSopenharmony_ci std::sort(counts.begin(), counts.end(), std::greater<int>()); 311020a203aSopenharmony_ci counts.resize(topN); 312020a203aSopenharmony_ci for (auto it = topEvents_.begin(); it != topEvents_.end(); it++) { 313020a203aSopenharmony_ci if (events.size() >= topN) { 314020a203aSopenharmony_ci break; 315020a203aSopenharmony_ci } 316020a203aSopenharmony_ci if (std::find(counts.begin(), counts.end(), it->second) != counts.end()) { 317020a203aSopenharmony_ci events.emplace_back(it->first); 318020a203aSopenharmony_ci } 319020a203aSopenharmony_ci } 320020a203aSopenharmony_ci return; 321020a203aSopenharmony_ci} 322020a203aSopenharmony_ci 323020a203aSopenharmony_civoid PlatformMonitor::ReportBreakProfile() 324020a203aSopenharmony_ci{ 325020a203aSopenharmony_ci // report current event size and count 326020a203aSopenharmony_ci uint32_t curTotalCount_ = SysEvent::totalCount_; 327020a203aSopenharmony_ci uint32_t curTotalSize_ = static_cast<uint32_t>(SysEvent::totalSize_); 328020a203aSopenharmony_ci 329020a203aSopenharmony_ci // report current speed 330020a203aSopenharmony_ci uint32_t curRealSpeed = curRealSpeed_; 331020a203aSopenharmony_ci uint32_t curProcessSpeed = curProcSpeed_; 332020a203aSopenharmony_ci 333020a203aSopenharmony_ci // report average real time, process time, wait time 334020a203aSopenharmony_ci double avgRealTime = avgRealTime_; 335020a203aSopenharmony_ci double avgProcessTime = avgProcessTime_; 336020a203aSopenharmony_ci double avgWaitTime = avgWaitTime_; 337020a203aSopenharmony_ci 338020a203aSopenharmony_ci // report topk cost time event 339020a203aSopenharmony_ci std::vector<std::string> events; 340020a203aSopenharmony_ci std::vector<uint32_t> eventCounts; 341020a203aSopenharmony_ci GetTopEvents(events, eventCounts); 342020a203aSopenharmony_ci 343020a203aSopenharmony_ci // report topk event and count 344020a203aSopenharmony_ci std::vector<std::string> domains; 345020a203aSopenharmony_ci std::vector<uint32_t> domainCounts; 346020a203aSopenharmony_ci GetTopDomains(domains, domainCounts); 347020a203aSopenharmony_ci int ret = HiSysEventWrite(HiSysEvent::Domain::HIVIEWDFX, "BREAK", HiSysEvent::EventType::BEHAVIOR, 348020a203aSopenharmony_ci "TOTAL_COUNT", curTotalCount_, "TOTAL_SIZE", curTotalSize_, "REAL_SPEED", curRealSpeed, 349020a203aSopenharmony_ci "PROC_SPEED", curProcessSpeed, "AVG_REAL_TIME", avgRealTime, "AVG_PROC_TIME", avgProcessTime, 350020a203aSopenharmony_ci "AVG_WAIT_TIME", avgWaitTime, "TOP_EVENT", events, "TOP_EVENT_COUNT", eventCounts, "TOP_DOMAIN", domains, 351020a203aSopenharmony_ci "TOP_DOMAIN_COUNT", domainCounts); 352020a203aSopenharmony_ci if (ret != SUCCESS) { 353020a203aSopenharmony_ci HIVIEW_LOGE("failed to write BREAK event, ret is %{public}d", ret); 354020a203aSopenharmony_ci } 355020a203aSopenharmony_ci} 356020a203aSopenharmony_ci 357020a203aSopenharmony_civoid PlatformMonitor::ReportRecoverProfile() 358020a203aSopenharmony_ci{ 359020a203aSopenharmony_ci // report break duration when recovery 360020a203aSopenharmony_ci int64_t duration = static_cast<int64_t>(recoverTimestamp_ - breakTimestamp_); 361020a203aSopenharmony_ci int ret = HiSysEventWrite(HiSysEvent::Domain::HIVIEWDFX, "RECOVER", HiSysEvent::EventType::BEHAVIOR, 362020a203aSopenharmony_ci "DURATION", duration); 363020a203aSopenharmony_ci if (ret != SUCCESS) { 364020a203aSopenharmony_ci HIVIEW_LOGE("failed to write RECOVER event, ret is %{public}d", ret); 365020a203aSopenharmony_ci } 366020a203aSopenharmony_ci} 367020a203aSopenharmony_ci 368020a203aSopenharmony_civoid PlatformMonitor::Breaking() 369020a203aSopenharmony_ci{ 370020a203aSopenharmony_ci // collect break count and duration every break 371020a203aSopenharmony_ci if (SysEvent::totalSize_ <= totalSizeBenchMark_) { 372020a203aSopenharmony_ci return; 373020a203aSopenharmony_ci } 374020a203aSopenharmony_ci 375020a203aSopenharmony_ci HIVIEW_LOGE("break as event reach critical size %{public}" PRId64, SysEvent::totalSize_.load()); 376020a203aSopenharmony_ci breakTimestamp_ = TimeUtil::GenerateTimestamp(); 377020a203aSopenharmony_ci ReportBreakProfile(); 378020a203aSopenharmony_ci int64_t recoveryBenchMark = static_cast<int64_t>(totalSizeBenchMark_ * 0.8); // 0.8 of total size will recover 379020a203aSopenharmony_ci while (true) { 380020a203aSopenharmony_ci if (SysEvent::totalSize_ <= recoveryBenchMark) { 381020a203aSopenharmony_ci break; 382020a203aSopenharmony_ci } 383020a203aSopenharmony_ci TimeUtil::Sleep(SLEEP_TEN_SECONDS); 384020a203aSopenharmony_ci } 385020a203aSopenharmony_ci breakCount_++; 386020a203aSopenharmony_ci recoverTimestamp_ = TimeUtil::GenerateTimestamp(); 387020a203aSopenharmony_ci breakDuration_ += recoverTimestamp_ - breakTimestamp_; 388020a203aSopenharmony_ci HIVIEW_LOGW("recover after break duration %{public}" PRIu64, breakDuration_); 389020a203aSopenharmony_ci ReportRecoverProfile(); 390020a203aSopenharmony_ci} 391020a203aSopenharmony_ci 392020a203aSopenharmony_civoid PlatformMonitor::InitData() 393020a203aSopenharmony_ci{ 394020a203aSopenharmony_ci MonitorConfig monitorConfig("/system/etc/hiview/monitor.cfg"); 395020a203aSopenharmony_ci if (!monitorConfig.Parse()) { 396020a203aSopenharmony_ci return; 397020a203aSopenharmony_ci } 398020a203aSopenharmony_ci 399020a203aSopenharmony_ci monitorConfig.ReadParam("collectPeriod", collectPeriod_); 400020a203aSopenharmony_ci monitorConfig.ReadParam("reportPeriod", reportPeriod_); 401020a203aSopenharmony_ci monitorConfig.ReadParam("totalSizeBenchMark", totalSizeBenchMark_); 402020a203aSopenharmony_ci monitorConfig.ReadParam("realTimeBenchMark", realTimeBenchMark_); 403020a203aSopenharmony_ci monitorConfig.ReadParam("processTimeBenchMark", processTimeBenchMark_); 404020a203aSopenharmony_ci} 405020a203aSopenharmony_ci 406020a203aSopenharmony_civoid PlatformMonitor::StartMonitor(std::shared_ptr<EventLoop> looper) 407020a203aSopenharmony_ci{ 408020a203aSopenharmony_ci if (looper == nullptr) { 409020a203aSopenharmony_ci HIVIEW_LOGE("can not get share looper"); 410020a203aSopenharmony_ci return; 411020a203aSopenharmony_ci } 412020a203aSopenharmony_ci InitData(); 413020a203aSopenharmony_ci 414020a203aSopenharmony_ci looper_ = looper; 415020a203aSopenharmony_ci 416020a203aSopenharmony_ci auto collectTask = std::bind(&PlatformMonitor::CollectPerfProfiler, this); 417020a203aSopenharmony_ci looper_->AddTimerEvent(nullptr, nullptr, collectTask, collectPeriod_, true); 418020a203aSopenharmony_ci auto reportTask = std::bind(&PlatformMonitor::ReportCycleProfile, this); 419020a203aSopenharmony_ci looper_->AddTimerEvent(nullptr, nullptr, reportTask, reportPeriod_, true); 420020a203aSopenharmony_ci} 421020a203aSopenharmony_ci} // namespace HiviewDFX 422020a203aSopenharmony_ci} // namespace OHOS