worked poc

This commit is contained in:
Mateusz Gruszczyński
2026-08-14 11:33:01 +02:00
parent adfdb0b86c
commit fc3a2944b2
94 changed files with 2931 additions and 3412 deletions
+56 -2
View File
@@ -2,12 +2,19 @@ from __future__ import annotations
import threading
from datetime import datetime, timezone
from typing import Any
class RuntimeStats:
def __init__(self) -> None:
self._lock = threading.Lock()
self._data = {
self._data = self._new_counters()
self._suricata: dict[str, int | float] = {}
self._suricata_timestamp: str | None = None
@staticmethod
def _new_counters() -> dict[str, Any]:
return {
"tzsp_datagrams": 0,
"tzsp_decode_errors": 0,
"tzsp_unsupported": 0,
@@ -16,6 +23,11 @@ class RuntimeStats:
"eve_events": 0,
"eve_alerts": 0,
"eve_parse_errors": 0,
"alerts_filtered": 0,
"alerts_filtered_low_priority": 0,
"alerts_filtered_ignored_sid": 0,
"alerts_filtered_ignored_category": 0,
"alerts_deduplicated": 0,
"block_attempts": 0,
"block_success": 0,
"block_errors": 0,
@@ -31,6 +43,48 @@ class RuntimeStats:
with self._lock:
self._data[key] = datetime.now(timezone.utc).isoformat()
def update_suricata(self, stats: dict[str, Any], timestamp: str | None = None) -> None:
flattened: dict[str, int | float] = {}
_flatten_numeric("", stats, flattened, 240)
with self._lock:
self._suricata = flattened
self._suricata_timestamp = timestamp or datetime.now(timezone.utc).isoformat()
def reset(self) -> None:
with self._lock:
last_packet = self._data.get("last_packet_at")
last_alert = self._data.get("last_alert_at")
self._data = self._new_counters()
self._data["last_packet_at"] = last_packet
self._data["last_alert_at"] = last_alert
def snapshot(self) -> dict:
with self._lock:
return dict(self._data)
data = dict(self._data)
data["suricata"] = dict(self._suricata)
data["suricata_stats_at"] = self._suricata_timestamp
datagrams = int(data.get("tzsp_datagrams", 0))
frames = int(data.get("frames_injected", 0))
data["tzsp_to_tap_loss"] = max(datagrams - frames, 0)
attempts = int(data.get("block_attempts", 0))
success = int(data.get("block_success", 0))
data["block_success_rate"] = round((success / attempts) * 100.0, 2) if attempts else None
return data
def _flatten_numeric(
prefix: str,
value: Any,
output: dict[str, int | float],
limit: int,
) -> None:
if len(output) >= limit:
return
if isinstance(value, dict):
for key, child in value.items():
name = f"{prefix}.{key}" if prefix else str(key)
_flatten_numeric(name, child, output, limit)
if len(output) >= limit:
return
elif isinstance(value, (int, float)) and not isinstance(value, bool):
output[prefix] = value