Added telemetry system to get information about issues.

This commit is contained in:
2026-09-07 21:49:37 +02:00
parent bea9d6fda7
commit f06fc2e4e3
16 changed files with 4125 additions and 169 deletions

View File

@@ -12,6 +12,7 @@ import re
import subprocess
import sys
import tempfile
import time
from typing import Callable, Mapping, Sequence
from . import __version__
@@ -301,16 +302,30 @@ def repair_container_host(
files=files,
command_executor=command_executor,
)
started_at = time.monotonic()
_send_dependency_fix_event(
"dependency_fix_requested",
metadata={"reason": "container_host", "issue": before.issue},
stage="requested",
)
_send_dependency_fix_event(
"dependency_fix_started",
metadata={"issue": before.issue, "repairable": before.repairable},
stage="started",
)
if before.ready and not before.broken_umu_profile_link:
_send_dependency_fix_outcome(before, started_at)
return before
if not before.repairable:
return replace(
result = replace(
before,
repair_attempted=True,
repair_error=(
before.recommendation or "No safe automatic repair is available."
),
)
_send_dependency_fix_outcome(result, started_at)
return result
actions: list[str] = []
created_managed_profile = False
profile_loaded = False
@@ -372,12 +387,14 @@ def repair_container_host(
error = str(exc)
if rollback_error:
error = f"{error}; rollback also failed: {rollback_error}"
return replace(
result = replace(
after_failure,
repair_attempted=True,
repair_actions=tuple(actions),
repair_error=error,
)
_send_dependency_fix_outcome(result, started_at)
return result
after = inspect_container_host(
environment=environment,
@@ -391,13 +408,63 @@ def repair_container_host(
"still fails. "
+ (after.recommendation or "Inspect the host security policy.")
)
return replace(
result = replace(
after,
repair_attempted=True,
repaired=after.ready,
repair_actions=tuple(actions),
repair_error=error,
)
_send_dependency_fix_outcome(result, started_at)
return result
def _send_dependency_fix_outcome(
report: ContainerHostReport,
started_at: float,
) -> None:
success = report.ready and not report.broken_umu_profile_link and (
report.repair_error is None
)
_send_dependency_fix_event(
"dependency_fix_success" if success else "dependency_fix_failed",
severity="info" if success else "error",
message=None if success else report.repair_error,
metadata={
"duration_ms": round((time.monotonic() - started_at) * 1000),
"ready": report.ready,
"repaired": report.repaired,
"repair_attempted": report.repair_attempted,
"action_count": len(report.repair_actions),
"issue": report.issue,
},
stage="completed" if success else "repair",
)
def _send_dependency_fix_event(
event: str,
*,
severity: str = "info",
message: str | None = None,
metadata: Mapping[str, object] | None = None,
stage: str,
) -> None:
try:
from .telemetry import current_telemetry
telemetry = current_telemetry()
if telemetry is not None:
telemetry.send_event(
event,
severity=severity,
message=message,
metadata=metadata,
context={"operation": "dependency_fix", "stage": stage},
)
except Exception:
# Host recovery must remain independent from optional telemetry.
pass
def repair_container_host_after_update(paths: AppPaths) -> ContainerHostReport: