-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiagnostics.py
More file actions
53 lines (40 loc) · 1.64 KB
/
Copy pathdiagnostics.py
File metadata and controls
53 lines (40 loc) · 1.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from __future__ import annotations
from collections import deque
from dataclasses import dataclass
from datetime import datetime, timezone
def _now() -> datetime:
return datetime.now(timezone.utc)
def _format_time(value: datetime | None) -> str:
return value.astimezone().strftime("%d.%m.%Y %H:%M:%S") if value else "нет"
@dataclass(frozen=True)
class RuntimeErrorInfo:
source: str
message: str
created_at: datetime
class Diagnostics:
def __init__(self) -> None:
self.started_at = _now()
self.ai_last_success_at: datetime | None = None
self.ai_last_error: RuntimeErrorInfo | None = None
self.errors: deque[RuntimeErrorInfo] = deque(maxlen=20)
def record_ai_success(self) -> None:
self.ai_last_success_at = _now()
self.ai_last_error = None
def record_error(self, source: str, message: str) -> None:
error = RuntimeErrorInfo(source=source, message=message[:300], created_at=_now())
self.errors.appendleft(error)
if source == "AI":
self.ai_last_error = error
def status_text(self, phrase_count: int) -> str:
last_error = self.errors[0] if self.errors else None
return (
"📊 Статус бота\n\n"
"Бот: работает\n"
f"Запрещенных фраз: {phrase_count}\n"
f"Последняя ошибка: {self._format_error(last_error)}"
)
@staticmethod
def _format_error(error: RuntimeErrorInfo | None) -> str:
if not error:
return "нет"
return f"{error.source}: {error.message} ({_format_time(error.created_at)})"