Analyze API
Functions wrapping systemd-analyze for boot analysis, security scoring,
unit verification, and critical-chain inspection.
These are available as methods on SystemdClient / AsyncSystemdClient
(e.g., client.analyze_blame()), but are implemented in the
systemd_client._analyze module.
Module functions
systemd_client._analyze
systemd-analyze wrapper for boot analysis and security scoring.
analyze_blame(scope)
async
Parse systemd-analyze blame output into BlameEntry list.
Source code in src/systemd_client/_analyze.py
| async def analyze_blame(scope: SystemdScope) -> list[BlameEntry]:
"""Parse systemd-analyze blame output into BlameEntry list."""
stdout = await _run_analyze(scope, "blame", "--no-pager")
entries: list[BlameEntry] = []
for line in stdout.splitlines():
line = line.strip()
if not line:
continue
# Format: "32.875s pmlogger.service" or "245ms dbus.service"
match = re.match(r"^\s*([\d.]+)(min|s|ms|us)\s+(.+)$", line)
if match:
val, unit_str, name = match.groups()
multipliers = {"us": 1, "ms": 1000, "s": 1_000_000, "min": 60_000_000}
time_us = int(float(val) * multipliers.get(unit_str, 1))
entries.append(BlameEntry(time_us=time_us, unit=name))
return entries
|
analyze_critical_chain(scope, unit=None)
async
Return systemd-analyze critical-chain output as raw text.
Source code in src/systemd_client/_analyze.py
| async def analyze_critical_chain(scope: SystemdScope, unit: str | None = None) -> str:
"""Return systemd-analyze critical-chain output as raw text."""
args = ["critical-chain", "--no-pager"]
if unit:
args.append(unit)
return await _run_analyze(scope, *args)
|
analyze_security(scope, unit)
async
Parse systemd-analyze security output for a specific unit.
Source code in src/systemd_client/_analyze.py
| async def analyze_security(scope: SystemdScope, unit: str) -> SecurityAnalysis:
"""Parse systemd-analyze security output for a specific unit."""
stdout = await _run_analyze(scope, "security", "--json=short", unit)
data = json.loads(stdout) if stdout.strip() else []
# JSON output is a list of unit analyses
for entry in data:
if entry.get("unit", "") == unit or len(data) == 1:
exposure = float(entry.get("exposure", 10.0))
issues: list[SecurityIssue] = []
for pred in entry.get("predicates", []):
issues.append(SecurityIssue(
id=pred.get("set_name", ""),
description=pred.get("description", ""),
severity=pred.get("badness_description", ""),
value=pred.get("value", ""),
))
return SecurityAnalysis(unit=unit, exposure=exposure, issues=issues)
return SecurityAnalysis(unit=unit, exposure=10.0)
|
analyze_verify(scope, unit)
async
Run systemd-analyze verify and return diagnostic messages.
Source code in src/systemd_client/_analyze.py
| async def analyze_verify(scope: SystemdScope, unit: str) -> list[str]:
"""Run systemd-analyze verify and return diagnostic messages."""
try:
stdout = await _run_analyze(scope, "verify", unit)
except SubprocessError as exc:
# verify returns non-zero on warnings, but stderr has the messages
return [line for line in exc.stderr.splitlines() if line.strip()]
return [line for line in stdout.splitlines() if line.strip()]
|