feat(collector): capture additional smartctl diagnostics
Record host read and write commands, controller busy time, error log entries, warning and critical temperature time, and thermal management transitions from the existing smartctl -a -j acquisition. Schema 7 adds nullable columns to samples so legacy rows read as unknown, and the Diagnostics panel shows each counter with its change.
This commit is contained in:
+45
-2
@@ -11,7 +11,23 @@ from typing import Optional
|
||||
|
||||
|
||||
# Schema version - increment on each migration
|
||||
SCHEMA_VERSION = 6
|
||||
SCHEMA_VERSION = 7
|
||||
|
||||
# Diagnostic counters added in schema 7 (issue #111), named after the
|
||||
# NVMe health-log keys they come from. All nullable: legacy rows and drives that
|
||||
# do not report a counter stay unknown rather than zero.
|
||||
DIAGNOSTIC_SAMPLE_COLUMNS = (
|
||||
"host_reads",
|
||||
"host_writes",
|
||||
"controller_busy_time",
|
||||
"num_err_log_entries",
|
||||
"warning_temp_time",
|
||||
"critical_comp_time",
|
||||
"thm_temp1_trans_count",
|
||||
"thm_temp1_total_time",
|
||||
"thm_temp2_trans_count",
|
||||
"thm_temp2_total_time",
|
||||
)
|
||||
|
||||
|
||||
# Packaged default placement (spec §8.3). The config may override it, but a
|
||||
@@ -109,7 +125,17 @@ def _create_schema(conn: sqlite3.Connection):
|
||||
bytes_read INTEGER,
|
||||
critical_warning INTEGER,
|
||||
segment_id INTEGER,
|
||||
local_tz TEXT
|
||||
local_tz TEXT,
|
||||
host_reads INTEGER,
|
||||
host_writes INTEGER,
|
||||
controller_busy_time INTEGER,
|
||||
num_err_log_entries INTEGER,
|
||||
warning_temp_time INTEGER,
|
||||
critical_comp_time INTEGER,
|
||||
thm_temp1_trans_count INTEGER,
|
||||
thm_temp1_total_time INTEGER,
|
||||
thm_temp2_trans_count INTEGER,
|
||||
thm_temp2_total_time INTEGER
|
||||
)
|
||||
""")
|
||||
|
||||
@@ -303,6 +329,7 @@ def _apply_migrations(conn: sqlite3.Connection, current_version: int):
|
||||
4: _migrate_3_to_4,
|
||||
5: _migrate_4_to_5,
|
||||
6: _migrate_5_to_6,
|
||||
7: _migrate_6_to_7,
|
||||
}
|
||||
while current_version < SCHEMA_VERSION:
|
||||
target_version = current_version + 1
|
||||
@@ -408,6 +435,22 @@ def _migrate_5_to_6(conn: sqlite3.Connection) -> None:
|
||||
repair_legacy_local_day_evidence(conn)
|
||||
|
||||
|
||||
def _migrate_6_to_7(conn: sqlite3.Connection) -> None:
|
||||
"""Add nullable diagnostic counters to samples (issue #111).
|
||||
|
||||
Additive only: existing rows are untouched and read NULL (unknown).
|
||||
Rollback (SQLite 3.35+, with the collector stopped): for each column in
|
||||
DIAGNOSTIC_SAMPLE_COLUMNS run ``ALTER TABLE samples DROP COLUMN <name>``,
|
||||
then ``PRAGMA user_version=6``. Dropping loses only the new counters.
|
||||
"""
|
||||
cols = {row[1] for row in conn.execute("PRAGMA table_info(samples)").fetchall()}
|
||||
if not cols:
|
||||
return
|
||||
for column in DIAGNOSTIC_SAMPLE_COLUMNS:
|
||||
if column not in cols:
|
||||
conn.execute(f"ALTER TABLE samples ADD COLUMN {column} INTEGER")
|
||||
|
||||
|
||||
def migrate_to_latest(store_path: Path) -> int:
|
||||
"""Apply forward-only migrations to bring the store to SCHEMA_VERSION.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user