Добавлен сбор телеметрии на ВМ2
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from time import perf_counter
|
||||
|
||||
from app.config import ActiveConfig
|
||||
from app.contracts import CheckRequest, FileCheck, Pending, TextCheck, Verdict
|
||||
@@ -19,6 +20,14 @@ from app.normalization import normalize_text
|
||||
from app.rate_limit import ConservativeRateLimiter
|
||||
from app.repository import QueueFull, Repository
|
||||
from app.settings import EmergencyMode
|
||||
from app.telemetry import (
|
||||
current_trace_fields,
|
||||
record_cache,
|
||||
record_check,
|
||||
record_dependency,
|
||||
record_file_rejection,
|
||||
record_runtime_state,
|
||||
)
|
||||
from app.url_policy import DnsError, Resolver, canonicalize, check_url, extract_urls
|
||||
|
||||
|
||||
@@ -54,6 +63,7 @@ class SafetyService:
|
||||
self.rate_limiter = ConservativeRateLimiter(
|
||||
config.document["rate"]["text_rps"], config.document["rate"]["file_rps"]
|
||||
)
|
||||
record_runtime_state("mock" if mode.mock else "standard", config.version)
|
||||
|
||||
def _verdict(
|
||||
self,
|
||||
@@ -74,6 +84,22 @@ class SafetyService:
|
||||
)
|
||||
|
||||
async def check(self, request: CheckRequest) -> Verdict | Pending:
|
||||
started = perf_counter()
|
||||
outcome = "error"
|
||||
try:
|
||||
result = await self._check(request)
|
||||
outcome = "pending" if isinstance(result, Pending) else result.verdict
|
||||
return result
|
||||
finally:
|
||||
record_check(
|
||||
request.content_kind,
|
||||
"mock" if self.mode.mock else "standard",
|
||||
outcome,
|
||||
(perf_counter() - started) * 1000,
|
||||
self.config.version,
|
||||
)
|
||||
|
||||
async def _check(self, request: CheckRequest) -> Verdict | Pending:
|
||||
digest = fingerprint(request)
|
||||
existing = await self.repository.get_request(request.message_id)
|
||||
if existing:
|
||||
@@ -101,6 +127,7 @@ class SafetyService:
|
||||
cache = await self.repository.text_cache(
|
||||
normalized.analysis_sha256, self.config.rules_version
|
||||
)
|
||||
record_cache("text_rules", cache is not None)
|
||||
if cache:
|
||||
deny_rule = cache.deny_rule_id
|
||||
else:
|
||||
@@ -145,6 +172,7 @@ class SafetyService:
|
||||
cached_link = await self.repository.link_cache(
|
||||
canonical.digest, self.config.rules_version, self.config.version
|
||||
)
|
||||
record_cache("link_verdict", cached_link is not None)
|
||||
if cached_link and cached_link.verdict == "deny":
|
||||
return await self._persist_sync(
|
||||
request,
|
||||
@@ -160,7 +188,9 @@ class SafetyService:
|
||||
_, rule = await check_url(
|
||||
raw, self.resolver, self.config.document["link"]["dns_lookup_timeout_sec"]
|
||||
)
|
||||
record_dependency("dns", "resolve", "success")
|
||||
except DnsError as exc:
|
||||
record_dependency("dns", "resolve", "error")
|
||||
raise CapabilityUnavailable("dns") from exc
|
||||
if rule != "url.nxdomain" and not cached_link:
|
||||
now = datetime.now(UTC)
|
||||
@@ -200,6 +230,7 @@ class SafetyService:
|
||||
set(self.config.document["file_policy"]["enabled_mime_types"]),
|
||||
)
|
||||
if rule:
|
||||
record_file_rejection(rule)
|
||||
return await self._persist_sync(
|
||||
request, digest, self._verdict(False, "standard", rule, self.config.rules_version)
|
||||
)
|
||||
@@ -207,6 +238,7 @@ class SafetyService:
|
||||
cached = await self.repository.file_cache(
|
||||
content_digest, self.config, self.signatures_version
|
||||
)
|
||||
record_cache("file_verdict", cached is not None)
|
||||
if cached:
|
||||
return await self._persist_sync(
|
||||
request,
|
||||
@@ -220,6 +252,7 @@ class SafetyService:
|
||||
)
|
||||
now = datetime.now(UTC)
|
||||
task_id = uuid.uuid4()
|
||||
trace_id, span_id, trace_flags, tracestate = current_trace_fields()
|
||||
task = SafetyTask(
|
||||
id=task_id,
|
||||
message_id=request.message_id,
|
||||
@@ -243,6 +276,10 @@ class SafetyService:
|
||||
detector_version=self.config.detector.version,
|
||||
scanner_engine="clamav",
|
||||
signatures_version=self.signatures_version,
|
||||
origin_trace_id=trace_id,
|
||||
origin_span_id=span_id,
|
||||
origin_trace_flags=trace_flags,
|
||||
origin_tracestate=tracestate,
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
@@ -262,6 +299,7 @@ class SafetyService:
|
||||
row, task, max_pending=self.config.document["task"]["max_pending"]
|
||||
)
|
||||
except QueueFull as exc:
|
||||
record_dependency("postgresql", "queue_capacity", "full")
|
||||
raise CapabilityUnavailable("queue_capacity") from exc
|
||||
if created:
|
||||
await self._audit(
|
||||
|
||||
Reference in New Issue
Block a user