macpm
Advanced tools
| Metadata-Version: 2.1 | ||
| Name: macpm | ||
| Version: 0.14 | ||
| Version: 0.15 | ||
| Summary: Performance monitoring CLI tool for Apple Silicon | ||
@@ -5,0 +5,0 @@ Home-page: https://github.com/visualcjy/macpm |
+534
-491
| import argparse | ||
| import humanize | ||
| from collections import deque | ||
| from blessed import Terminal | ||
| from dashing import VSplit, HSplit, HGauge, HChart, VGauge, HBrailleChart, HBrailleFilledChart | ||
@@ -11,4 +10,5 @@ import os, time | ||
| import plistlib | ||
| import curses | ||
| version = 'macpm v0.14' | ||
| version = 'macpm v0.15' | ||
| parser = argparse.ArgumentParser( | ||
@@ -333,527 +333,547 @@ description=f'{version}: Performance monitoring CLI tool for Apple Silicon') | ||
| def main(): | ||
| print("\nmacpm - Performance monitoring CLI tool for Apple Silicon") | ||
| print("You can update macpm by running `pip install macpm --upgrade`") | ||
| print("Get help at `https://github.com/visualcjy/macpm`") | ||
| print("P.S. You are recommended to run macpm with `sudo macpm`\n") | ||
| print("\n[1/3] Loading macpm\n") | ||
| print("\033[?25l") | ||
| global powermetrics_process | ||
| cpu1_gauge = HGauge(title="E-CPU Usage", val=0, color=args.color) | ||
| cpu2_gauge = HGauge(title="P-CPU Usage", val=0, color=args.color) | ||
| gpu_gauge = HGauge(title="GPU Usage", val=0, color=args.color) | ||
| ane_gauge = HGauge(title="ANE", val=0, color=args.color) | ||
| gpu_ane_gauges = [gpu_gauge, ane_gauge] | ||
| class DefaultView(): | ||
| def __init__(self,soc_info_dict,args): | ||
| self.cpu_peak_power = 0 | ||
| self.gpu_peak_power = 0 | ||
| self.package_peak_power = 0 | ||
| self.disk_read_iops_peak = 0 | ||
| self.disk_write_iops_peak = 0 | ||
| self.disk_read_bps_peak = 0 | ||
| self.disk_write_bps_peak = 0 | ||
| self.network_in_bps_peak = 0 | ||
| self.network_out_bps_peak = 0 | ||
| self.construct(soc_info_dict,args) | ||
| def construct(self,soc_info_dict,args): | ||
| self.cpu1_gauge = HGauge(title="E-CPU Usage", val=0, color=args.color) | ||
| self.cpu2_gauge = HGauge(title="P-CPU Usage", val=0, color=args.color) | ||
| self.gpu_gauge = HGauge(title="GPU Usage", val=0, color=args.color) | ||
| self.ane_gauge = HGauge(title="ANE", val=0, color=args.color) | ||
| self.gpu_ane_gauges = [self.gpu_gauge, self.ane_gauge] | ||
| self.e_core_count = soc_info_dict["e_core_count"] | ||
| self.e_core_gauges = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(self.e_core_count)] | ||
| self.p_core_count = soc_info_dict["p_core_count"] | ||
| self.p_core_gauges = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(min(self.p_core_count, 8))] | ||
| self.p_core_split = [HSplit( | ||
| *self.p_core_gauges, | ||
| )] | ||
| if self.p_core_count > 8: | ||
| self.p_core_gauges_ext = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(self.p_core_count - 8)] | ||
| self.p_core_split.append(HSplit( | ||
| *self.p_core_gauges_ext, | ||
| )) | ||
| self.processor_gauges = [self.cpu1_gauge, | ||
| HSplit(*self.e_core_gauges), | ||
| self.cpu2_gauge, | ||
| *self.p_core_split, | ||
| *self.gpu_ane_gauges | ||
| ] if args.show_cores else [ | ||
| HSplit(self.cpu1_gauge, self.cpu2_gauge), | ||
| HSplit(*self.gpu_ane_gauges) | ||
| ] | ||
| self.processor_split = VSplit( | ||
| *self.processor_gauges, | ||
| title="Processor Utilization", | ||
| border_color=args.color, | ||
| ) | ||
| soc_info_dict = get_soc_info() | ||
| e_core_count = soc_info_dict["e_core_count"] | ||
| e_core_gauges = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(e_core_count)] | ||
| p_core_count = soc_info_dict["p_core_count"] | ||
| p_core_gauges = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(min(p_core_count, 8))] | ||
| p_core_split = [HSplit( | ||
| *p_core_gauges, | ||
| )] | ||
| if p_core_count > 8: | ||
| p_core_gauges_ext = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(p_core_count - 8)] | ||
| p_core_split.append(HSplit( | ||
| *p_core_gauges_ext, | ||
| )) | ||
| processor_gauges = [cpu1_gauge, | ||
| HSplit(*e_core_gauges), | ||
| cpu2_gauge, | ||
| *p_core_split, | ||
| *gpu_ane_gauges | ||
| ] if args.show_cores else [ | ||
| HSplit(cpu1_gauge, cpu2_gauge), | ||
| HSplit(*gpu_ane_gauges) | ||
| ] | ||
| processor_split = VSplit( | ||
| *processor_gauges, | ||
| title="Processor Utilization", | ||
| border_color=args.color, | ||
| ) | ||
| ram_gauge = HGauge(title="RAM Usage", val=0, color=args.color) | ||
| """ | ||
| ecpu_bw_gauge = HGauge(title="E-CPU B/W", val=50, color=args.color) | ||
| pcpu_bw_gauge = HGauge(title="P-CPU B/W", val=50, color=args.color) | ||
| gpu_bw_gauge = HGauge(title="GPU B/W", val=50, color=args.color) | ||
| media_bw_gauge = HGauge(title="Media B/W", val=50, color=args.color) | ||
| bw_gauges = [HSplit( | ||
| ecpu_bw_gauge, | ||
| pcpu_bw_gauge, | ||
| ), | ||
| HSplit( | ||
| gpu_bw_gauge, | ||
| media_bw_gauge, | ||
| )] if args.show_cores else [ | ||
| HSplit( | ||
| self.ram_gauge = HGauge(title="RAM Usage", val=0, color=args.color) | ||
| """ | ||
| ecpu_bw_gauge = HGauge(title="E-CPU B/W", val=50, color=args.color) | ||
| pcpu_bw_gauge = HGauge(title="P-CPU B/W", val=50, color=args.color) | ||
| gpu_bw_gauge = HGauge(title="GPU B/W", val=50, color=args.color) | ||
| media_bw_gauge = HGauge(title="Media B/W", val=50, color=args.color) | ||
| bw_gauges = [HSplit( | ||
| ecpu_bw_gauge, | ||
| pcpu_bw_gauge, | ||
| gpu_bw_gauge, | ||
| media_bw_gauge, | ||
| )] | ||
| """ | ||
| memory_gauges = VSplit( | ||
| ram_gauge, | ||
| #*bw_gauges, | ||
| border_color=args.color, | ||
| title="Memory" | ||
| ) | ||
| ), | ||
| HSplit( | ||
| gpu_bw_gauge, | ||
| media_bw_gauge, | ||
| )] if args.show_cores else [ | ||
| HSplit( | ||
| ecpu_bw_gauge, | ||
| pcpu_bw_gauge, | ||
| gpu_bw_gauge, | ||
| media_bw_gauge, | ||
| )] | ||
| """ | ||
| self.memory_gauges = VSplit( | ||
| self.ram_gauge, | ||
| #*bw_gauges, | ||
| border_color=args.color, | ||
| title="Memory" | ||
| ) | ||
| cpu_power_chart = HChart(title="CPU Power", color=args.color) | ||
| gpu_power_chart = HChart(title="GPU Power", color=args.color) | ||
| power_charts = VSplit( | ||
| cpu_power_chart, | ||
| gpu_power_chart, | ||
| title="Power Chart", | ||
| border_color=args.color, | ||
| ) if args.show_cores else HSplit( | ||
| cpu_power_chart, | ||
| gpu_power_chart, | ||
| title="Power Chart", | ||
| border_color=args.color, | ||
| ) | ||
| self.cpu_power_chart = HChart(title="CPU Power", color=args.color) | ||
| self.gpu_power_chart = HChart(title="GPU Power", color=args.color) | ||
| self.power_charts = VSplit( | ||
| self.cpu_power_chart, | ||
| self.gpu_power_chart, | ||
| title="Power Chart", | ||
| border_color=args.color, | ||
| ) if args.show_cores else HSplit( | ||
| self.cpu_power_chart, | ||
| self.gpu_power_chart, | ||
| title="Power Chart", | ||
| border_color=args.color, | ||
| ) | ||
| disk_read_iops_charts = HChart(title="read iops", color=args.color) | ||
| disk_write_iops_charts = HChart(title="write iops", color=args.color) | ||
| disk_read_bps_charts = HChart(title="read Bps", color=args.color) | ||
| disk_write_bps_charts = HChart(title="write Bps", color=args.color) | ||
| network_in_bps_charts = HChart(title="in Bps", color=args.color) | ||
| network_out_bps_charts = HChart(title="out Bps", color=args.color) | ||
| disk_io_charts = HSplit( | ||
| VSplit(disk_read_iops_charts, | ||
| disk_write_iops_charts,), | ||
| VSplit(disk_read_bps_charts, | ||
| disk_write_bps_charts,), | ||
| title="Disk IO", | ||
| color=args.color, | ||
| border_color=args.color) | ||
| network_io_charts = HSplit( | ||
| network_in_bps_charts, | ||
| network_out_bps_charts, | ||
| title="Network IO", | ||
| color=args.color, | ||
| border_color=args.color) | ||
| ui = HSplit( | ||
| processor_split, | ||
| VSplit( | ||
| memory_gauges, | ||
| power_charts, | ||
| disk_io_charts, | ||
| network_io_charts, | ||
| self.disk_read_iops_charts = HChart(title="read iops", color=args.color) | ||
| self.disk_write_iops_charts = HChart(title="write iops", color=args.color) | ||
| self.disk_read_bps_charts = HChart(title="read Bps", color=args.color) | ||
| self.disk_write_bps_charts = HChart(title="write Bps", color=args.color) | ||
| self.network_in_bps_charts = HChart(title="in Bps", color=args.color) | ||
| self.network_out_bps_charts = HChart(title="out Bps", color=args.color) | ||
| self.disk_io_charts = HSplit( | ||
| VSplit(self.disk_read_iops_charts, | ||
| self.disk_write_iops_charts,), | ||
| VSplit(self.disk_read_bps_charts, | ||
| self.disk_write_bps_charts,), | ||
| title="Disk IO", | ||
| color=args.color, | ||
| border_color=args.color) | ||
| self.network_io_charts = HSplit( | ||
| self.network_in_bps_charts, | ||
| self.network_out_bps_charts, | ||
| title="Network IO", | ||
| color=args.color, | ||
| border_color=args.color) | ||
| self.ui = HSplit( | ||
| self.processor_split, | ||
| VSplit( | ||
| self.memory_gauges, | ||
| self.power_charts, | ||
| self.disk_io_charts, | ||
| self.network_io_charts, | ||
| ) | ||
| ) if args.show_cores else VSplit( | ||
| self.processor_split, | ||
| self.memory_gauges, | ||
| self.power_charts, | ||
| self.disk_io_charts, | ||
| self.network_io_charts, | ||
| ) | ||
| ) if args.show_cores else VSplit( | ||
| processor_split, | ||
| memory_gauges, | ||
| power_charts, | ||
| disk_io_charts, | ||
| network_io_charts, | ||
| ) | ||
| """ | ||
| ui.title = "".join([ | ||
| version, | ||
| " (Press q or ESC to stop)" | ||
| ]) | ||
| ui.border_color = args.color | ||
| """ | ||
| usage_gauges = ui.items[0] | ||
| #bw_gauges = memory_gauges.items[1] | ||
| """ | ||
| ui.title = "".join([ | ||
| version, | ||
| " (Press q or ESC to stop)" | ||
| ]) | ||
| ui.border_color = args.color | ||
| """ | ||
| self.usage_gauges = self.ui.items[0] | ||
| #bw_gauges = memory_gauges.items[1] | ||
| cpu_title = "".join([ | ||
| soc_info_dict["name"], | ||
| " (cores: ", | ||
| str(soc_info_dict["e_core_count"]), | ||
| "E+", | ||
| str(soc_info_dict["p_core_count"]), | ||
| "P+", | ||
| str(soc_info_dict["gpu_core_count"]), | ||
| "GPU)" | ||
| ]) | ||
| usage_gauges.title = cpu_title | ||
| cpu_max_power = soc_info_dict["cpu_max_power"] | ||
| gpu_max_power = soc_info_dict["gpu_max_power"] | ||
| ane_max_power = 16.0 | ||
| """max_cpu_bw = soc_info_dict["cpu_max_bw"] | ||
| max_gpu_bw = soc_info_dict["gpu_max_bw"] | ||
| max_media_bw = 7.0""" | ||
| cpu_title = "".join([ | ||
| soc_info_dict["name"], | ||
| " (cores: ", | ||
| str(soc_info_dict["e_core_count"]), | ||
| "E+", | ||
| str(soc_info_dict["p_core_count"]), | ||
| "P+", | ||
| str(soc_info_dict["gpu_core_count"]), | ||
| "GPU)" | ||
| ]) | ||
| self.usage_gauges.title = cpu_title | ||
| self.cpu_max_power = soc_info_dict["cpu_max_power"] | ||
| self.gpu_max_power = soc_info_dict["gpu_max_power"] | ||
| self.ane_max_power = 16.0 | ||
| """max_cpu_bw = soc_info_dict["cpu_max_bw"] | ||
| max_gpu_bw = soc_info_dict["gpu_max_bw"] | ||
| max_media_bw = 7.0""" | ||
| cpu_peak_power = 0 | ||
| gpu_peak_power = 0 | ||
| package_peak_power = 0 | ||
| disk_read_iops_peak = 0 | ||
| disk_write_iops_peak = 0 | ||
| disk_read_bps_peak = 0 | ||
| disk_write_bps_peak = 0 | ||
| network_in_bps_peak = 0 | ||
| network_out_bps_peak = 0 | ||
| self.avg_package_power_list = deque([], maxlen=int(args.avg / args.interval)) | ||
| self.avg_cpu_power_list = deque([], maxlen=int(args.avg / args.interval)) | ||
| self.avg_gpu_power_list = deque([], maxlen=int(args.avg / args.interval)) | ||
| print("\n[2/3] Starting powermetrics process\n") | ||
| def display(self,powermetrics_parse,args): | ||
| if args.color != self.gpu_gauge.color: | ||
| clear_console() | ||
| self.gpu_gauge.color = args.color | ||
| self.ane_gauge.color = args.color | ||
| self.cpu1_gauge.color = args.color | ||
| self.cpu2_gauge.color = args.color | ||
| self.power_charts.color = args.color | ||
| self.power_charts.border_color = args.color | ||
| self.processor_split.border_color = args.color | ||
| self.ram_gauge.color = args.color | ||
| self.memory_gauges.border_color = args.color | ||
| self.cpu_power_chart.color = args.color | ||
| self.gpu_power_chart.color = args.color | ||
| #self.cpu_power_chart.border_color = args.color | ||
| self.disk_io_charts.color = args.color | ||
| self.disk_io_charts.border_color = args.color | ||
| self.network_io_charts.color = args.color | ||
| self.network_io_charts.border_color = args.color | ||
| self.disk_read_iops_charts.color = args.color | ||
| self.disk_write_iops_charts.color = args.color | ||
| self.disk_read_bps_charts.color = args.color | ||
| self.disk_write_bps_charts.color = args.color | ||
| self.network_in_bps_charts.color = args.color | ||
| self.network_out_bps_charts.color = args.color | ||
| for i in range(len(self.e_core_gauges)): | ||
| self.e_core_gauges[i].color = args.color | ||
| self.e_core_gauges[i].border_color = args.color | ||
| for i in range(len(self.p_core_gauges)): | ||
| self.p_core_gauges[i].color = args.color | ||
| self.p_core_gauges[i].border_color = args.color | ||
| for i in range(len(self.p_core_gauges_ext)): | ||
| self.p_core_gauges_ext[i].color = args.color | ||
| self.p_core_gauges_ext[i].border_color = args.color | ||
| thermal_pressure = parse_thermal_pressure(powermetrics_parse) | ||
| cpu_metrics_dict = parse_cpu_metrics(powermetrics_parse) | ||
| gpu_metrics_dict = parse_gpu_metrics(powermetrics_parse) | ||
| disk_metrics_dict = parse_disk_metrics(powermetrics_parse) | ||
| network_metrics_dict = parse_network_metrics(powermetrics_parse) | ||
| #bandwidth_metrics = parse_bandwidth_metrics(powermetrics_parse) | ||
| bandwidth_metrics = None | ||
| timestamp = powermetrics_parse["timestamp"] | ||
| if timestamp : | ||
| if thermal_pressure == "Nominal": | ||
| thermal_throttle = "no" | ||
| else: | ||
| thermal_throttle = "yes" | ||
| command = " ".join([ | ||
| "sudo nice -n", | ||
| str(10), | ||
| "powermetrics", | ||
| "--samplers cpu_power,gpu_power,thermal,network,disk", | ||
| "-f plist", | ||
| "-i", | ||
| str(args.interval * 1000) | ||
| ]) | ||
| process = subprocess.Popen(command.split(" "), stdin=PIPE, stdout=PIPE) | ||
| powermetrics_process = process | ||
| """e_cpu_usage = 0 | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["e_core"]: | ||
| e_cpu_usage += cpu_metrics_dict["E-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| e_cpu_usage = (e_cpu_usage / core_count) if core_count > 0 else 0""" | ||
| self.cpu1_gauge.title = "".join([ | ||
| "E-CPU Usage: ", | ||
| str(cpu_metrics_dict["E-Cluster_active"]), | ||
| "% @ ", | ||
| str(cpu_metrics_dict["E-Cluster_freq_Mhz"]), | ||
| " MHz" | ||
| ]) | ||
| self.cpu1_gauge.value = cpu_metrics_dict["E-Cluster_active"] | ||
| print("\n[3/3] Waiting for first reading...\n") | ||
| """ | ||
| def get_reading(wait=0.1): | ||
| ready = parse_powermetrics(timecode=timecode) | ||
| while not ready: | ||
| time.sleep(wait) | ||
| ready = parse_powermetrics(timecode=timecode) | ||
| return ready | ||
| """p_cpu_usage = 0 | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["p_core"]: | ||
| p_cpu_usage += cpu_metrics_dict["P-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| p_cpu_usage = (p_cpu_usage / core_count) if core_count > 0 else 0""" | ||
| self.cpu2_gauge.title = "".join([ | ||
| "P-CPU Usage: ", | ||
| str(cpu_metrics_dict["P-Cluster_active"]), | ||
| "% @ ", | ||
| str(cpu_metrics_dict["P-Cluster_freq_Mhz"]), | ||
| " MHz" | ||
| ]) | ||
| self.cpu2_gauge.value = cpu_metrics_dict["P-Cluster_active"] | ||
| ready = get_reading() | ||
| last_timestamp = ready[-1] | ||
| """ | ||
| def get_avg(inlist): | ||
| avg = sum(inlist) / len(inlist) | ||
| return avg | ||
| avg_package_power_list = deque([], maxlen=int(args.avg / args.interval)) | ||
| avg_cpu_power_list = deque([], maxlen=int(args.avg / args.interval)) | ||
| avg_gpu_power_list = deque([], maxlen=int(args.avg / args.interval)) | ||
| clear_console() | ||
| term = Terminal() | ||
| try: | ||
| data = b'' | ||
| while True: | ||
| output = process.stdout.readline() | ||
| #output, stderr = process.communicate() | ||
| if process.poll() is not None: | ||
| break | ||
| data = data + output | ||
| str_output = output.decode() | ||
| if str_output.startswith('</plist>'): | ||
| data = data.replace(b'\x00',b'') | ||
| powermetrics_parse = plistlib.loads(data) | ||
| thermal_pressure = parse_thermal_pressure(powermetrics_parse) | ||
| cpu_metrics_dict = parse_cpu_metrics(powermetrics_parse) | ||
| gpu_metrics_dict = parse_gpu_metrics(powermetrics_parse) | ||
| disk_metrics_dict = parse_disk_metrics(powermetrics_parse) | ||
| network_metrics_dict = parse_network_metrics(powermetrics_parse) | ||
| #bandwidth_metrics = parse_bandwidth_metrics(powermetrics_parse) | ||
| bandwidth_metrics = None | ||
| timestamp = powermetrics_parse["timestamp"] | ||
| data = b'' | ||
| if timestamp : | ||
| if thermal_pressure == "Nominal": | ||
| thermal_throttle = "no" | ||
| else: | ||
| thermal_throttle = "yes" | ||
| """e_cpu_usage = 0 | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["e_core"]: | ||
| e_cpu_usage += cpu_metrics_dict["E-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| e_cpu_usage = (e_cpu_usage / core_count) if core_count > 0 else 0""" | ||
| cpu1_gauge.title = "".join([ | ||
| "E-CPU Usage: ", | ||
| str(cpu_metrics_dict["E-Cluster_active"]), | ||
| "% @ ", | ||
| str(cpu_metrics_dict["E-Cluster_freq_Mhz"]), | ||
| " MHz" | ||
| if args.show_cores: | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["e_core"]: | ||
| self.e_core_gauges[core_count % 4].title = "".join([ | ||
| "Core-" + str(i + 1) + " ", | ||
| str(cpu_metrics_dict["E-Cluster" + str(i) + "_active"]), | ||
| "%", | ||
| ]) | ||
| cpu1_gauge.value = cpu_metrics_dict["E-Cluster_active"] | ||
| """p_cpu_usage = 0 | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["p_core"]: | ||
| p_cpu_usage += cpu_metrics_dict["P-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| p_cpu_usage = (p_cpu_usage / core_count) if core_count > 0 else 0""" | ||
| cpu2_gauge.title = "".join([ | ||
| "P-CPU Usage: ", | ||
| str(cpu_metrics_dict["P-Cluster_active"]), | ||
| "% @ ", | ||
| str(cpu_metrics_dict["P-Cluster_freq_Mhz"]), | ||
| " MHz" | ||
| self.e_core_gauges[core_count % 4].value = cpu_metrics_dict["E-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["p_core"]: | ||
| core_gauges =self.p_core_gauges if core_count < 8 else self.p_core_gauges_ext | ||
| core_gauges[core_count % 8].title = "".join([ | ||
| ("Core-" if self.p_core_count < 6 else 'C-') + str(i + 1) + " ", | ||
| str(cpu_metrics_dict["P-Cluster" + str(i) + "_active"]), | ||
| "%", | ||
| ]) | ||
| cpu2_gauge.value = cpu_metrics_dict["P-Cluster_active"] | ||
| core_gauges[core_count % 8].value = cpu_metrics_dict["P-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| if args.show_cores: | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["e_core"]: | ||
| e_core_gauges[core_count % 4].title = "".join([ | ||
| "Core-" + str(i + 1) + " ", | ||
| str(cpu_metrics_dict["E-Cluster" + str(i) + "_active"]), | ||
| "%", | ||
| ]) | ||
| e_core_gauges[core_count % 4].value = cpu_metrics_dict["E-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| core_count = 0 | ||
| for i in cpu_metrics_dict["p_core"]: | ||
| core_gauges = p_core_gauges if core_count < 8 else p_core_gauges_ext | ||
| core_gauges[core_count % 8].title = "".join([ | ||
| ("Core-" if p_core_count < 6 else 'C-') + str(i + 1) + " ", | ||
| str(cpu_metrics_dict["P-Cluster" + str(i) + "_active"]), | ||
| "%", | ||
| ]) | ||
| core_gauges[core_count % 8].value = cpu_metrics_dict["P-Cluster" + str(i) + "_active"] | ||
| core_count += 1 | ||
| self.gpu_gauge.title = "".join([ | ||
| "GPU Usage: ", | ||
| str(gpu_metrics_dict["active"]), | ||
| "% @ ", | ||
| str(gpu_metrics_dict["freq_MHz"]), | ||
| " MHz" | ||
| ]) | ||
| self.gpu_gauge.value = gpu_metrics_dict["active"] | ||
| gpu_gauge.title = "".join([ | ||
| "GPU Usage: ", | ||
| str(gpu_metrics_dict["active"]), | ||
| "% @ ", | ||
| str(gpu_metrics_dict["freq_MHz"]), | ||
| " MHz" | ||
| ]) | ||
| gpu_gauge.value = gpu_metrics_dict["active"] | ||
| ane_power_W = cpu_metrics_dict["ane_W"] / args.interval | ||
| if ane_power_W > self.ane_max_power: | ||
| self.ane_max_power = ane_power_W | ||
| ane_util_percent = int( | ||
| ane_power_W / self.ane_max_power * 100) | ||
| self.ane_gauge.title = "".join([ | ||
| "ANE Usage: ", | ||
| str(ane_util_percent), | ||
| "% @ ", | ||
| '{0:.1f}'.format(ane_power_W), | ||
| " W" | ||
| ]) | ||
| self.ane_gauge.value = ane_util_percent | ||
| ane_power_W = cpu_metrics_dict["ane_W"] / args.interval | ||
| if ane_power_W > ane_max_power: | ||
| ane_max_power = ane_power_W | ||
| ane_util_percent = int( | ||
| ane_power_W / ane_max_power * 100) | ||
| ane_gauge.title = "".join([ | ||
| "ANE Usage: ", | ||
| str(ane_util_percent), | ||
| "% @ ", | ||
| '{0:.1f}'.format(ane_power_W), | ||
| " W" | ||
| ]) | ||
| ane_gauge.value = ane_util_percent | ||
| ram_metrics_dict = get_ram_metrics_dict() | ||
| ram_metrics_dict = get_ram_metrics_dict() | ||
| if ram_metrics_dict["swap_total_GB"] < 0.1: | ||
| self.ram_gauge.title = "".join([ | ||
| "RAM Usage: ", | ||
| str(ram_metrics_dict["used_GB"]), | ||
| "/", | ||
| str(ram_metrics_dict["total_GB"]), | ||
| "GB - swap inactive" | ||
| ]) | ||
| else: | ||
| self.ram_gauge.title = "".join([ | ||
| "RAM Usage: ", | ||
| str(ram_metrics_dict["used_GB"]), | ||
| "/", | ||
| str(ram_metrics_dict["total_GB"]), | ||
| "GB", | ||
| " - swap:", | ||
| str(ram_metrics_dict["swap_used_GB"]), | ||
| "/", | ||
| str(ram_metrics_dict["swap_total_GB"]), | ||
| "GB" | ||
| ]) | ||
| self.ram_gauge.value = ram_metrics_dict["free_percent"] | ||
| if ram_metrics_dict["swap_total_GB"] < 0.1: | ||
| ram_gauge.title = "".join([ | ||
| "RAM Usage: ", | ||
| str(ram_metrics_dict["used_GB"]), | ||
| "/", | ||
| str(ram_metrics_dict["total_GB"]), | ||
| "GB - swap inactive" | ||
| ]) | ||
| else: | ||
| ram_gauge.title = "".join([ | ||
| "RAM Usage: ", | ||
| str(ram_metrics_dict["used_GB"]), | ||
| "/", | ||
| str(ram_metrics_dict["total_GB"]), | ||
| "GB", | ||
| " - swap:", | ||
| str(ram_metrics_dict["swap_used_GB"]), | ||
| "/", | ||
| str(ram_metrics_dict["swap_total_GB"]), | ||
| "GB" | ||
| ]) | ||
| ram_gauge.value = ram_metrics_dict["free_percent"] | ||
| """ | ||
| """ | ||
| ecpu_bw_percent = int( | ||
| (bandwidth_metrics["ECPU DCS RD"] + bandwidth_metrics[ | ||
| "ECPU DCS WR"]) / args.interval / max_cpu_bw * 100) | ||
| ecpu_read_GB = bandwidth_metrics["ECPU DCS RD"] / \ | ||
| args.interval | ||
| ecpu_write_GB = bandwidth_metrics["ECPU DCS WR"] / \ | ||
| args.interval | ||
| ecpu_bw_gauge.title = "".join([ | ||
| "E-CPU: ", | ||
| '{0:.1f}'.format(ecpu_read_GB + ecpu_write_GB), | ||
| "GB/s" | ||
| ]) | ||
| ecpu_bw_gauge.value = ecpu_bw_percent | ||
| ecpu_bw_percent = int( | ||
| (bandwidth_metrics["ECPU DCS RD"] + bandwidth_metrics[ | ||
| "ECPU DCS WR"]) / args.interval / max_cpu_bw * 100) | ||
| ecpu_read_GB = bandwidth_metrics["ECPU DCS RD"] / \ | ||
| args.interval | ||
| ecpu_write_GB = bandwidth_metrics["ECPU DCS WR"] / \ | ||
| args.interval | ||
| ecpu_bw_gauge.title = "".join([ | ||
| "E-CPU: ", | ||
| '{0:.1f}'.format(ecpu_read_GB + ecpu_write_GB), | ||
| "GB/s" | ||
| ]) | ||
| ecpu_bw_gauge.value = ecpu_bw_percent | ||
| pcpu_bw_percent = int( | ||
| (bandwidth_metrics["PCPU DCS RD"] + bandwidth_metrics[ | ||
| "PCPU DCS WR"]) / args.interval / max_cpu_bw * 100) | ||
| pcpu_read_GB = bandwidth_metrics["PCPU DCS RD"] / \ | ||
| args.interval | ||
| pcpu_write_GB = bandwidth_metrics["PCPU DCS WR"] / \ | ||
| args.interval | ||
| pcpu_bw_gauge.title = "".join([ | ||
| "P-CPU: ", | ||
| '{0:.1f}'.format(pcpu_read_GB + pcpu_write_GB), | ||
| "GB/s" | ||
| ]) | ||
| pcpu_bw_gauge.value = pcpu_bw_percent | ||
| pcpu_bw_percent = int( | ||
| (bandwidth_metrics["PCPU DCS RD"] + bandwidth_metrics[ | ||
| "PCPU DCS WR"]) / args.interval / max_cpu_bw * 100) | ||
| pcpu_read_GB = bandwidth_metrics["PCPU DCS RD"] / \ | ||
| args.interval | ||
| pcpu_write_GB = bandwidth_metrics["PCPU DCS WR"] / \ | ||
| args.interval | ||
| pcpu_bw_gauge.title = "".join([ | ||
| "P-CPU: ", | ||
| '{0:.1f}'.format(pcpu_read_GB + pcpu_write_GB), | ||
| "GB/s" | ||
| ]) | ||
| pcpu_bw_gauge.value = pcpu_bw_percent | ||
| gpu_bw_percent = int( | ||
| (bandwidth_metrics["GFX DCS RD"] + bandwidth_metrics["GFX DCS WR"]) / max_gpu_bw * 100) | ||
| gpu_read_GB = bandwidth_metrics["GFX DCS RD"] | ||
| gpu_write_GB = bandwidth_metrics["GFX DCS WR"] | ||
| gpu_bw_gauge.title = "".join([ | ||
| "GPU: ", | ||
| '{0:.1f}'.format(gpu_read_GB + gpu_write_GB), | ||
| "GB/s" | ||
| ]) | ||
| gpu_bw_gauge.value = gpu_bw_percent | ||
| gpu_bw_percent = int( | ||
| (bandwidth_metrics["GFX DCS RD"] + bandwidth_metrics["GFX DCS WR"]) / max_gpu_bw * 100) | ||
| gpu_read_GB = bandwidth_metrics["GFX DCS RD"] | ||
| gpu_write_GB = bandwidth_metrics["GFX DCS WR"] | ||
| gpu_bw_gauge.title = "".join([ | ||
| "GPU: ", | ||
| '{0:.1f}'.format(gpu_read_GB + gpu_write_GB), | ||
| "GB/s" | ||
| ]) | ||
| gpu_bw_gauge.value = gpu_bw_percent | ||
| media_bw_percent = int( | ||
| bandwidth_metrics["MEDIA DCS"] / args.interval / max_media_bw * 100) | ||
| media_bw_gauge.title = "".join([ | ||
| "Media: ", | ||
| '{0:.1f}'.format( | ||
| bandwidth_metrics["MEDIA DCS"] / args.interval), | ||
| "GB/s" | ||
| ]) | ||
| media_bw_gauge.value = media_bw_percent | ||
| media_bw_percent = int( | ||
| bandwidth_metrics["MEDIA DCS"] / args.interval / max_media_bw * 100) | ||
| media_bw_gauge.title = "".join([ | ||
| "Media: ", | ||
| '{0:.1f}'.format( | ||
| bandwidth_metrics["MEDIA DCS"] / args.interval), | ||
| "GB/s" | ||
| ]) | ||
| media_bw_gauge.value = media_bw_percent | ||
| total_bw_GB = ( | ||
| bandwidth_metrics["DCS RD"] + bandwidth_metrics["DCS WR"]) / args.interval | ||
| bw_gauges.title = "".join([ | ||
| "Memory Bandwidth: ", | ||
| '{0:.2f}'.format(total_bw_GB), | ||
| " GB/s (R:", | ||
| '{0:.2f}'.format( | ||
| bandwidth_metrics["DCS RD"] / args.interval), | ||
| "/W:", | ||
| '{0:.2f}'.format( | ||
| bandwidth_metrics["DCS WR"] / args.interval), | ||
| " GB/s)" | ||
| ]) | ||
| if args.show_cores: | ||
| bw_gauges_ext = memory_gauges.items[2] | ||
| bw_gauges_ext.title = "Memory Bandwidth:" | ||
| """ | ||
| total_bw_GB = ( | ||
| bandwidth_metrics["DCS RD"] + bandwidth_metrics["DCS WR"]) / args.interval | ||
| bw_gauges.title = "".join([ | ||
| "Memory Bandwidth: ", | ||
| '{0:.2f}'.format(total_bw_GB), | ||
| " GB/s (R:", | ||
| '{0:.2f}'.format( | ||
| bandwidth_metrics["DCS RD"] / args.interval), | ||
| "/W:", | ||
| '{0:.2f}'.format( | ||
| bandwidth_metrics["DCS WR"] / args.interval), | ||
| " GB/s)" | ||
| ]) | ||
| if args.show_cores: | ||
| bw_gauges_ext = memory_gauges.items[2] | ||
| bw_gauges_ext.title = "Memory Bandwidth:" | ||
| """ | ||
| package_power_W = cpu_metrics_dict["package_W"] / \ | ||
| args.interval | ||
| if package_power_W > self.package_peak_power: | ||
| self.package_peak_power = package_power_W | ||
| self.avg_package_power_list.append(package_power_W) | ||
| avg_package_power = get_avg(self.avg_package_power_list) | ||
| self.power_charts.title = "".join([ | ||
| "CPU+GPU+ANE Power: ", | ||
| '{0:.2f}'.format(package_power_W), | ||
| "W (avg: ", | ||
| '{0:.2f}'.format(avg_package_power), | ||
| "W peak: ", | ||
| '{0:.2f}'.format(self.package_peak_power), | ||
| "W) throttle: ", | ||
| thermal_throttle, | ||
| ]) | ||
| package_power_W = cpu_metrics_dict["package_W"] / \ | ||
| args.interval | ||
| if package_power_W > package_peak_power: | ||
| package_peak_power = package_power_W | ||
| avg_package_power_list.append(package_power_W) | ||
| avg_package_power = get_avg(avg_package_power_list) | ||
| power_charts.title = "".join([ | ||
| "CPU+GPU+ANE Power: ", | ||
| '{0:.2f}'.format(package_power_W), | ||
| "W (avg: ", | ||
| '{0:.2f}'.format(avg_package_power), | ||
| "W peak: ", | ||
| '{0:.2f}'.format(package_peak_power), | ||
| "W) throttle: ", | ||
| thermal_throttle, | ||
| ]) | ||
| cpu_power_W = cpu_metrics_dict["cpu_W"] / args.interval | ||
| if cpu_power_W > self.cpu_peak_power: | ||
| self.cpu_peak_power = cpu_power_W | ||
| if cpu_power_W > self.cpu_max_power: | ||
| self.cpu_max_power = cpu_power_W | ||
| cpu_power_percent = int( | ||
| cpu_power_W / self.cpu_max_power * 100) | ||
| self.avg_cpu_power_list.append(cpu_power_W) | ||
| avg_cpu_power = get_avg(self.avg_cpu_power_list) | ||
| self.cpu_power_chart.title = "".join([ | ||
| "CPU: ", | ||
| '{0:.2f}'.format(cpu_power_W), | ||
| "W (avg: ", | ||
| '{0:.2f}'.format(avg_cpu_power), | ||
| "W peak: ", | ||
| '{0:.2f}'.format(self.cpu_peak_power), | ||
| "W)" | ||
| ]) | ||
| self.cpu_power_chart.append(cpu_power_percent) | ||
| cpu_power_W = cpu_metrics_dict["cpu_W"] / args.interval | ||
| if cpu_power_W > cpu_peak_power: | ||
| cpu_peak_power = cpu_power_W | ||
| if cpu_power_W > cpu_max_power: | ||
| cpu_max_power = cpu_power_W | ||
| cpu_power_percent = int( | ||
| cpu_power_W / cpu_max_power * 100) | ||
| avg_cpu_power_list.append(cpu_power_W) | ||
| avg_cpu_power = get_avg(avg_cpu_power_list) | ||
| cpu_power_chart.title = "".join([ | ||
| "CPU: ", | ||
| '{0:.2f}'.format(cpu_power_W), | ||
| "W (avg: ", | ||
| '{0:.2f}'.format(avg_cpu_power), | ||
| "W peak: ", | ||
| '{0:.2f}'.format(cpu_peak_power), | ||
| "W)" | ||
| ]) | ||
| cpu_power_chart.append(cpu_power_percent) | ||
| gpu_power_W = cpu_metrics_dict["gpu_W"] / args.interval | ||
| if gpu_power_W > self.gpu_peak_power: | ||
| self.gpu_peak_power = gpu_power_W | ||
| if gpu_power_W > self.gpu_max_power: | ||
| self.gpu_max_power = gpu_power_W | ||
| gpu_power_percent = int( | ||
| gpu_power_W / self.gpu_max_power * 100) | ||
| self.avg_gpu_power_list.append(gpu_power_W) | ||
| avg_gpu_power = get_avg(self.avg_gpu_power_list) | ||
| self.gpu_power_chart.title = "".join([ | ||
| "GPU: ", | ||
| '{0:.2f}'.format(gpu_power_W), | ||
| "W (avg: ", | ||
| '{0:.2f}'.format(avg_gpu_power), | ||
| "W peak: ", | ||
| '{0:.2f}'.format(self.gpu_peak_power), | ||
| "W)" | ||
| ]) | ||
| self.gpu_power_chart.append(gpu_power_percent) | ||
| gpu_power_W = cpu_metrics_dict["gpu_W"] / args.interval | ||
| if gpu_power_W > gpu_peak_power: | ||
| gpu_peak_power = gpu_power_W | ||
| if gpu_power_W > gpu_max_power: | ||
| gpu_max_power = gpu_power_W | ||
| gpu_power_percent = int( | ||
| gpu_power_W / gpu_max_power * 100) | ||
| avg_gpu_power_list.append(gpu_power_W) | ||
| avg_gpu_power = get_avg(avg_gpu_power_list) | ||
| gpu_power_chart.title = "".join([ | ||
| "GPU: ", | ||
| '{0:.2f}'.format(gpu_power_W), | ||
| "W (avg: ", | ||
| '{0:.2f}'.format(avg_gpu_power), | ||
| "W peak: ", | ||
| '{0:.2f}'.format(gpu_peak_power), | ||
| "W)" | ||
| ]) | ||
| gpu_power_chart.append(gpu_power_percent) | ||
| def format_number(number): | ||
| return humanize.naturalsize(number) | ||
| def format_number(number): | ||
| return humanize.naturalsize(number) | ||
| disk_read_iops = disk_metrics_dict["read_iops"] | ||
| if disk_read_iops > self.disk_read_iops_peak: | ||
| self.disk_read_iops_peak = disk_read_iops | ||
| self.disk_read_iops_charts.title = "Read iops: "+ f'{disk_read_iops} (peak: {self.disk_read_iops_peak})' | ||
| if self.disk_read_iops_charts.datapoints: | ||
| disk_read_iops_rate = int(disk_read_iops / self.disk_read_iops_peak * 100) if self.disk_read_iops_peak > 0 else 0 | ||
| else: | ||
| disk_read_iops_rate = 100 | ||
| self.disk_read_iops_charts.append(disk_read_iops_rate) | ||
| disk_read_iops = disk_metrics_dict["read_iops"] | ||
| if disk_read_iops > disk_read_iops_peak: | ||
| disk_read_iops_peak = disk_read_iops | ||
| disk_read_iops_charts.title = "Read iops: "+ f'{disk_read_iops} (peak: {disk_read_iops_peak})' | ||
| if disk_read_iops_charts.datapoints: | ||
| disk_read_iops_rate = int(disk_read_iops / disk_read_iops_peak * 100) if disk_read_iops_peak > 0 else 0 | ||
| else: | ||
| disk_read_iops_rate = 100 | ||
| disk_read_iops_charts.append(disk_read_iops_rate) | ||
| disk_write_iops = disk_metrics_dict["write_iops"] | ||
| if disk_write_iops > self.disk_write_iops_peak: | ||
| self.disk_write_iops_peak = disk_write_iops | ||
| self.disk_write_iops_charts.title = "Write iops: "+ f'{disk_write_iops} (peak: {self.disk_write_iops_peak})' | ||
| if self.disk_write_iops_charts.datapoints: | ||
| disk_write_iops_rate = int(disk_read_iops / self.disk_write_iops_peak * 100) if self.disk_write_iops_peak > 0 else 0 | ||
| else: | ||
| disk_write_iops_rate = 100 | ||
| self.disk_write_iops_charts.append(disk_write_iops_rate) | ||
| disk_write_iops = disk_metrics_dict["write_iops"] | ||
| if disk_write_iops > disk_write_iops_peak: | ||
| disk_write_iops_peak = disk_write_iops | ||
| disk_write_iops_charts.title = "Write iops: "+ f'{disk_write_iops} (peak: {disk_write_iops_peak})' | ||
| if disk_write_iops_charts.datapoints: | ||
| disk_write_iops_rate = int(disk_read_iops / disk_write_iops_peak * 100) if disk_write_iops_peak > 0 else 0 | ||
| else: | ||
| disk_write_iops_rate = 100 | ||
| disk_write_iops_charts.append(disk_write_iops_rate) | ||
| disk_read_bps = disk_metrics_dict["read_Bps"] | ||
| if disk_read_bps > self.disk_read_bps_peak: | ||
| self.disk_read_bps_peak = disk_read_bps | ||
| self.disk_read_bps_charts.title = "Read : "+ f'{format_number(disk_read_bps)}/s (peak: {format_number(self.disk_read_bps_peak)}/s)' | ||
| if self.disk_read_bps_charts.datapoints: | ||
| disk_read_bps_rate = int(disk_read_bps / self.disk_read_bps_peak * 100) if self.disk_read_bps_peak > 0 else 0 | ||
| else: | ||
| disk_read_bps_rate = 100 | ||
| self.disk_read_bps_charts.append(disk_read_bps_rate) | ||
| disk_read_bps = disk_metrics_dict["read_Bps"] | ||
| if disk_read_bps > disk_read_bps_peak: | ||
| disk_read_bps_peak = disk_read_bps | ||
| disk_read_bps_charts.title = "Read : "+ f'{format_number(disk_read_bps)}/s (peak: {format_number(disk_read_bps_peak)}/s)' | ||
| if disk_read_bps_charts.datapoints: | ||
| disk_read_bps_rate = int(disk_read_bps / disk_read_bps_peak * 100) if disk_read_bps_peak > 0 else 0 | ||
| else: | ||
| disk_read_bps_rate = 100 | ||
| disk_read_bps_charts.append(disk_read_bps_rate) | ||
| disk_write_bps = disk_metrics_dict["write_Bps"] | ||
| if disk_write_bps > self.disk_write_bps_peak: | ||
| self.disk_write_bps_peak = disk_write_bps | ||
| self.disk_write_bps_charts.title = "Write : "+ f'{format_number(disk_write_bps)}/s (peak: {format_number(self.disk_write_bps_peak)}/s)' | ||
| if self.disk_write_bps_charts.datapoints: | ||
| disk_write_bps_rate = int(disk_write_bps / self.disk_write_bps_peak * 100) if self.disk_write_bps_peak > 0 else 0 | ||
| else: | ||
| disk_write_bps_rate = 100 | ||
| self.disk_write_bps_charts.append(disk_write_bps_rate) | ||
| disk_write_bps = disk_metrics_dict["write_Bps"] | ||
| if disk_write_bps > disk_write_bps_peak: | ||
| disk_write_bps_peak = disk_write_bps | ||
| disk_write_bps_charts.title = "Write : "+ f'{format_number(disk_write_bps)}/s (peak: {format_number(disk_write_bps_peak)}/s)' | ||
| if disk_write_bps_charts.datapoints: | ||
| disk_write_bps_rate = int(disk_write_bps / disk_write_bps_peak * 100) if disk_write_bps_peak > 0 else 0 | ||
| else: | ||
| disk_write_bps_rate = 100 | ||
| disk_write_bps_charts.append(disk_write_bps_rate) | ||
| network_in_bps = network_metrics_dict["in_Bps"] | ||
| if network_in_bps > self.network_in_bps_peak: | ||
| self.network_in_bps_peak = network_in_bps | ||
| self.network_in_bps_charts.title = "in : "+ f'{format_number(network_in_bps)}/s (peak: {format_number(self.network_in_bps_peak)}/s)' | ||
| if self.network_in_bps_charts.datapoints: | ||
| network_in_bps_rate = int(network_in_bps / self.network_in_bps_peak * 100) if self.network_in_bps_peak > 0 else 0 | ||
| else: | ||
| network_in_bps_rate = 100 | ||
| self.network_in_bps_charts.append(network_in_bps_rate) | ||
| network_in_bps = network_metrics_dict["in_Bps"] | ||
| if network_in_bps > network_in_bps_peak: | ||
| network_in_bps_peak = network_in_bps | ||
| network_in_bps_charts.title = "in : "+ f'{format_number(network_in_bps)}/s (peak: {format_number(network_in_bps_peak)}/s)' | ||
| if network_in_bps_charts.datapoints: | ||
| network_in_bps_rate = int(network_in_bps / network_in_bps_peak * 100) if network_in_bps_peak > 0 else 0 | ||
| else: | ||
| network_in_bps_rate = 100 | ||
| network_in_bps_charts.append(network_in_bps_rate) | ||
| network_out_bps = network_metrics_dict["out_Bps"] | ||
| if network_out_bps > self.network_out_bps_peak: | ||
| self.network_out_bps_peak = network_out_bps | ||
| self.network_out_bps_charts.title = "out : "+ f'{format_number(network_out_bps)}/s (peak: {format_number(self.network_out_bps_peak)}/s)' | ||
| if self.network_out_bps_charts.datapoints: | ||
| network_out_bps_rate = int(network_out_bps / self.network_out_bps_peak * 100) if self.network_out_bps_peak > 0 else 0 | ||
| else: | ||
| network_out_bps_rate = 100 | ||
| self.network_out_bps_charts.append(network_out_bps_rate) | ||
| network_out_bps = network_metrics_dict["out_Bps"] | ||
| if network_out_bps > network_out_bps_peak: | ||
| network_out_bps_peak = network_out_bps | ||
| network_out_bps_charts.title = "out : "+ f'{format_number(network_out_bps)}/s (peak: {format_number(network_out_bps_peak)}/s)' | ||
| if network_out_bps_charts.datapoints: | ||
| network_out_bps_rate = int(network_out_bps / network_out_bps_peak * 100) if network_out_bps_peak > 0 else 0 | ||
| else: | ||
| network_out_bps_rate = 100 | ||
| network_out_bps_charts.append(network_out_bps_rate) | ||
| self.ui.display() | ||
| ui.display() | ||
| key_cmd = '' | ||
| with term.cbreak(): | ||
| key = term.inkey(timeout=1) | ||
| if key: | ||
| if key.is_sequence: | ||
| if key.name == 'KEY_ESCAPE': | ||
| key_cmd = "quit" | ||
| elif key.lower() == 'q': | ||
| key_cmd = "quit" | ||
| if key_cmd == "quit": | ||
| def get_avg(inlist): | ||
| avg = sum(inlist) / len(inlist) | ||
| return avg | ||
| def main(stdscr): | ||
| soc_info_dict = get_soc_info() | ||
| view1 = DefaultView(soc_info_dict=soc_info_dict,args=args) | ||
| clear_console() | ||
| stdscr.nodelay(True) | ||
| view = 1 | ||
| try: | ||
| data = b'' | ||
| while True: | ||
| output = powermetrics_process.stdout.readline() | ||
| if powermetrics_process.poll() is not None: | ||
| break | ||
| data = data + output | ||
| str_output = output.decode() | ||
| if str_output.startswith('</plist>'): | ||
| data = data.replace(b'\x00',b'') | ||
| powermetrics_parse = plistlib.loads(data) | ||
| key = stdscr.getch() | ||
| if key > 0: | ||
| if key == 27: | ||
| print("\nStopping...") | ||
| break | ||
| elif key == curses.KEY_LEFT: | ||
| args.color = (args.color - 1) if args.color > 1 else 8 | ||
| elif key == curses.KEY_RIGHT: | ||
| args.color = (args.color + 1) if args.color < 8 else 1 | ||
| elif chr(key).lower() == 'q': | ||
| print("\nStopping...") | ||
| break | ||
| elif chr(key) == '1': | ||
| args.show_cores = False | ||
| if view != 1: | ||
| view1.construct(soc_info_dict,args) | ||
| view = 1 | ||
| clear_console() | ||
| elif chr(key) == '2': | ||
| args.show_cores = True | ||
| if view != 2: | ||
| view1.construct(soc_info_dict,args) | ||
| view = 2 | ||
| clear_console() | ||
| if view == 1 or view == 2: | ||
| view1.display(powermetrics_parse,args) | ||
| data = b'' | ||
| if str_output == '': | ||
@@ -864,3 +884,2 @@ time.sleep(0.1) | ||
| print("Stopping...") | ||
| print("\033[?25h") | ||
@@ -871,3 +890,27 @@ return | ||
| if __name__ == "__main__": | ||
| main() | ||
| print(f"\n{version} - enhanced MAC Performance monitoring CLI tool for Apple Silicon") | ||
| print("You can update macpm by running `pip install macpm --upgrade`") | ||
| print("Get help at `https://github.com/visualcjy/macpm`") | ||
| print("P.S. You are recommended to run macpm with `sudo macpm`\n") | ||
| print("\n[1/3] Loading macpm\n") | ||
| print("\033[?25l") | ||
| #global powermetrics_process | ||
| print("\n[2/3] Starting powermetrics process\n") | ||
| command = " ".join([ | ||
| "sudo nice -n", | ||
| str(10), | ||
| "powermetrics", | ||
| "--samplers cpu_power,gpu_power,thermal,network,disk", | ||
| "-f plist", | ||
| "-i", | ||
| str(args.interval * 1000) | ||
| ]) | ||
| powermetrics_process = subprocess.Popen(command.split(" "), stdin=PIPE, stdout=PIPE) | ||
| print("\n[3/3] Waiting for first reading...\n") | ||
| curses.wrapper(main) | ||
| print("\033[?25h") | ||
| try: | ||
@@ -874,0 +917,0 @@ powermetrics_process.terminate() |
+1
-1
| Metadata-Version: 2.1 | ||
| Name: macpm | ||
| Version: 0.14 | ||
| Version: 0.15 | ||
| Summary: Performance monitoring CLI tool for Apple Silicon | ||
@@ -5,0 +5,0 @@ Home-page: https://github.com/visualcjy/macpm |
+2
-1
@@ -6,3 +6,3 @@ # macpm | ||
| Performance monitoring CLI tool for Apple Silicon | ||
| enhanced MAC Performance monitoring CLI tool for Apple Silicon | ||
@@ -22,2 +22,3 @@  | ||
| 4. change the way to call powermetrics, no temp files in /tmp | ||
| 5. press ESC or q to quit | ||
@@ -24,0 +25,0 @@ A Python-based `nvtop`-inspired command line tool for Apple Silicon (aka M1) Macs. |
+1
-1
@@ -7,3 +7,3 @@ from setuptools import setup, find_packages | ||
| name='macpm', | ||
| version='0.14', | ||
| version='0.15', | ||
| author='Jinyu Chen', | ||
@@ -10,0 +10,0 @@ author_email='visualcjy@mail.com', |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
45735
3.92%876
5.04%