15f9996aaSopenharmony_ci#!/usr/bin/env python 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd. 45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 65f9996aaSopenharmony_ci# You may obtain a copy of the License at 75f9996aaSopenharmony_ci# 85f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 145f9996aaSopenharmony_ci# limitations under the License. 155f9996aaSopenharmony_ci 165f9996aaSopenharmony_ciimport sys 175f9996aaSopenharmony_ciimport os 185f9996aaSopenharmony_ciimport time 195f9996aaSopenharmony_ciimport platform 205f9996aaSopenharmony_cifrom datetime import datetime 215f9996aaSopenharmony_ciimport re 225f9996aaSopenharmony_cifrom pathlib import Path 235f9996aaSopenharmony_ciimport subprocess 245f9996aaSopenharmony_cifrom collections import defaultdict 255f9996aaSopenharmony_ci 265f9996aaSopenharmony_cifrom resources.global_var import ROOT_CONFIG_FILE 275f9996aaSopenharmony_cifrom log_util import LogUtil 285f9996aaSopenharmony_cifrom io_util import IoUtil 295f9996aaSopenharmony_ci 305f9996aaSopenharmony_ciGB_CONSTANT = 1024 ** 3 315f9996aaSopenharmony_ciMEM_CONSTANT = 1024 325f9996aaSopenharmony_ciRET_CONSTANT = 0 335f9996aaSopenharmony_ciMONITOR_TIME_CONSTANT = 30 345f9996aaSopenharmony_ciSNOP_TIME_CONSTANT = 5 355f9996aaSopenharmony_ci 365f9996aaSopenharmony_cimemory_info = [RET_CONSTANT] * 3 375f9996aaSopenharmony_citarget_keys = ['MemTotal', 'SwapTotal', 'MemFree'] 385f9996aaSopenharmony_cikey_indices = {key: index for index, key in enumerate(target_keys)} 395f9996aaSopenharmony_ci 405f9996aaSopenharmony_ci 415f9996aaSopenharmony_ciclass Monitor(): 425f9996aaSopenharmony_ci def __init__(self): 435f9996aaSopenharmony_ci self.now_times = [] 445f9996aaSopenharmony_ci self.usr_cpus = [] 455f9996aaSopenharmony_ci self.sys_cpus = [] 465f9996aaSopenharmony_ci self.idle_cpus = [] 475f9996aaSopenharmony_ci self.total_mems = [] 485f9996aaSopenharmony_ci self.swap_mems = [] 495f9996aaSopenharmony_ci self.free_mems = [] 505f9996aaSopenharmony_ci self.log_path = "" 515f9996aaSopenharmony_ci 525f9996aaSopenharmony_ci def collect_cpu_info(self): 535f9996aaSopenharmony_ci if platform.system() != "Linux": 545f9996aaSopenharmony_ci return RET_CONSTANT, RET_CONSTANT, RET_CONSTANT 555f9996aaSopenharmony_ci 565f9996aaSopenharmony_ci try: 575f9996aaSopenharmony_ci top_command = ["top", "-bn1"] 585f9996aaSopenharmony_ci grep_command = ["grep", "%Cpu(s)"] 595f9996aaSopenharmony_ci top_output = subprocess.check_output(top_command, universal_newlines=True) 605f9996aaSopenharmony_ci result = subprocess.check_output(grep_command, input=top_output, universal_newlines=True).strip() 615f9996aaSopenharmony_ci if result: 625f9996aaSopenharmony_ci parts = result.split() 635f9996aaSopenharmony_ci if len(parts) >= 5: 645f9996aaSopenharmony_ci usr_cpu_str = parts[1] 655f9996aaSopenharmony_ci sys_cpu_str = parts[3] 665f9996aaSopenharmony_ci idle_cpu_str = parts[7] 675f9996aaSopenharmony_ci 685f9996aaSopenharmony_ci usr_cpu_str = usr_cpu_str.split(',')[0].rstrip('%') 695f9996aaSopenharmony_ci sys_cpu_str = sys_cpu_str.split(',')[0].rstrip('%') 705f9996aaSopenharmony_ci idle_cpu_str = idle_cpu_str.split(',')[0].rstrip('%') 715f9996aaSopenharmony_ci 725f9996aaSopenharmony_ci usr_cpu = float(usr_cpu_str) if usr_cpu_str.replace('.', '', 1).isdigit() else RET_CONSTANT 735f9996aaSopenharmony_ci sys_cpu = float(sys_cpu_str) if sys_cpu_str.replace('.', '', 1).isdigit() else RET_CONSTANT 745f9996aaSopenharmony_ci idle_cpu = float(idle_cpu_str) if idle_cpu_str.replace('.', '', 1).isdigit() else RET_CONSTANT 755f9996aaSopenharmony_ci 765f9996aaSopenharmony_ci self.usr_cpu = usr_cpu 775f9996aaSopenharmony_ci self.sys_cpu = sys_cpu 785f9996aaSopenharmony_ci self.idle_cpu = idle_cpu 795f9996aaSopenharmony_ci return self.usr_cpu, self.sys_cpu, self.idle_cpu 805f9996aaSopenharmony_ci else: 815f9996aaSopenharmony_ci return RET_CONSTANT, RET_CONSTANT, RET_CONSTANT 825f9996aaSopenharmony_ci else: 835f9996aaSopenharmony_ci return RET_CONSTANT, RET_CONSTANT, RET_CONSTANT 845f9996aaSopenharmony_ci except subprocess.CalledProcessError: 855f9996aaSopenharmony_ci return RET_CONSTANT, RET_CONSTANT, RET_CONSTANT 865f9996aaSopenharmony_ci 875f9996aaSopenharmony_ci def extract_memory_value(self, line: str): 885f9996aaSopenharmony_ci match = re.search(r'\d+', line) 895f9996aaSopenharmony_ci return int(match.group()) * MEM_CONSTANT if match else RET_CONSTANT 905f9996aaSopenharmony_ci 915f9996aaSopenharmony_ci def get_ret_num(self, line: str): 925f9996aaSopenharmony_ci key = line.split(':')[0] 935f9996aaSopenharmony_ci if key in target_keys: 945f9996aaSopenharmony_ci value = self.extract_memory_value(line) 955f9996aaSopenharmony_ci memory_info[key_indices[key]] = value 965f9996aaSopenharmony_ci 975f9996aaSopenharmony_ci def get_linux_mem_info(self): 985f9996aaSopenharmony_ci try: 995f9996aaSopenharmony_ci with open('/proc/meminfo', 'r') as f: 1005f9996aaSopenharmony_ci for line in f: 1015f9996aaSopenharmony_ci self.get_ret_num(line) 1025f9996aaSopenharmony_ci return memory_info[0], memory_info[1], memory_info[2] 1035f9996aaSopenharmony_ci except FileNotFoundError: 1045f9996aaSopenharmony_ci return RET_CONSTANT, RET_CONSTANT, RET_CONSTANT 1055f9996aaSopenharmony_ci except Exception as e: 1065f9996aaSopenharmony_ci print(f"Error occurred while getting memory info: {e}") 1075f9996aaSopenharmony_ci return RET_CONSTANT, RET_CONSTANT, RET_CONSTANT 1085f9996aaSopenharmony_ci 1095f9996aaSopenharmony_ci def collect_linux_mem_info(self): 1105f9996aaSopenharmony_ci total_memory, swap_memory, free_memory = self.get_linux_mem_info() 1115f9996aaSopenharmony_ci total_mem = round(total_memory / GB_CONSTANT, 1) 1125f9996aaSopenharmony_ci free_mem = round(free_memory / GB_CONSTANT, 1) 1135f9996aaSopenharmony_ci swap_mem = round(swap_memory / GB_CONSTANT, 1) 1145f9996aaSopenharmony_ci return total_mem, free_mem, swap_mem 1155f9996aaSopenharmony_ci 1165f9996aaSopenharmony_ci def get_current_time(self): 1175f9996aaSopenharmony_ci now_time = datetime.now().strftime("%H:%M:%S") 1185f9996aaSopenharmony_ci self.now_times.append(now_time) 1195f9996aaSopenharmony_ci 1205f9996aaSopenharmony_ci def get_current_cpu(self): 1215f9996aaSopenharmony_ci usr_cpu, sys_cpu, idle_cpu = self.collect_cpu_info() 1225f9996aaSopenharmony_ci self.usr_cpus.append(usr_cpu) 1235f9996aaSopenharmony_ci self.sys_cpus.append(sys_cpu) 1245f9996aaSopenharmony_ci self.idle_cpus.append(idle_cpu) 1255f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, f"User Cpu%: {usr_cpu}%", "info") 1265f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, f"System Cpu%: {sys_cpu}%", "info") 1275f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, f"Idle CPU%: {idle_cpu}%", "info") 1285f9996aaSopenharmony_ci 1295f9996aaSopenharmony_ci def get_current_memory(self): 1305f9996aaSopenharmony_ci total_mem, free_mem, swap_mem = self.collect_linux_mem_info() 1315f9996aaSopenharmony_ci self.total_mems.append(total_mem) 1325f9996aaSopenharmony_ci self.free_mems.append(free_mem) 1335f9996aaSopenharmony_ci self.swap_mems.append(swap_mem) 1345f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, f"Total Memory: {total_mem}GB", "info") 1355f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, f"Free Memory: {free_mem}GB", "info") 1365f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, f"Swap Memory: {swap_mem}GB", "info") 1375f9996aaSopenharmony_ci 1385f9996aaSopenharmony_ci def get_log_path(self): 1395f9996aaSopenharmony_ci count = 0 1405f9996aaSopenharmony_ci config_content = IoUtil.read_json_file(ROOT_CONFIG_FILE) 1415f9996aaSopenharmony_ci while not os.path.exists(ROOT_CONFIG_FILE) or not config_content.get('out_path', None) and count <= 60: 1425f9996aaSopenharmony_ci time.sleep(SNAP_TIME_CONSTANT) 1435f9996aaSopenharmony_ci count += 1 1445f9996aaSopenharmony_ci return config_content.get('out_path', None) 1455f9996aaSopenharmony_ci 1465f9996aaSopenharmony_ci def get_disk_usage(self): 1475f9996aaSopenharmony_ci result = subprocess.run(['df', '-h'], stdout=subprocess.PIPE, text=True) 1485f9996aaSopenharmony_ci if result.returncode == 0: 1495f9996aaSopenharmony_ci lines = result.stdout.strip().split('\n')[1:] 1505f9996aaSopenharmony_ci for line in lines: 1515f9996aaSopenharmony_ci columns = line.split() 1525f9996aaSopenharmony_ci if len(columns) > 5: 1535f9996aaSopenharmony_ci filesystem, size, used, available, percent, mountpoint = columns[:6] 1545f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, 1555f9996aaSopenharmony_ci f"Filesystem: {filesystem}, " 1565f9996aaSopenharmony_ci f"Size: {size}, " 1575f9996aaSopenharmony_ci f"Used: {used}, " 1585f9996aaSopenharmony_ci f"Available: {available}, " 1595f9996aaSopenharmony_ci f"Use%: {percent}, " 1605f9996aaSopenharmony_ci f"Mounted on: {mountpoint}", 1615f9996aaSopenharmony_ci "info") 1625f9996aaSopenharmony_ci else: 1635f9996aaSopenharmony_ci LogUtil.write_log(self.log_path, f"Error running df command:{result.stderr}", "info") 1645f9996aaSopenharmony_ci 1655f9996aaSopenharmony_ci def run(self): 1665f9996aaSopenharmony_ci if platform.system() != "Linux": 1675f9996aaSopenharmony_ci return 1685f9996aaSopenharmony_ci out_path = self.get_log_path() 1695f9996aaSopenharmony_ci self.log_path = os.path.join(out_path, "build.log") 1705f9996aaSopenharmony_ci self.get_current_time() 1715f9996aaSopenharmony_ci self.get_current_cpu() 1725f9996aaSopenharmony_ci self.get_current_memory() 1735f9996aaSopenharmony_ci self.get_disk_usage() 174