homelab-codex-ws/services/ha-diag-agent/src/ha_diag/event_emitter.py
Oskar Kapala 07bd498fd6 feat(ha-diag-agent): test environment with dual HA Docker instances
- dockerized ken + chelsty HA test instances with template fixtures
- snapshot/reset/wait scripts for fixture management
- integration test infrastructure with separate marker
- location_tag promoted from metadata to event payload (Phase 1 flag #3)
- chelsty-infra target_url points to chelsty-ha via tailnet (Phase 1 flag #1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:56:13 +02:00

62 lines
1.9 KiB
Python

from __future__ import annotations
import json
import re
import time
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
from .models import EventRecord
class EventEmitter:
"""Writes atomic JSON event files to the events directory."""
def __init__(
self, events_dir: Path, node_name: str, location_tag: str = ""
) -> None:
self._events_dir = events_dir
self._node_name = node_name
self._location_tag = location_tag
self._seq = 0
events_dir.mkdir(parents=True, exist_ok=True)
def _make_id(self, event_type: str, service: str) -> str:
# Sequence suffix guarantees uniqueness even when multiple events of the
# same type are emitted within the same millisecond.
self._seq += 1
ts = int(time.time())
svc_slug = re.sub(r"[^a-z0-9]", "-", (service or "ha").lower())[:32].strip("-")
return f"evt-{self._node_name}-{ts}-{event_type}-{svc_slug}-{self._seq}"
def emit(
self,
event_type: str,
severity: str,
service: str,
message: str,
payload: dict[str, Any] | None = None,
) -> str:
event_id = self._make_id(event_type, service)
merged: dict[str, Any] = {}
if self._location_tag:
merged["location_tag"] = self._location_tag
merged.update(payload or {})
record = EventRecord(
id=event_id,
timestamp=int(time.time()),
date=datetime.now(timezone.utc).isoformat(),
type=event_type,
severity=severity,
node=self._node_name,
service=service,
message=message,
payload=merged,
)
path = self._events_dir / f"{event_id}.json"
tmp = path.with_suffix(".tmp")
tmp.write_text(json.dumps(record.model_dump(), indent=2))
tmp.rename(path)
return event_id