4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
97 lines
2.5 KiB
Python
97 lines
2.5 KiB
Python
"""Typed records for Hermes log lines and detected incidents.
|
|
|
|
These types are deliberately lightweight (frozen dataclasses) so they can be
|
|
passed across thread boundaries from the tailer/parser into the classifier
|
|
and out to subscribers without locking concerns.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from enum import StrEnum
|
|
from typing import Final
|
|
|
|
|
|
class LogLevel(StrEnum):
|
|
"""Subset of Python logging levels we track from Hermes logs."""
|
|
|
|
DEBUG = "DEBUG"
|
|
INFO = "INFO"
|
|
WARNING = "WARNING"
|
|
ERROR = "ERROR"
|
|
CRITICAL = "CRITICAL"
|
|
|
|
@property
|
|
def severity_rank(self) -> int:
|
|
# Used for severity comparisons in the classifier; higher = worse.
|
|
return _LEVEL_RANK[self]
|
|
|
|
|
|
_LEVEL_RANK: Final[dict[LogLevel, int]] = {
|
|
LogLevel.DEBUG: 10,
|
|
LogLevel.INFO: 20,
|
|
LogLevel.WARNING: 30,
|
|
LogLevel.ERROR: 40,
|
|
LogLevel.CRITICAL: 50,
|
|
}
|
|
|
|
|
|
class IncidentSeverity(StrEnum):
|
|
"""Incident severity emitted by the classifier."""
|
|
|
|
LOW = "low"
|
|
MEDIUM = "medium"
|
|
HIGH = "high"
|
|
CRITICAL = "critical"
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class LogRecord:
|
|
"""A single parsed Hermes log line.
|
|
|
|
``raw`` retains the original line (without its trailing newline) so
|
|
downstream consumers can render the unmodified source for debugging.
|
|
Continuation lines (e.g. traceback frames) appear as records with the
|
|
same level as their parent and an empty ``logger``.
|
|
"""
|
|
|
|
timestamp: datetime
|
|
level: LogLevel
|
|
logger: str
|
|
message: str
|
|
raw: str
|
|
run_id: str | None = None
|
|
is_continuation: bool = False
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class HermesIncident:
|
|
"""An incident identified from one or more Hermes log records.
|
|
|
|
``rule`` is the classifier rule that produced the incident (e.g.
|
|
``"error_severity"``, ``"warning_burst"``, ``"traceback"``); it is
|
|
stable across runs and intended for both routing and metrics.
|
|
|
|
``fingerprint`` is a deterministic identifier derived from the rule
|
|
and the contributing logger/message so downstream alerting can
|
|
deduplicate without re-parsing the records.
|
|
"""
|
|
|
|
rule: str
|
|
severity: IncidentSeverity
|
|
title: str
|
|
detected_at: datetime
|
|
logger: str
|
|
fingerprint: str
|
|
records: tuple[LogRecord, ...] = field(default_factory=tuple)
|
|
run_id: str | None = None
|
|
|
|
|
|
__all__ = [
|
|
"HermesIncident",
|
|
"IncidentSeverity",
|
|
"LogLevel",
|
|
"LogRecord",
|
|
]
|