diff --git a/strix/report/state.py b/strix/report/state.py index 3dbc9772..9dede601 100644 --- a/strix/report/state.py +++ b/strix/report/state.py @@ -135,6 +135,10 @@ class ReportState: self._sarif_repo_ctx: dict[str, Any] | None = None self._sarif_repo_ctx_ready: bool = False + self.posthog_scan_ended_sent: bool = False + self.scarf_scan_ended_sent: bool = False + self.scan_ended_exit_reason: str | None = None + def get_run_dir(self) -> Path: if self._run_dir is None: run_dir_name = self.run_name if self.run_name else self.run_id diff --git a/strix/telemetry/posthog.py b/strix/telemetry/posthog.py index d1a9b460..df6bed4d 100644 --- a/strix/telemetry/posthog.py +++ b/strix/telemetry/posthog.py @@ -26,10 +26,10 @@ def _is_enabled() -> bool: return load_settings().telemetry.enabled -def _send(event: str, properties: dict[str, Any]) -> None: +def _send(event: str, properties: dict[str, Any]) -> bool: if not _is_enabled(): logger.debug("posthog disabled; skipping event %s", event) - return + return False try: payload = { "api_key": _POSTHOG_PUBLIC_API_KEY, @@ -46,8 +46,10 @@ def _send(event: str, properties: dict[str, Any]) -> None: pass except Exception: # noqa: BLE001 logger.debug("posthog send failed for event %s", event, exc_info=True) + return False else: logger.debug("posthog event sent: %s", event) + return True def start( @@ -82,6 +84,11 @@ def finding(severity: str) -> None: def end(report_state: "ReportState", exit_reason: str = "completed") -> None: + if report_state.posthog_scan_ended_sent: + return + if report_state.scan_ended_exit_reason is None: + report_state.scan_ended_exit_reason = exit_reason + vulnerabilities_counts = {"critical": 0, "high": 0, "medium": 0, "low": 0, "info": 0} for v in report_state.vulnerability_reports: sev = v.get("severity", "info").lower() @@ -110,11 +117,11 @@ def end(report_state: "ReportState", exit_reason: str = "completed") -> None: except (TypeError, ValueError, AttributeError): pass - _send( + report_state.posthog_scan_ended_sent = _send( "scan_ended", { **base_props(), - "exit_reason": exit_reason, + "exit_reason": report_state.scan_ended_exit_reason, "duration_seconds": round(duration), "vulnerabilities_total": len(report_state.vulnerability_reports), **{f"vulnerabilities_{k}": v for k, v in vulnerabilities_counts.items()}, diff --git a/strix/telemetry/scarf.py b/strix/telemetry/scarf.py index 037494bb..6e48570c 100644 --- a/strix/telemetry/scarf.py +++ b/strix/telemetry/scarf.py @@ -28,10 +28,10 @@ def _is_enabled() -> bool: return load_settings().telemetry.enabled -def _send(event: str, properties: dict[str, Any]) -> None: +def _send(event: str, properties: dict[str, Any]) -> bool: if not _is_enabled(): logger.debug("scarf disabled; skipping event %s", event) - return + return False try: props = dict(properties) version = str(props.pop("strix_version", get_version()) or "unknown") @@ -47,8 +47,10 @@ def _send(event: str, properties: dict[str, Any]) -> None: pass except Exception: # noqa: BLE001 logger.debug("scarf send failed for event %s", event, exc_info=True) + return False else: logger.debug("scarf event sent: %s", event) + return True def start( @@ -85,6 +87,11 @@ def finding(severity: str) -> None: def end(report_state: ReportState, exit_reason: str = "completed") -> None: + if report_state.scarf_scan_ended_sent: + return + if report_state.scan_ended_exit_reason is None: + report_state.scan_ended_exit_reason = exit_reason + vulnerabilities_counts = {"critical": 0, "high": 0, "medium": 0, "low": 0, "info": 0} for v in report_state.vulnerability_reports: sev = v.get("severity", "info").lower() @@ -115,12 +122,12 @@ def end(report_state: ReportState, exit_reason: str = "completed") -> None: except (TypeError, ValueError, AttributeError): pass - _send( + report_state.scarf_scan_ended_sent = _send( "scan_ended", { **base_props(), "session": SESSION_ID, - "exit_reason": exit_reason, + "exit_reason": report_state.scan_ended_exit_reason, "duration_seconds": round(duration), "vulnerabilities_total": len(report_state.vulnerability_reports), **{f"vulnerabilities_{k}": v for k, v in vulnerabilities_counts.items()},