관리-도구
편집 파일: hardware_statistics.py
# coding=utf-8 # # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT import os from typing import Optional, Dict, AnyStr, Union, List class NotSupported(Exception): """ Custom error to handle compatibility issues """ pass def get_proc_info_as_list_of_dicts( file_content: AnyStr ) -> List[Optional[Dict[AnyStr, AnyStr]]]: """ Parses the response of /proc files Since this file has a possibility to include multiple objects info, we need to parse all of them in the separate dicts :file_content: /proc file content. Example: processor : 0 vendor_id : AuthenticAMD processor : 1 vendor_id : AuthenticAMD_1 return: list of dicts with each node """ result = [] for info_object in file_content.split("\n\n"): temp_dict = {} if not info_object: continue for info_attr in info_object.split("\n"): values = info_attr.split(":") if len(values) == 2: temp_dict[values[0].strip()] = values[1].strip() result.append(temp_dict) return result def convert_string_kb_to_mb_value(value: str) -> float: """ Helper to get numeric value of string record and convert it to mb :value: metric value from /proc file. Example: '512 KB' return: converted value. Example: 0.5 """ return float(value.split()[0]) / 1024 def get_cpu_metrics() -> List[Optional[Dict[AnyStr, Union[AnyStr, float, int]]]]: """ Prepare list of dicts with required cpu metrics The base of this method was taken from rhn_client_tools (src/up2date_client/hardware.py) Each CPU will be represented with a dict { "model": "foo", "cache_mb": 100, "frequency_mhz": 100, "id": 0 } return: list of dicts with cpu metrics """ result_list = [] uname = os.uname().machine # We can't read the /proc/cpuinfo file or arch isn't compatible if not os.access("/proc/cpuinfo", os.R_OK): raise OSError("File for cpuinfo is restricted!") if uname not in ["x86_64", "i386"]: raise NotSupported(f"Machine arch {uname} isn't compatible!") with open("/proc/cpuinfo", "r", encoding="utf-8") as f: proc_cpuinfo = f.read() cpu_list = get_proc_info_as_list_of_dicts(proc_cpuinfo) for cpu in cpu_list: cpu_dict = { "id": int(cpu.get('processor', "0")), # Idea of set a default value from machine arch # was taken from rhn-client-tools hw getter "model": cpu.get('model name', uname), "cache_mb": convert_string_kb_to_mb_value(cpu.get('cache size', "0 KB")), "frequency_mhz": float(cpu.get('cpu MHz', "0")) } result_list.append(cpu_dict) return result_list def get_memory_metrics() -> Dict[AnyStr, float]: """ Prepare dict of memory metrics Dict will be represented as: { "ram_mb": 8.5 "swap_mb": 2.04 } """ if not os.access("/proc/meminfo", os.R_OK): raise OSError("File for meminfo is restricted!") with open("/proc/meminfo", "r", encoding="utf-8") as f: proc_meminfo = f.read() # meminfo return only one info object mem_dict = get_proc_info_as_list_of_dicts(proc_meminfo)[0] # All mem_dict values are represented as string. Example: # 1000 KB # We need to split them, convert to int and divide on 1024 # Thus, we will get MB representation of metric result = { "ram_mb": convert_string_kb_to_mb_value(mem_dict.get("MemTotal", "0 KB")), "swap_mb": convert_string_kb_to_mb_value(mem_dict.get("SwapTotal", "0 KB")), } return result