Реализация транспорта для трейсинга

This commit is contained in:
2026-03-04 12:17:07 +03:00
parent c5a78d80d4
commit 4a0646bb14
6 changed files with 126 additions and 4 deletions

View File

@@ -1,10 +1,11 @@
from app_runtime.contracts.trace import TraceContext, TraceContextRecord, TraceLogMessage, TraceTransport
from app_runtime.tracing.service import TraceManager, TraceService
from app_runtime.tracing.store import ActiveTraceContext, TraceContextStore
from app_runtime.tracing.transport import NoOpTraceTransport
from app_runtime.tracing.transport import MySqlTraceTransport, NoOpTraceTransport
__all__ = [
"ActiveTraceContext",
"MySqlTraceTransport",
"NoOpTraceTransport",
"TraceContext",
"TraceContextRecord",

View File

@@ -1,5 +1,9 @@
from __future__ import annotations
import json
from datetime import date, datetime
from app_runtime.contracts.trace import TraceContextRecord, TraceLogMessage, TraceTransport
@@ -9,3 +13,81 @@ class NoOpTraceTransport(TraceTransport):
def write_message(self, record: TraceLogMessage) -> None:
del record
class MySqlTraceTransport(TraceTransport):
def __init__(
self,
*,
host: str,
port: int,
database: str,
user: str,
password: str,
) -> None:
self._host = host
self._port = port
self._database = database
self._user = user
self._password = password
def write_context(self, record: TraceContextRecord) -> None:
query = """
INSERT INTO trace_contexts (trace_id, parent_id, alias, type, event_time, attrs_json)
VALUES (%s, %s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
parent_id = VALUES(parent_id),
alias = VALUES(alias),
type = VALUES(type),
event_time = VALUES(event_time),
attrs_json = VALUES(attrs_json)
"""
params = (
record.trace_id,
record.parent_id,
record.alias,
record.type,
record.event_time.replace(tzinfo=None),
self._dumps(record.attrs),
)
self._execute(query, params)
def write_message(self, record: TraceLogMessage) -> None:
query = """
INSERT INTO trace_messages (trace_id, event_time, step, status, level, message, attrs_json)
VALUES (%s, %s, %s, %s, %s, %s, %s)
"""
params = (
record.trace_id,
record.event_time.replace(tzinfo=None),
record.step,
record.status,
record.level,
record.message,
self._dumps(record.attrs),
)
self._execute(query, params)
def _execute(self, query: str, params: tuple[object, ...]) -> None:
import pymysql
with pymysql.connect(
host=self._host,
port=self._port,
user=self._user,
password=self._password,
database=self._database,
charset="utf8mb4",
autocommit=True,
cursorclass=pymysql.cursors.DictCursor,
) as connection:
with connection.cursor() as cursor:
cursor.execute(query, params)
def _dumps(self, payload: dict[str, object]) -> str:
return json.dumps(payload, ensure_ascii=False, default=self._json_default)
def _json_default(self, value: object) -> str:
if isinstance(value, (datetime, date)):
return value.isoformat()
return str(value)