ВМ1: реализован сбор логов

This commit is contained in:
mi
2026-09-07 12:46:45 +03:00
parent 44db38f6fe
commit 85df788f2d
42 changed files with 1669 additions and 310 deletions
@@ -10,6 +10,7 @@ from datetime import UTC, datetime, timedelta
import httpx
import structlog
from opentelemetry import trace
from opentelemetry.propagate import extract
from prometheus_client import start_http_server
from sqlalchemy import and_, func, or_, select, update
@@ -26,14 +27,27 @@ from app.metrics import (
from app.provider import IdgtlClient, IdgtlConfig
from app.service import RuntimeSettings, load_runtime_settings
from app.settings import Settings, get_settings
from app.telemetry import add_trace_context, init_telemetry
from app.telemetry import TelemetryRuntime, add_trace_context, init_telemetry
log = structlog.get_logger()
MAX_CONNECT_ATTEMPTS = 3
def configure_logging(level: str) -> None:
def origin_links(traceparent: str | None) -> list[trace.Link]:
if not traceparent:
return []
context = extract({"traceparent": traceparent})
span_context = trace.get_current_span(context).get_span_context()
return [trace.Link(span_context)] if span_context.is_valid else []
def configure_logging(level: str, telemetry: TelemetryRuntime | None = None) -> None:
logging.basicConfig(level=level, format="%(message)s")
if telemetry and telemetry.logging_handler not in logging.getLogger().handlers:
telemetry.logging_handler.addFilter(
lambda record: not record.name.startswith("opentelemetry")
)
logging.getLogger().addHandler(telemetry.logging_handler)
structlog.configure(
processors=[
structlog.contextvars.merge_contextvars,
@@ -42,7 +56,10 @@ def configure_logging(level: str) -> None:
structlog.processors.TimeStamper(fmt="iso", utc=True, key="timestamp"),
structlog.stdlib.add_log_level,
structlog.processors.JSONRenderer(),
]
],
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)
@@ -177,7 +194,7 @@ async def update_queue_metrics(db: Database) -> None:
async def worker_loop(stop: asyncio.Event) -> None:
settings = get_settings()
telemetry = init_telemetry("sms-worker")
configure_logging(settings.log_level)
configure_logging(settings.log_level, telemetry)
structlog.contextvars.bind_contextvars(**{"service.name": "sms-worker"})
metrics_server, metrics_thread = start_http_server(
settings.metrics_port,
@@ -200,8 +217,17 @@ async def worker_loop(stop: asyncio.Event) -> None:
await update_queue_metrics(db)
await asyncio.wait_for(stop.wait(), timeout=runtime.poll_interval_ms / 1000)
continue
process_span = tracer.start_span("sms.process", start_time=claim_started_ns)
with trace.use_span(process_span, end_on_exit=True):
process_span = tracer.start_span(
"sms.process",
start_time=claim_started_ns,
links=origin_links(message.traceparent),
)
with (
trace.use_span(process_span, end_on_exit=True),
structlog.contextvars.bound_contextvars(
sms_message_id=str(message.id)
),
):
claim_span = tracer.start_span("sms.claim", start_time=claim_started_ns)
claim_span.set_attribute("sms.claimed", True)
claim_span.end(end_time=claim_finished_ns)