Реализация транспорта для трейсинга
This commit is contained in:
37
README.md
37
README.md
@@ -368,6 +368,8 @@ Control plane и HTTP-канал управления.
|
||||
pip install "plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git"
|
||||
```
|
||||
|
||||
При такой установке `pip` ставит не только сам пакет `plba`, но и все его зависимости, объявленные в [pyproject.toml](/Users/alex/Dev_projects_v2/apps/plba/pyproject.toml), например `fastapi`, `uvicorn` и `PyYAML`.
|
||||
|
||||
Если нужна установка из конкретной ветки:
|
||||
|
||||
```bash
|
||||
@@ -395,6 +397,41 @@ pip install --upgrade pip
|
||||
pip install "plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git"
|
||||
```
|
||||
|
||||
### Подключение `plba` в бизнес-приложении
|
||||
|
||||
Чтобы при установке бизнес-приложения автоматически подтягивались зависимости `plba`, нужно добавить `plba` в зависимости самого бизнес-приложения как Git dependency.
|
||||
|
||||
Пример для `requirements.txt`:
|
||||
|
||||
```txt
|
||||
plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git
|
||||
```
|
||||
|
||||
Пример для `pyproject.toml`:
|
||||
|
||||
```toml
|
||||
[project]
|
||||
dependencies = [
|
||||
"plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git",
|
||||
]
|
||||
```
|
||||
|
||||
Если бизнес-приложение собирается в Docker, достаточно чтобы на этапе сборки выполнялся обычный `pip install`, например:
|
||||
|
||||
```dockerfile
|
||||
COPY pyproject.toml .
|
||||
RUN pip install .
|
||||
```
|
||||
|
||||
или при использовании `requirements.txt`:
|
||||
|
||||
```dockerfile
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
```
|
||||
|
||||
В обоих случаях `pip` установит `plba` из Git и автоматически подтянет его транзитивные зависимости.
|
||||
|
||||
### Локальная разработка
|
||||
|
||||
Если пакет нужно не только использовать, но и разрабатывать:
|
||||
|
||||
@@ -10,6 +10,7 @@ readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"fastapi>=0.129.0",
|
||||
"PyMySQL>=1.1",
|
||||
"PyYAML>=6.0.3",
|
||||
"uvicorn>=0.41.0",
|
||||
]
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -20,7 +20,7 @@ from plba.core import ConfigurationManager, RuntimeManager, ServiceContainer
|
||||
from plba.health import HealthRegistry
|
||||
from plba.logging import LogManager
|
||||
from plba.queue import InMemoryTaskQueue
|
||||
from plba.tracing import NoOpTraceTransport, TraceService
|
||||
from plba.tracing import MySqlTraceTransport, NoOpTraceTransport, TraceService
|
||||
from plba.workers import QueueWorker, WorkerSupervisor
|
||||
|
||||
__all__ = [
|
||||
@@ -38,6 +38,7 @@ __all__ = [
|
||||
"HttpControlChannel",
|
||||
"InMemoryTaskQueue",
|
||||
"LogManager",
|
||||
"MySqlTraceTransport",
|
||||
"NoOpTraceTransport",
|
||||
"QueueWorker",
|
||||
"RuntimeManager",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from app_runtime.tracing.service import TraceService
|
||||
from app_runtime.tracing.transport import NoOpTraceTransport
|
||||
from app_runtime.tracing.transport import MySqlTraceTransport, NoOpTraceTransport
|
||||
|
||||
__all__ = ["NoOpTraceTransport", "TraceService"]
|
||||
__all__ = ["MySqlTraceTransport", "NoOpTraceTransport", "TraceService"]
|
||||
|
||||
Reference in New Issue
Block a user