Merge pull request 'v0.1.20: The Log release' (#1) from v0.1.20 into master
Reviewed-on: https://git.jlay.dev/jlay/amdgpu_stats/pulls/1
This commit is contained in:
commit
1ee20d3554
5 changed files with 193 additions and 21 deletions
|
@ -7,11 +7,11 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.8", "3.9", "3.10", "3.11"]
|
python-version: ["3.8.17", "3.9.17", "3.10.12", "3.11.4"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: https://github.com/actions/checkout@v3
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: "Set up Python ${{ matrix.python-version }}"
|
||||||
uses: actions/setup-python@v3
|
uses: https://github.com/actions/setup-python@v3
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
|
@ -5,6 +5,7 @@ A Python module/TUI for AMD GPU statistics
|
||||||
|
|
||||||
![Screenshot of the main stats table](https://raw.githubusercontent.com/joshlay/amdgpu_stats/master/screens/main.svg "Main screen")
|
![Screenshot of the main stats table](https://raw.githubusercontent.com/joshlay/amdgpu_stats/master/screens/main.svg "Main screen")
|
||||||
![Screenshot of the 'graphing' scroll bars](https://raw.githubusercontent.com/joshlay/amdgpu_stats/master/screens/graphs.svg "Graphs")
|
![Screenshot of the 'graphing' scroll bars](https://raw.githubusercontent.com/joshlay/amdgpu_stats/master/screens/graphs.svg "Graphs")
|
||||||
|
![Screenshot of the 'Logs' tab pane](https://raw.githubusercontent.com/joshlay/amdgpu_stats/master/screens/logs.svg "Logs")
|
||||||
|
|
||||||
Tested _only_ on `RX6000` series cards; APUs and more _may_ be supported. Please file an issue if finding incompatibility!
|
Tested _only_ on `RX6000` series cards; APUs and more _may_ be supported. Please file an issue if finding incompatibility!
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "amdgpu-stats"
|
name = "amdgpu-stats"
|
||||||
version = "0.1.19"
|
version = "0.1.20"
|
||||||
description = "A module/TUI for AMD GPU statistics"
|
description = "A module/TUI for AMD GPU statistics"
|
||||||
authors = ["Josh Lay <pypi@jlay.io>"]
|
authors = ["Josh Lay <pypi@jlay.io>"]
|
||||||
repository = "https://github.com/joshlay/amdgpu_stats"
|
repository = "https://git.jlay.dev/jlay/amdgpu_stats"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
documentation = "https://amdgpu-stats.readthedocs.io/en/latest/"
|
documentation = "https://amdgpu-stats.readthedocs.io/en/latest/"
|
||||||
|
@ -22,9 +22,8 @@ classifiers = [
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.8"
|
python = "^3.8"
|
||||||
textual = ">=0.30.0"
|
textual = ">=0.32.0"
|
||||||
humanfriendly = ">=10.0"
|
humanfriendly = ">=10.0"
|
||||||
pyyaml = "^6.0"
|
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
amdgpu-stats = "amdgpu_stats:textual_run"
|
amdgpu-stats = "amdgpu_stats:textual_run"
|
||||||
|
|
165
screens/logs.svg
Normal file
165
screens/logs.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 39 KiB |
|
@ -16,7 +16,6 @@ Functions:
|
||||||
# pylint: disable=line-too-long
|
# pylint: disable=line-too-long
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from yaml import dump
|
|
||||||
|
|
||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
from textual import work
|
from textual import work
|
||||||
|
@ -32,7 +31,7 @@ from textual.widgets import (
|
||||||
Static,
|
Static,
|
||||||
TabbedContent,
|
TabbedContent,
|
||||||
TabPane,
|
TabPane,
|
||||||
TextLog,
|
Log,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .utils import (
|
from .utils import (
|
||||||
|
@ -129,10 +128,9 @@ class GPUStatsWidget(Static):
|
||||||
def __init__(self, *args, cards=None, **kwargs):
|
def __init__(self, *args, cards=None, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.cards = cards
|
self.cards = cards
|
||||||
self.text_log = TextLog(highlight=True,
|
self.text_log = Log(highlight=True,
|
||||||
markup=True,
|
name='log_gpu',
|
||||||
name='log_gpu',
|
classes='logs')
|
||||||
classes='logs')
|
|
||||||
self.stats_table = DataTable(zebra_stripes=True,
|
self.stats_table = DataTable(zebra_stripes=True,
|
||||||
show_cursor=True,
|
show_cursor=True,
|
||||||
name='stats_table',
|
name='stats_table',
|
||||||
|
@ -142,18 +140,17 @@ class GPUStatsWidget(Static):
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
'''Fires when stats widget 'mounted', behaves like on first showing'''
|
'''Fires when stats widget 'mounted', behaves like on first showing'''
|
||||||
self.update_log("[bold green]App started, logging begin!\n")
|
self.update_log("App started, logging begin!")
|
||||||
# construct the table columns
|
# construct the table columns
|
||||||
columns = list(self.get_column_data_mapping(None).keys())
|
columns = list(self.get_column_data_mapping(None).keys())
|
||||||
|
self.update_log('Stat columns:')
|
||||||
for column in columns:
|
for column in columns:
|
||||||
|
self.update_log(f" - '{column}'", show_ts=False)
|
||||||
if column in ['Limit', 'Default', 'Capability']:
|
if column in ['Limit', 'Default', 'Capability']:
|
||||||
self.stats_table.add_column(label='[italic]' + column,
|
self.stats_table.add_column(label='[italic]' + column,
|
||||||
key=column)
|
key=column)
|
||||||
else:
|
else:
|
||||||
self.stats_table.add_column(label=column, key=column)
|
self.stats_table.add_column(label=column, key=column)
|
||||||
# self.update_log(f' - "{column}"')
|
|
||||||
self.update_log('[bold]Stat columns:')
|
|
||||||
self.update_log(dump(data=columns, default_flow_style=False, sort_keys=True))
|
|
||||||
# do a one-off stat collection, populate table before the interval
|
# do a one-off stat collection, populate table before the interval
|
||||||
self.get_stats()
|
self.get_stats()
|
||||||
# stand up the stat-collecting interval, twice per second
|
# stand up the stat-collecting interval, twice per second
|
||||||
|
@ -176,9 +173,19 @@ class GPUStatsWidget(Static):
|
||||||
with TabPane("Logs", id="tab_logs"):
|
with TabPane("Logs", id="tab_logs"):
|
||||||
yield self.text_log
|
yield self.text_log
|
||||||
|
|
||||||
def update_log(self, message: str) -> None:
|
def update_log(self, message: str, show_ts: bool = True) -> None:
|
||||||
"""Update the TextLog widget with a new message."""
|
"""Update the Log widget with a new message.
|
||||||
self.text_log.write(message)
|
|
||||||
|
Highest Textual version-requiring widget; >=0.32.0
|
||||||
|
Should be more performant than the old TextLog widget
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): The message to be added to the logging widget on the 'Logs' tab.
|
||||||
|
show_ts (bool, optional): If True (default), appends a timestamp to the message.
|
||||||
|
"""
|
||||||
|
if show_ts:
|
||||||
|
message = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {message}"
|
||||||
|
self.text_log.write_line(message)
|
||||||
|
|
||||||
@work(exclusive=True)
|
@work(exclusive=True)
|
||||||
async def get_stats(self):
|
async def get_stats(self):
|
||||||
|
|
Reference in a new issue