Fixed issues with telemetry.
This commit is contained in:
@@ -34,6 +34,8 @@ DEFAULT_TELEMETRY_ENDPOINT = "https://pristontale.eu/api/launcher/telemetry"
|
||||
TELEMETRY_ENDPOINT_VARIABLE = "PTLINUX_TELEMETRY_ENDPOINT"
|
||||
TELEMETRY_KEY_VARIABLE = "PTLINUX_TELEMETRY_KEY"
|
||||
TELEMETRY_DEBUG_VARIABLE = "PTLINUX_TELEMETRY_DEBUG"
|
||||
TELEMETRY_PROCESS_ROLE_VARIABLE = "PTLINUX_TELEMETRY_PROCESS_ROLE"
|
||||
TELEMETRY_OPERATION_PROCESS_ROLE = "operation"
|
||||
|
||||
MAX_REQUEST_BYTES = 64 * 1024
|
||||
MAX_MESSAGE_BYTES = 10 * 1024
|
||||
@@ -263,9 +265,14 @@ class TelemetryService:
|
||||
self._session_metadata = dict(session_metadata or {})
|
||||
self._monotonic = monotonic
|
||||
self._started_at = monotonic()
|
||||
self._reports_launcher_lifecycle = (
|
||||
self._environment.get(TELEMETRY_PROCESS_ROLE_VARIABLE, "").strip().casefold()
|
||||
!= TELEMETRY_OPERATION_PROCESS_ROLE
|
||||
)
|
||||
self._enabled = bool(enabled)
|
||||
self._active = False
|
||||
self._accepting = False
|
||||
self._closing = False
|
||||
self._ready = False
|
||||
self._first_run = False
|
||||
self._installation_id: str | None = None
|
||||
@@ -322,6 +329,7 @@ class TelemetryService:
|
||||
self._base_payload = self._collect_common_payload(first_seen)
|
||||
self._stop.clear()
|
||||
self._accepting = True
|
||||
self._closing = False
|
||||
self._active = True
|
||||
worker = threading.Thread(
|
||||
target=self._worker_loop,
|
||||
@@ -338,15 +346,16 @@ class TelemetryService:
|
||||
self._debug_log(f"initialization failed: {type(exc).__name__}")
|
||||
return
|
||||
|
||||
self.send_event(
|
||||
"launcher_started",
|
||||
metadata={"cold_start": True, **self._session_metadata},
|
||||
)
|
||||
if self._first_run:
|
||||
if self._reports_launcher_lifecycle:
|
||||
self.send_event(
|
||||
"first_run_started",
|
||||
metadata={"install_type": self._install_type()},
|
||||
"launcher_started",
|
||||
metadata={"cold_start": True, **self._session_metadata},
|
||||
)
|
||||
if self._first_run:
|
||||
self.send_event(
|
||||
"first_run_started",
|
||||
metadata={"install_type": self._install_type()},
|
||||
)
|
||||
self._start_environment_collection()
|
||||
|
||||
def set_enabled(self, enabled: bool) -> None:
|
||||
@@ -368,6 +377,8 @@ class TelemetryService:
|
||||
if self._ready or not self._active:
|
||||
return
|
||||
self._ready = True
|
||||
if not self._reports_launcher_lifecycle:
|
||||
return
|
||||
duration_ms = round((self._monotonic() - self._started_at) * 1000)
|
||||
self.send_event(
|
||||
"launcher_ready",
|
||||
@@ -674,11 +685,12 @@ class TelemetryService:
|
||||
self._send_repeated_error(state)
|
||||
|
||||
def shutdown(self, timeout_seconds: float = SHUTDOWN_WAIT_SECONDS) -> None:
|
||||
"""Queue the closing event and give the daemon worker a bounded flush."""
|
||||
"""Finish this process role and give the daemon worker a bounded flush."""
|
||||
|
||||
with self._state_lock:
|
||||
if not self._active:
|
||||
if not self._active or self._closing:
|
||||
return
|
||||
self._closing = True
|
||||
deadline = time.monotonic() + max(0.0, timeout_seconds)
|
||||
environment_worker = self._environment_worker
|
||||
if isinstance(environment_worker, threading.Thread) and (
|
||||
@@ -692,17 +704,18 @@ class TelemetryService:
|
||||
)
|
||||
self._flush_repeated_errors()
|
||||
runtime_seconds = max(0, round(self._monotonic() - self._started_at))
|
||||
if self._first_run and not self._ready:
|
||||
if self._reports_launcher_lifecycle:
|
||||
if self._first_run and not self._ready:
|
||||
self.send_event(
|
||||
"first_run_failed",
|
||||
severity="error",
|
||||
message="Launcher did not reach the ready state",
|
||||
metadata={"duration_ms": runtime_seconds * 1000},
|
||||
)
|
||||
self.send_event(
|
||||
"first_run_failed",
|
||||
severity="error",
|
||||
message="Launcher did not reach the ready state",
|
||||
metadata={"duration_ms": runtime_seconds * 1000},
|
||||
"launcher_closed",
|
||||
metadata={"runtime_seconds": runtime_seconds, **self._session_metadata},
|
||||
)
|
||||
self.send_event(
|
||||
"launcher_closed",
|
||||
metadata={"runtime_seconds": runtime_seconds, **self._session_metadata},
|
||||
)
|
||||
with self._state_lock:
|
||||
self._accepting = False
|
||||
self._stop.set()
|
||||
@@ -719,6 +732,7 @@ class TelemetryService:
|
||||
with self._state_lock:
|
||||
self._enabled = False
|
||||
self._accepting = False
|
||||
self._closing = True
|
||||
self._stop.set()
|
||||
self._repeated_errors.clear()
|
||||
while True:
|
||||
@@ -795,6 +809,11 @@ class TelemetryService:
|
||||
self._base_payload[key] = {**existing, **value}
|
||||
else:
|
||||
self._base_payload[key] = value
|
||||
if not self._reports_launcher_lifecycle:
|
||||
# Dashboard operation subprocesses enrich their own events with the
|
||||
# detected environment, while the dashboard remains the sole source
|
||||
# of launcher lifecycle and automatic compatibility events.
|
||||
return
|
||||
|
||||
runtime = sanitized.get("runtime")
|
||||
dependencies = sanitized.get("dependencies")
|
||||
@@ -816,14 +835,38 @@ class TelemetryService:
|
||||
context={"operation": "launcher", "stage": "environment_detection"},
|
||||
)
|
||||
missing_required = dependency_details.get("missing_required")
|
||||
if dependency_details.get("healthy") is False:
|
||||
generic_dependency_failures = (
|
||||
[
|
||||
str(value)
|
||||
for value in missing_required
|
||||
if isinstance(value, str) and value
|
||||
]
|
||||
if isinstance(missing_required, list)
|
||||
else []
|
||||
)
|
||||
if (
|
||||
dependency_details.get("container_ready") is False
|
||||
and "container_host" not in generic_dependency_failures
|
||||
):
|
||||
generic_dependency_failures.append("container_host")
|
||||
if (
|
||||
dependency_details.get("healthy") is False
|
||||
and generic_dependency_failures
|
||||
):
|
||||
self.send_event(
|
||||
"dependency_check_failed",
|
||||
severity="warning",
|
||||
message="One or more launcher dependencies are unavailable",
|
||||
metadata={
|
||||
"dependencies": (
|
||||
missing_required if isinstance(missing_required, list) else []
|
||||
"dependencies": generic_dependency_failures,
|
||||
"required_shared_libraries_present": dependency_details.get(
|
||||
"required_shared_libraries_present"
|
||||
),
|
||||
"vulkan_64bit_available": dependency_details.get(
|
||||
"vulkan_64bit_available"
|
||||
),
|
||||
"vulkan_32bit_available": dependency_details.get(
|
||||
"vulkan_32bit_available"
|
||||
),
|
||||
},
|
||||
context={"operation": "launcher", "stage": "dependency_check"},
|
||||
@@ -846,7 +889,17 @@ class TelemetryService:
|
||||
self.send_event(
|
||||
"vulkan_32bit_check_failed",
|
||||
severity="warning",
|
||||
metadata={"dependency": "vulkan_32bit", "check": "32bit_vulkan"},
|
||||
metadata={
|
||||
"dependency": "vulkan_32bit",
|
||||
"check": "32bit_vulkan",
|
||||
"loader_available": runtime_details.get(
|
||||
"vulkan_32bit_loader_available"
|
||||
),
|
||||
"icd_available": runtime_details.get(
|
||||
"vulkan_32bit_icd_available"
|
||||
),
|
||||
"detection": runtime_details.get("vulkan_32bit_detection"),
|
||||
},
|
||||
context={"operation": "launcher", "stage": "vulkan_check"},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user