Files
microdao-daarion/crews/agromatrix_crew/telemetry.py
Apple 129e4ea1fc feat(platform): add new services, tools, tests and crews modules
New router intelligence modules (26 files): alert_ingest/store, audit_store,
architecture_pressure, backlog_generator/store, cost_analyzer, data_governance,
dependency_scanner, drift_analyzer, incident_* (5 files), llm_enrichment,
platform_priority_digest, provider_budget, release_check_runner, risk_* (6 files),
signature_state_store, sofiia_auto_router, tool_governance

New services:
- sofiia-console: Dockerfile, adapters/, monitor/nodes/ops/voice modules, launchd, react static
- memory-service: integration_endpoints, integrations, voice_endpoints, static UI
- aurora-service: full app suite (analysis, job_store, orchestrator, reporting, schemas, subagents)
- sofiia-supervisor: new supervisor service
- aistalk-bridge-lite: Telegram bridge lite
- calendar-service: CalDAV calendar service with reminders
- mlx-stt-service / mlx-tts-service: Apple Silicon speech services
- binance-bot-monitor: market monitor service
- node-worker: STT/TTS memory providers

New tools (9): agent_email, browser_tool, contract_tool, observability_tool,
oncall_tool, pr_reviewer_tool, repo_tool, safe_code_executor, secure_vault

New crews: agromatrix_crew (10 modules: depth_classifier, doc_facts, doc_focus,
farm_state, light_reply, llm_factory, memory_manager, proactivity, reflection_engine,
session_context, style_adapter, telemetry)

Tests: 85+ test files for all new modules
Made-with: Cursor
2026-03-03 07:14:14 -08:00

118 lines
4.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Telemetry helpers для Humanized Stepan v2.7.2.
Забезпечує єдиний тег AGX_STEPAN_METRIC на всіх ключових лог-рядках
і PII-safe анонімізацію ідентифікаторів.
Grep у проді:
grep "AGX_STEPAN_METRIC" /logs/gateway.log
Формат рядка:
AGX_STEPAN_METRIC <event> key=value key2=value2
PII-safe:
- Ключі з pii_keys (default: {"user_id","chat_id"}) автоматично анонімізуються:
user_id=h:3f9a12b4c7 (sha256 перших 10 hex-символів)
- Дає можливість корелювати події одного користувача без прямого витоку.
- Не є криптографічним захистом проти таргетованого знання.
Правила серіалізації:
- bool → "true" / "false"
- int/float → str
- list → елементи через кому
- dict → компактний JSON
- None → "null"
- Нічого з секретів/токенів не передавати у kv.
"""
from __future__ import annotations
import hashlib
import json
import logging
from typing import Any
TELEMETRY_TAG = "AGX_STEPAN_METRIC"
# Ключі, які автоматично анонімізуються у tlog()
_DEFAULT_PII_KEYS: frozenset[str] = frozenset({"user_id", "chat_id"})
def anonymize_id(value: str | None) -> str | None:
"""
Повертає PII-safe псевдонім для ідентифікатора.
Правила:
- None → None
- Пусте рядок → повернути як є (нема що хешувати)
- Інакше: "h:" + sha256(value)[:10]
Формат стабільний: завжди 12 символів ("h:" + 10 hex).
Колізії теоретично можливі, але практично нереальні для user_id-просторів.
Приклади:
anonymize_id("123456789") → "h:3f9a12b4c7"
anonymize_id(None) → None
anonymize_id("") → ""
"""
if value is None:
return None
if not value:
return value
try:
digest = hashlib.sha256(value.encode()).hexdigest()
return f"h:{digest[:10]}"
except Exception:
return "h:error"
def _fmt_value(v: Any) -> str:
if isinstance(v, bool):
return str(v).lower()
if isinstance(v, (int, float)):
return str(v)
if v is None:
return "null"
if isinstance(v, list):
return ",".join(str(i) for i in v)
if isinstance(v, dict):
return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
return str(v)
def tlog(
logger: logging.Logger,
msg: str,
level: int = logging.INFO,
pii_keys: frozenset[str] | set[str] = _DEFAULT_PII_KEYS,
**kv: Any,
) -> None:
"""
Логує рядок з уніфікованим тегом AGX_STEPAN_METRIC і PII-safe анонімізацією.
Приклади:
tlog(logger, "depth", depth="light", reason="greeting")
"AGX_STEPAN_METRIC depth depth=light reason=greeting"
tlog(logger, "memory_save", user_id="123456789", ok=True)
"AGX_STEPAN_METRIC memory_save user_id=h:3f9a12b4c7 ok=true"
Ключі в pii_keys автоматично анонімізуються через anonymize_id().
Безпечний: всі помилки форматування ігноруються — fallback без kv.
"""
try:
parts: list[str] = []
for k, v in kv.items():
if k in pii_keys:
anon = anonymize_id(str(v) if v is not None else None)
parts.append(f"{k}={_fmt_value(anon)}")
else:
parts.append(f"{k}={_fmt_value(v)}")
kv_str = " ".join(parts)
line = f"{TELEMETRY_TAG} {msg}"
if kv_str:
line = f"{line} {kv_str}"
except Exception:
line = f"{TELEMETRY_TAG} {msg}"
logger.log(level, line)