mirror of
https://github.com/fastapi-practices/fastapi_best_architecture.git
synced 2026-03-13 09:31:31 +08:00
Add the Grafana observability suite (#961)
* Add the Grafana observability suite * Update configs * Update docker script directory structure * Fix the otel trace id * Add grafana ini * Fix some configs and loguru integration * Add the celery grafana * Update Grafana dashboards * Update configs * Fix issues with the panel * Update grafana configs * Update grafana dashboards * Optimized panel styles * Add sqlalchemy traces * Fix the CORS * Update the grafana query and config * Update grafana status is off by default
This commit is contained in:
10
Dockerfile
10
Dockerfile
@@ -36,14 +36,14 @@ COPY --from=builder /fba /fba
|
||||
|
||||
COPY --from=builder /usr/local /usr/local
|
||||
|
||||
COPY deploy/backend/supervisord.conf /etc/supervisor/supervisord.conf
|
||||
COPY deploy/backend/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
|
||||
|
||||
WORKDIR /fba/backend
|
||||
|
||||
# === FastAPI server image ===
|
||||
FROM base_server AS fba_server
|
||||
|
||||
COPY deploy/backend/fba_server.conf /etc/supervisor/conf.d/
|
||||
COPY deploy/backend/supervisor/fba_server.conf /etc/supervisor/conf.d/
|
||||
|
||||
RUN mkdir -p /var/log/fba
|
||||
|
||||
@@ -54,7 +54,7 @@ CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
|
||||
# === Celery Worker image ===
|
||||
FROM base_server AS fba_celery_worker
|
||||
|
||||
COPY deploy/backend/fba_celery_worker.conf /etc/supervisor/conf.d/
|
||||
COPY deploy/backend/supervisor/fba_celery_worker.conf /etc/supervisor/conf.d/
|
||||
|
||||
RUN mkdir -p /var/log/fba
|
||||
|
||||
@@ -63,7 +63,7 @@ CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
|
||||
# === Celery Beat image ===
|
||||
FROM base_server AS fba_celery_beat
|
||||
|
||||
COPY deploy/backend/fba_celery_beat.conf /etc/supervisor/conf.d/
|
||||
COPY deploy/backend/supervisor/fba_celery_beat.conf /etc/supervisor/conf.d/
|
||||
|
||||
RUN mkdir -p /var/log/fba
|
||||
|
||||
@@ -72,7 +72,7 @@ CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
|
||||
# === Celery Flower image ===
|
||||
FROM base_server AS fba_celery_flower
|
||||
|
||||
COPY deploy/backend/fba_celery_flower.conf /etc/supervisor/conf.d/
|
||||
COPY deploy/backend/supervisor/fba_celery_flower.conf /etc/supervisor/conf.d/
|
||||
|
||||
RUN mkdir -p /var/log/fba
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ def init_celery() -> celery.Celery:
|
||||
task_track_started=True,
|
||||
enable_utc=False,
|
||||
timezone=settings.DATETIME_TIMEZONE,
|
||||
worker_send_task_events=True,
|
||||
task_send_sent_event=True,
|
||||
)
|
||||
|
||||
# 在 Celery 中设置此参数无效
|
||||
|
||||
@@ -2,6 +2,7 @@ from fastapi import FastAPI, Request
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from pydantic import ValidationError
|
||||
from starlette.exceptions import HTTPException
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
from uvicorn.protocols.http.h11_impl import STATUS_PHRASES
|
||||
|
||||
from backend.common.context import ctx
|
||||
@@ -75,7 +76,7 @@ async def _validation_exception_handler(exc: RequestValidationError | Validation
|
||||
return MsgSpecJSONResponse(status_code=StandardResponseCode.HTTP_422, content=content)
|
||||
|
||||
|
||||
def register_exception(app: FastAPI) -> None:
|
||||
def register_exception(app: FastAPI) -> None: # noqa: C901
|
||||
@app.exception_handler(HTTPException)
|
||||
async def http_exception_handler(request: Request, exc: HTTPException):
|
||||
"""
|
||||
@@ -194,3 +195,55 @@ def register_exception(app: FastAPI) -> None:
|
||||
status_code=StandardResponseCode.HTTP_500,
|
||||
content=content,
|
||||
)
|
||||
|
||||
if settings.MIDDLEWARE_CORS:
|
||||
|
||||
@app.exception_handler(StandardResponseCode.HTTP_500)
|
||||
async def cors_custom_code_500_exception_handler(request: Request, exc: BaseExceptionError | Exception):
|
||||
"""
|
||||
跨域自定义 500 异常处理
|
||||
|
||||
:param request: FastAPI 请求对象
|
||||
:param exc: 自定义异常
|
||||
:return:
|
||||
"""
|
||||
if isinstance(exc, BaseExceptionError):
|
||||
content = {
|
||||
'code': exc.code,
|
||||
'msg': exc.msg,
|
||||
'data': exc.data,
|
||||
}
|
||||
else:
|
||||
if settings.ENVIRONMENT == 'dev':
|
||||
content = {
|
||||
'code': StandardResponseCode.HTTP_500,
|
||||
'msg': str(exc),
|
||||
'data': None,
|
||||
}
|
||||
else:
|
||||
res = response_base.fail(res=CustomResponseCode.HTTP_500)
|
||||
content = res.model_dump()
|
||||
content.update(trace_id=get_request_trace_id())
|
||||
response = MsgSpecJSONResponse(
|
||||
status_code=exc.code if isinstance(exc, BaseExceptionError) else StandardResponseCode.HTTP_500,
|
||||
content=content,
|
||||
background=exc.background if isinstance(exc, BaseExceptionError) else None,
|
||||
)
|
||||
origin = request.headers.get('origin')
|
||||
if origin:
|
||||
cors = CORSMiddleware(
|
||||
app=app,
|
||||
allow_origins=settings.CORS_ALLOWED_ORIGINS,
|
||||
allow_credentials=True,
|
||||
allow_methods=['*'],
|
||||
allow_headers=['*'],
|
||||
expose_headers=settings.CORS_EXPOSE_HEADERS,
|
||||
)
|
||||
response.headers.update(cors.simple_headers)
|
||||
has_cookie = 'cookie' in request.headers
|
||||
if cors.allow_all_origins and has_cookie:
|
||||
response.headers['Access-Control-Allow-Origin'] = origin
|
||||
elif not cors.allow_all_origins and cors.is_allowed_origin(origin=origin):
|
||||
response.headers['Access-Control-Allow-Origin'] = origin
|
||||
response.headers.add_vary_header('Origin')
|
||||
return response
|
||||
|
||||
@@ -47,6 +47,13 @@ def default_formatter(record: logging.LogRecord) -> str:
|
||||
return settings.LOG_FORMAT if settings.LOG_FORMAT.endswith('\n') else f'{settings.LOG_FORMAT}\n'
|
||||
|
||||
|
||||
def request_id_filter(record: logging.LogRecord) -> logging.LogRecord:
|
||||
"""请求 ID 过滤器"""
|
||||
rid = get_request_trace_id()
|
||||
record['request_id'] = rid[: settings.TRACE_ID_LOG_LENGTH]
|
||||
return record
|
||||
|
||||
|
||||
def setup_logging() -> None:
|
||||
"""
|
||||
设置日志处理器
|
||||
@@ -75,12 +82,6 @@ def setup_logging() -> None:
|
||||
# 移除 loguru 默认处理器
|
||||
logger.remove()
|
||||
|
||||
# request_id 过滤器
|
||||
def request_id_filter(record: logging.LogRecord) -> logging.LogRecord:
|
||||
rid = get_request_trace_id()
|
||||
record['request_id'] = rid[: settings.TRACE_ID_LOG_LENGTH]
|
||||
return record
|
||||
|
||||
# 配置 loguru 处理器
|
||||
logger.configure(
|
||||
handlers=[
|
||||
|
||||
0
backend/common/prometheus/__init__.py
Normal file
0
backend/common/prometheus/__init__.py
Normal file
35
backend/common/prometheus/instruments.py
Normal file
35
backend/common/prometheus/instruments.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from prometheus_client import Counter, Gauge, Histogram
|
||||
|
||||
from backend.core.conf import settings
|
||||
|
||||
PROMETHEUS_INFO_GAUGE = (
|
||||
Gauge(name='fba_app_info', documentation='fba 应用信息', labelnames=['app_name'])
|
||||
.labels(app_name=settings.GRAFANA_APP_NAME)
|
||||
.inc()
|
||||
)
|
||||
|
||||
PROMETHEUS_REQUEST_IN_PROGRESS_GAUGE = Gauge(
|
||||
'fba_request_in_progress',
|
||||
'按方法和路径统计请求的衡量',
|
||||
['app_name', 'method', 'path'],
|
||||
)
|
||||
|
||||
PROMETHEUS_REQUEST_COUNTER = Counter('fba_request_total', '按方法和路径统计请求总数', ['app_name', 'method', 'path'])
|
||||
|
||||
PROMETHEUS_RESPONSE_COUNTER = Counter(
|
||||
'fba_response_total',
|
||||
'按方法、路径和状态码统计响应总数',
|
||||
['app_name', 'method', 'path', 'status_code'],
|
||||
)
|
||||
|
||||
PROMETHEUS_EXCEPTION_COUNTER = Counter(
|
||||
'fba_exception_total',
|
||||
'按方法,路径和异常类型统计异常总数',
|
||||
['app_name', 'method', 'path', 'exception_type'],
|
||||
)
|
||||
|
||||
PROMETHEUS_REQUEST_COST_TIME_HISTOGRAM = Histogram(
|
||||
'fba_request_cost_time',
|
||||
'按方法和路径划分请求耗时的直方图(以 ms 为单位)',
|
||||
['app_name', 'method', 'path'],
|
||||
)
|
||||
@@ -23,7 +23,7 @@ class Settings(BaseSettings):
|
||||
|
||||
# FastAPI
|
||||
FASTAPI_API_V1_PATH: str = '/api/v1'
|
||||
FASTAPI_TITLE: str = 'FastAPI'
|
||||
FASTAPI_TITLE: str = 'fba'
|
||||
FASTAPI_DESCRIPTION: str = 'FastAPI Best Architecture'
|
||||
FASTAPI_DOCS_URL: str = '/docs'
|
||||
FASTAPI_REDOC_URL: str = '/redoc'
|
||||
@@ -215,6 +215,11 @@ class Settings(BaseSettings):
|
||||
# I18n 配置
|
||||
I18N_DEFAULT_LANGUAGE: str = 'zh-CN'
|
||||
|
||||
# Grafana
|
||||
GRAFANA_METRICS: bool = False
|
||||
GRAFANA_APP_NAME: str = 'fba_server'
|
||||
GRAFANA_OTLP_GRPC_ENDPOINT: str = 'fba_alloy:4317'
|
||||
|
||||
##################################################
|
||||
# [ App ] task
|
||||
##################################################
|
||||
|
||||
@@ -9,10 +9,10 @@ import socketio
|
||||
from fastapi import Depends, FastAPI
|
||||
from fastapi_limiter import FastAPILimiter
|
||||
from fastapi_pagination import add_pagination
|
||||
from prometheus_client import make_asgi_app
|
||||
from starlette.middleware.authentication import AuthenticationMiddleware
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
from starlette.staticfiles import StaticFiles
|
||||
from starlette.types import ASGIApp
|
||||
from starlette_context.middleware import ContextMiddleware
|
||||
from starlette_context.plugins import RequestIdPlugin
|
||||
|
||||
@@ -33,8 +33,10 @@ from backend.plugin.tools import build_final_router
|
||||
from backend.utils.demo_site import demo_site
|
||||
from backend.utils.health_check import ensure_unique_route_names, http_limit_callback
|
||||
from backend.utils.openapi import simplify_operation_ids
|
||||
from backend.utils.otel import init_otel
|
||||
from backend.utils.serializers import MsgSpecJSONResponse
|
||||
from backend.utils.snowflake import snowflake
|
||||
from backend.utils.trace_id import OtelTraceIdPlugin
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
@@ -76,22 +78,7 @@ async def register_init(app: FastAPI) -> AsyncGenerator[None, None]:
|
||||
def register_app() -> FastAPI:
|
||||
"""注册 FastAPI 应用"""
|
||||
|
||||
class MyFastAPI(FastAPI):
|
||||
if settings.MIDDLEWARE_CORS:
|
||||
# Related issues
|
||||
# https://github.com/fastapi/fastapi/discussions/7847
|
||||
# https://github.com/fastapi/fastapi/discussions/8027
|
||||
def build_middleware_stack(self) -> ASGIApp:
|
||||
return CORSMiddleware(
|
||||
super().build_middleware_stack(),
|
||||
allow_origins=settings.CORS_ALLOWED_ORIGINS,
|
||||
allow_credentials=True,
|
||||
allow_methods=['*'],
|
||||
allow_headers=['*'],
|
||||
expose_headers=settings.CORS_EXPOSE_HEADERS,
|
||||
)
|
||||
|
||||
app = MyFastAPI(
|
||||
app = FastAPI(
|
||||
title=settings.FASTAPI_TITLE,
|
||||
version=__version__,
|
||||
description=settings.FASTAPI_DESCRIPTION,
|
||||
@@ -111,6 +98,9 @@ def register_app() -> FastAPI:
|
||||
register_page(app)
|
||||
register_exception(app)
|
||||
|
||||
if settings.GRAFANA_METRICS:
|
||||
register_metrics(app)
|
||||
|
||||
return app
|
||||
|
||||
|
||||
@@ -164,15 +154,29 @@ def register_middleware(app: FastAPI) -> None:
|
||||
app.add_middleware(AccessMiddleware)
|
||||
|
||||
# ContextVar
|
||||
plugins = [OtelTraceIdPlugin()] if settings.GRAFANA_METRICS else [RequestIdPlugin(validate=True)]
|
||||
app.add_middleware(
|
||||
ContextMiddleware,
|
||||
plugins=[RequestIdPlugin(validate=True)],
|
||||
plugins=plugins,
|
||||
default_error_response=MsgSpecJSONResponse(
|
||||
content={'code': StandardResponseCode.HTTP_400, 'msg': 'BAD_REQUEST', 'data': None},
|
||||
status_code=StandardResponseCode.HTTP_400,
|
||||
),
|
||||
)
|
||||
|
||||
# CORS
|
||||
# https://github.com/fastapi-practices/fastapi_best_architecture/pull/789/changes
|
||||
# https://github.com/open-telemetry/opentelemetry-python-contrib/issues/4031
|
||||
if settings.MIDDLEWARE_CORS:
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=settings.CORS_ALLOWED_ORIGINS,
|
||||
allow_credentials=True,
|
||||
allow_methods=['*'],
|
||||
allow_headers=['*'],
|
||||
expose_headers=settings.CORS_EXPOSE_HEADERS,
|
||||
)
|
||||
|
||||
|
||||
def register_router(app: FastAPI) -> None:
|
||||
"""
|
||||
@@ -218,3 +222,16 @@ def register_socket_app(app: FastAPI) -> None:
|
||||
socketio_path='/ws/socket.io',
|
||||
)
|
||||
app.mount('/ws', socket_app)
|
||||
|
||||
|
||||
def register_metrics(app: FastAPI) -> None:
|
||||
"""
|
||||
注册指标
|
||||
|
||||
:param app: FastAPI 应用实例
|
||||
:return:
|
||||
"""
|
||||
metrics_app = make_asgi_app()
|
||||
app.mount('/metrics', metrics_app)
|
||||
|
||||
init_otel(app)
|
||||
|
||||
@@ -14,6 +14,13 @@ from backend.app.admin.service.opera_log_service import opera_log_service
|
||||
from backend.common.context import ctx
|
||||
from backend.common.enums import OperaLogCipherType, StatusType
|
||||
from backend.common.log import log
|
||||
from backend.common.prometheus.instruments import (
|
||||
PROMETHEUS_EXCEPTION_COUNTER,
|
||||
PROMETHEUS_REQUEST_COST_TIME_HISTOGRAM,
|
||||
PROMETHEUS_REQUEST_COUNTER,
|
||||
PROMETHEUS_REQUEST_IN_PROGRESS_GAUGE,
|
||||
PROMETHEUS_RESPONSE_COUNTER,
|
||||
)
|
||||
from backend.common.queue import batch_dequeue
|
||||
from backend.common.response.response_code import StandardResponseCode
|
||||
from backend.core.conf import settings
|
||||
@@ -43,6 +50,10 @@ class OperaLogMiddleware(BaseHTTPMiddleware):
|
||||
else:
|
||||
method = request.method
|
||||
args = await self.get_request_args(request)
|
||||
PROMETHEUS_REQUEST_IN_PROGRESS_GAUGE.labels(
|
||||
app_name=settings.GRAFANA_APP_NAME, method=method, path=path
|
||||
).inc()
|
||||
PROMETHEUS_REQUEST_COUNTER.labels(app_name=settings.GRAFANA_APP_NAME, method=method, path=path).inc()
|
||||
|
||||
# 执行请求
|
||||
code = 200
|
||||
@@ -63,6 +74,12 @@ class OperaLogMiddleware(BaseHTTPMiddleware):
|
||||
code = exception.get('code')
|
||||
msg = exception.get('msg')
|
||||
log.error(f'请求异常: {msg}')
|
||||
PROMETHEUS_EXCEPTION_COUNTER.labels(
|
||||
app_name=settings.GRAFANA_APP_NAME,
|
||||
method=method,
|
||||
path=path,
|
||||
exception_type=type(e).__name__,
|
||||
).inc()
|
||||
break
|
||||
except Exception as e:
|
||||
elapsed = round((time.perf_counter() - ctx.perf_time) * 1000, 3)
|
||||
@@ -71,6 +88,20 @@ class OperaLogMiddleware(BaseHTTPMiddleware):
|
||||
status = StatusType.disable
|
||||
error = e
|
||||
log.error(f'请求异常: {e!s}')
|
||||
PROMETHEUS_EXCEPTION_COUNTER.labels(
|
||||
app_name=settings.GRAFANA_APP_NAME, method=method, path=path, exception_type=type(e).__name__
|
||||
).inc()
|
||||
else:
|
||||
PROMETHEUS_REQUEST_COST_TIME_HISTOGRAM.labels(
|
||||
app_name=settings.GRAFANA_APP_NAME, method=method, path=path
|
||||
).observe(elapsed, exemplar={'TraceID': get_request_trace_id()})
|
||||
finally:
|
||||
PROMETHEUS_RESPONSE_COUNTER.labels(
|
||||
app_name=settings.GRAFANA_APP_NAME, method=method, path=path, status_code=code
|
||||
).inc()
|
||||
PROMETHEUS_REQUEST_IN_PROGRESS_GAUGE.labels(
|
||||
app_name=settings.GRAFANA_APP_NAME, method=method, path=path
|
||||
).dec()
|
||||
|
||||
# 此信息只能在请求后获取
|
||||
route = request.scope.get('route')
|
||||
|
||||
59
backend/utils/otel.py
Normal file
59
backend/utils/otel.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from fastapi import FastAPI
|
||||
from opentelemetry import trace
|
||||
from opentelemetry._logs import set_logger_provider
|
||||
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
|
||||
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
||||
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
|
||||
from opentelemetry.instrumentation.logging import LoggingInstrumentor
|
||||
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
|
||||
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
|
||||
from opentelemetry.sdk._logs._internal.export import BatchLogRecordProcessor
|
||||
from opentelemetry.sdk.resources import Resource
|
||||
from opentelemetry.sdk.trace import TracerProvider
|
||||
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
||||
|
||||
from backend.common.log import log, request_id_filter
|
||||
from backend.core.conf import settings
|
||||
from backend.database.db import async_engine
|
||||
|
||||
|
||||
def init_otel(app: FastAPI) -> None:
|
||||
"""
|
||||
初始化 OpenTelemetry
|
||||
|
||||
:param app: FastAPI 应用实例
|
||||
:return:
|
||||
"""
|
||||
from backend import __version__
|
||||
|
||||
resource = Resource(
|
||||
attributes={
|
||||
'service.name': settings.GRAFANA_APP_NAME,
|
||||
'service.version': __version__,
|
||||
'deployment.environment': settings.ENVIRONMENT,
|
||||
},
|
||||
)
|
||||
|
||||
tracer_provider = TracerProvider(resource=resource)
|
||||
trace.set_tracer_provider(tracer_provider)
|
||||
|
||||
span_exporter = OTLPSpanExporter(endpoint=settings.GRAFANA_OTLP_GRPC_ENDPOINT, insecure=True)
|
||||
tracer_provider.add_span_processor(BatchSpanProcessor(span_exporter))
|
||||
|
||||
logger_provider = LoggerProvider(resource=resource)
|
||||
set_logger_provider(logger_provider)
|
||||
|
||||
log_exporter = OTLPLogExporter(endpoint=settings.GRAFANA_OTLP_GRPC_ENDPOINT, insecure=True)
|
||||
logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter))
|
||||
|
||||
otel_logging_handler = LoggingHandler(logger_provider=logger_provider)
|
||||
log.add( # type: ignore
|
||||
otel_logging_handler,
|
||||
level=settings.LOG_STD_LEVEL,
|
||||
format=settings.LOG_FORMAT,
|
||||
filter=lambda record: request_id_filter(record),
|
||||
)
|
||||
|
||||
LoggingInstrumentor().instrument(set_logging_format=True)
|
||||
SQLAlchemyInstrumentor().instrument(engine=async_engine.sync_engine)
|
||||
FastAPIInstrumentor.instrument_app(app, tracer_provider=tracer_provider)
|
||||
@@ -1,9 +1,31 @@
|
||||
from typing import Any
|
||||
|
||||
from opentelemetry import trace
|
||||
from starlette.requests import Request
|
||||
from starlette_context.plugins import Plugin
|
||||
|
||||
from backend.common.context import ctx
|
||||
from backend.core.conf import settings
|
||||
|
||||
|
||||
def get_request_trace_id() -> str:
|
||||
"""从请求头中获取追踪 ID"""
|
||||
"""从上下文中获取追踪 ID"""
|
||||
if ctx.exists():
|
||||
return ctx.get(settings.TRACE_ID_REQUEST_HEADER_KEY, settings.TRACE_ID_LOG_DEFAULT_VALUE)
|
||||
return settings.TRACE_ID_LOG_DEFAULT_VALUE
|
||||
|
||||
|
||||
class OtelTraceIdPlugin(Plugin):
|
||||
"""OpenTelemetry Trace ID 插件"""
|
||||
|
||||
key = settings.TRACE_ID_REQUEST_HEADER_KEY
|
||||
|
||||
async def process_request(self, request: Request) -> Any:
|
||||
"""从 OpenTelemetry span 中提取 trace_id"""
|
||||
span = trace.get_current_span()
|
||||
span_ctx = span.get_span_context()
|
||||
|
||||
if span_ctx.is_valid:
|
||||
return trace.format_trace_id(span_ctx.trace_id)
|
||||
|
||||
return settings.TRACE_ID_LOG_DEFAULT_VALUE
|
||||
|
||||
2049
deploy/backend/grafana/dashboards/fba_celery.json
Normal file
2049
deploy/backend/grafana/dashboards/fba_celery.json
Normal file
File diff suppressed because it is too large
Load Diff
1892
deploy/backend/grafana/dashboards/fba_server.json
Normal file
1892
deploy/backend/grafana/dashboards/fba_server.json
Normal file
File diff suppressed because it is too large
Load Diff
158
deploy/backend/grafana/fba_config.alloy
Normal file
158
deploy/backend/grafana/fba_config.alloy
Normal file
@@ -0,0 +1,158 @@
|
||||
// ============================================================================
|
||||
// Grafana Alloy 配置文件
|
||||
// Alloy 是 Grafana 的可观测性数据收集器(原 Grafana Agent)
|
||||
// 官方文档: https://grafana.com/docs/alloy/latest/
|
||||
//
|
||||
// 数据流向:
|
||||
// 应用程序 -> OTLP Receiver -> Batch Processor -> Exporters -> 后端存储
|
||||
// - 日志 (Logs) -> Loki
|
||||
// - 指标 (Metrics) -> Prometheus
|
||||
// - 链路 (Traces) -> Tempo
|
||||
// ============================================================================
|
||||
|
||||
// OTLP 接收器配置
|
||||
// OpenTelemetry Protocol (OTLP) 是 OpenTelemetry 的标准数据传输协议
|
||||
// 支持同时接收日志、指标和链路追踪数据
|
||||
otelcol.receiver.otlp "default" {
|
||||
// gRPC 协议配置
|
||||
// gRPC 是高性能的 RPC 框架,适用于服务间通信
|
||||
grpc {
|
||||
endpoint = "0.0.0.0:4317"
|
||||
// 0.0.0.0 表示监听所有网络接口
|
||||
// 4317 是 OTLP gRPC 的标准端口
|
||||
// 应用程序通过此端口发送遥测数据
|
||||
}
|
||||
|
||||
// HTTP 协议配置
|
||||
// HTTP 协议更通用,适用于无法使用 gRPC 的场景
|
||||
http {
|
||||
endpoint = "0.0.0.0:4318"
|
||||
// 4318 是 OTLP HTTP 的标准端口
|
||||
// 支持 JSON 和 Protobuf 格式的数据
|
||||
}
|
||||
|
||||
// 输出配置
|
||||
// 定义接收到的数据发送到哪些处理器
|
||||
output {
|
||||
logs = [otelcol.processor.batch.default.input]
|
||||
metrics = [otelcol.processor.batch.default.input]
|
||||
traces = [otelcol.processor.batch.default.input]
|
||||
}
|
||||
}
|
||||
|
||||
// 批处理器配置
|
||||
// 将多个遥测数据项合并成批次,提高传输效率
|
||||
otelcol.processor.batch "default" {
|
||||
// 输出配置
|
||||
// 定义处理后的数据发送到哪些导出器
|
||||
output {
|
||||
logs = [otelcol.exporter.loki.default.input]
|
||||
metrics = [otelcol.exporter.prometheus.default.input]
|
||||
traces = [otelcol.exporter.otlp.tempo.input]
|
||||
}
|
||||
}
|
||||
|
||||
// Loki 导出器配置
|
||||
// 将日志数据发送到 Grafana Loki
|
||||
otelcol.exporter.loki "default" {
|
||||
forward_to = [loki.write.loki_server.receiver]
|
||||
}
|
||||
|
||||
// Loki 写入组件
|
||||
// 负责将日志数据推送到 Loki 服务器
|
||||
loki.write "loki_server" {
|
||||
endpoint {
|
||||
url = "http://fba_loki:3100/loki/api/v1/push"
|
||||
}
|
||||
}
|
||||
|
||||
// Prometheus 导出器配置
|
||||
// 将指标数据发送到 Prometheus
|
||||
otelcol.exporter.prometheus "default" {
|
||||
forward_to = [prometheus.remote_write.prom_server.receiver]
|
||||
}
|
||||
|
||||
// Prometheus 远程写入组件
|
||||
// 负责将指标数据推送到 Prometheus 服务器
|
||||
prometheus.remote_write "prom_server" {
|
||||
endpoint {
|
||||
url = "http://fba_prometheus:9090/api/v1/write"
|
||||
}
|
||||
}
|
||||
|
||||
// Prometheus 自身指标抓取
|
||||
// 监控 Prometheus 服务器本身的运行状态
|
||||
prometheus.scrape "prometheus" {
|
||||
targets = [{
|
||||
__address__ = "fba_prometheus:9090",
|
||||
}]
|
||||
forward_to = [prometheus.remote_write.prom_server.receiver]
|
||||
// 抓取的指标发送到远程写入组件
|
||||
|
||||
job_name = "fba_prometheus"
|
||||
// 任务名称
|
||||
// 将作为 job 标签添加到所有抓取的指标上
|
||||
|
||||
scrape_interval = "15s"
|
||||
// 抓取间隔
|
||||
}
|
||||
|
||||
// FastAPI 后端服务指标抓取
|
||||
// 监控 FastAPI 应用的性能和业务指标
|
||||
prometheus.scrape "fba_server" {
|
||||
targets = [{
|
||||
__address__ = "fba_server:8001",
|
||||
}]
|
||||
forward_to = [prometheus.remote_write.prom_server.receiver]
|
||||
// 抓取的指标发送到远程写入组件
|
||||
|
||||
job_name = "fba_server"
|
||||
// 任务名称
|
||||
// 用于在 Prometheus 查询中区分不同服务
|
||||
|
||||
scrape_interval = "5s"
|
||||
// 抓取间隔
|
||||
|
||||
scrape_timeout = "5s"
|
||||
// 抓取超时时间
|
||||
}
|
||||
|
||||
// Celery Exporter 指标抓取
|
||||
// 监控 Celery 异步任务队列的运行状态
|
||||
prometheus.scrape "fba_celery_exporter" {
|
||||
targets = [{
|
||||
__address__ = "fba_celery_exporter:9808",
|
||||
}]
|
||||
forward_to = [prometheus.remote_write.prom_server.receiver]
|
||||
// 抓取的指标发送到远程写入组件
|
||||
|
||||
job_name = "fba_celery_exporter"
|
||||
// 任务名称
|
||||
// 用于标识 Celery 相关的指标
|
||||
|
||||
scrape_interval = "5s"
|
||||
// 抓取间隔
|
||||
|
||||
scrape_timeout = "5s"
|
||||
// 抓取超时时间
|
||||
}
|
||||
|
||||
// Tempo 导出器配置
|
||||
// 将链路追踪数据发送到 Grafana Tempo
|
||||
otelcol.exporter.otlp "tempo" {
|
||||
client {
|
||||
endpoint = "fba_tempo:4317"
|
||||
|
||||
tls {
|
||||
insecure = true
|
||||
// 禁用 TLS 加密
|
||||
// 在 Docker 内部网络中通信时可以禁用
|
||||
// 生产环境建议启用 TLS
|
||||
|
||||
insecure_skip_verify = true
|
||||
// 跳过 TLS 证书验证
|
||||
// 仅在开发/测试环境使用
|
||||
// 生产环境应配置正确的证书
|
||||
}
|
||||
}
|
||||
}
|
||||
36
deploy/backend/grafana/fba_dashboards.yml
Normal file
36
deploy/backend/grafana/fba_dashboards.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
# ============================================================================
|
||||
# Grafana 仪表盘 Provisioning 配置文件
|
||||
# 官方文档: https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards
|
||||
# 用于自动加载和管理仪表盘,无需手动导入
|
||||
# ============================================================================
|
||||
|
||||
# API 版本号
|
||||
# 当前仅支持版本 1
|
||||
apiVersion: 1
|
||||
|
||||
# providers: 仪表盘提供者列表
|
||||
# 定义 Grafana 从哪里加载仪表盘以及如何管理它们
|
||||
providers:
|
||||
- name: 'fba_server'
|
||||
# 提供者名称,用于标识和日志记录
|
||||
|
||||
orgId: 1
|
||||
# 组织 ID
|
||||
# 指定仪表盘属于哪个组织
|
||||
# 默认值: 1(默认组织)
|
||||
|
||||
type: 'file'
|
||||
# 提供者类型
|
||||
# 可选值:
|
||||
# - file: 从本地文件系统加载仪表盘 JSON 文件
|
||||
|
||||
disableDeletion: true
|
||||
# 禁止通过 UI 删除仪表盘
|
||||
|
||||
editable: false
|
||||
# 是否允许通过 UI 编辑仪表盘
|
||||
|
||||
options:
|
||||
path: '/etc/grafana/dashboards'
|
||||
# 仪表盘 JSON 文件所在目录(容器内路径)
|
||||
# Grafana 会自动扫描此目录下的所有 .json 文件
|
||||
164
deploy/backend/grafana/fba_datasource.yml
Normal file
164
deploy/backend/grafana/fba_datasource.yml
Normal file
@@ -0,0 +1,164 @@
|
||||
# ============================================================================
|
||||
# Grafana 数据源 Provisioning 配置文件
|
||||
# 官方文档: https://grafana.com/docs/grafana/latest/administration/provisioning/#datasources
|
||||
# 用于自动配置数据源,实现基础设施即代码
|
||||
# ============================================================================
|
||||
|
||||
# API 版本号
|
||||
# 当前仅支持版本 1
|
||||
apiVersion: 1
|
||||
|
||||
# datasources: 数据源列表
|
||||
# 定义 Grafana 连接的所有后端数据存储
|
||||
datasources:
|
||||
# ==========================================================================
|
||||
# Loki 数据源配置
|
||||
# Loki 是 Grafana 的日志聚合系统,类似于 Prometheus 但用于日志
|
||||
# 官方文档: https://grafana.com/docs/loki/latest/
|
||||
# ==========================================================================
|
||||
- name: Loki
|
||||
# 数据源显示名称,在 Grafana UI 中显示
|
||||
|
||||
uid: loki
|
||||
# 数据源唯一标识符
|
||||
# 用于在仪表盘和告警规则中引用此数据源
|
||||
|
||||
type: loki
|
||||
# 数据源类型
|
||||
# 必须与 Grafana 支持的数据源插件类型匹配
|
||||
|
||||
url: http://fba_loki:3100
|
||||
# Loki 服务器地址
|
||||
|
||||
isDefault: false
|
||||
# 是否设为默认数据源
|
||||
|
||||
jsonData:
|
||||
# 数据源特定的 JSON 配置
|
||||
|
||||
derivedFields:
|
||||
# 派生字段配置
|
||||
# 用于从日志中提取字段并创建链接到其他数据源
|
||||
# 这是实现日志到链路追踪关联的关键配置
|
||||
|
||||
- datasourceUid: tempo
|
||||
# 目标数据源的 UID
|
||||
# 点击链接时将跳转到此数据源
|
||||
|
||||
matcherRegex: '"traceid":"([a-f0-9]{32})"'
|
||||
# 正则表达式,用于从日志内容中提取 Trace ID
|
||||
|
||||
matcherType: regex
|
||||
# 匹配器类型
|
||||
# 可选值: regex(正则表达式)
|
||||
|
||||
name: TraceID
|
||||
# 派生字段的名称
|
||||
# 将显示在日志详情中
|
||||
|
||||
url: $${__value.raw}
|
||||
# 链接 URL 模板
|
||||
# $${__value.raw} 表示提取的原始值
|
||||
|
||||
urlDisplayLabel: 查看 Trace
|
||||
# 链接显示的文本标签
|
||||
|
||||
# ==========================================================================
|
||||
# Prometheus 数据源配置
|
||||
# Prometheus 是云原生监控系统,用于收集和存储时序指标数据
|
||||
# 官方文档: https://prometheus.io/docs/
|
||||
# ==========================================================================
|
||||
- name: Prometheus
|
||||
# 数据源显示名称
|
||||
|
||||
uid: prometheus
|
||||
# 数据源唯一标识符
|
||||
|
||||
type: prometheus
|
||||
# 数据源类型
|
||||
|
||||
url: http://fba_prometheus:9090
|
||||
# Prometheus 服务器地址
|
||||
|
||||
isDefault: true
|
||||
# 设为默认数据源
|
||||
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
# 查询使用的 HTTP 方法
|
||||
|
||||
exemplarTraceIdDestinations:
|
||||
# Exemplar(范例)配置
|
||||
# Exemplar 是指标数据点关联的 Trace ID
|
||||
# 用于从指标跳转到对应的链路追踪
|
||||
|
||||
- name: TraceID
|
||||
# Exemplar 中 Trace ID 的字段名称
|
||||
|
||||
datasourceUid: tempo
|
||||
# 目标 Tempo 数据源的 UID
|
||||
# 点击 Exemplar 时将跳转到此数据源查看 Trace
|
||||
|
||||
# ==========================================================================
|
||||
# Tempo 数据源配置
|
||||
# Tempo 是 Grafana 的分布式链路追踪后端
|
||||
# 官方文档: https://grafana.com/docs/tempo/latest/
|
||||
# ==========================================================================
|
||||
- name: Tempo
|
||||
# 数据源显示名称
|
||||
|
||||
uid: tempo
|
||||
# 数据源唯一标识符
|
||||
|
||||
type: tempo
|
||||
# 数据源类型
|
||||
|
||||
url: http://fba_tempo:3200
|
||||
# Tempo 服务器地址
|
||||
|
||||
jsonData:
|
||||
nodeGraph:
|
||||
enabled: true
|
||||
# 启用节点图功能
|
||||
# 可视化展示服务之间的调用关系图
|
||||
|
||||
tracesToLogsV2:
|
||||
# Trace 到日志的关联配置(V2 版本)
|
||||
# 允许从 Trace 详情页面跳转到相关日志
|
||||
|
||||
datasourceUid: loki
|
||||
# 日志数据源的 UID
|
||||
|
||||
filterByTraceID: true
|
||||
# 是否按 Trace ID 过滤日志
|
||||
|
||||
spanStartTimeShift: "-1m"
|
||||
# Span 开始时间偏移
|
||||
# 用于捕获 Span 开始前的相关日志
|
||||
|
||||
spanEndTimeShift: "1m"
|
||||
# Span 结束时间偏移
|
||||
# 用于捕获 Span 结束后的相关日志
|
||||
|
||||
customQuery: true
|
||||
# 启用自定义查询
|
||||
# 允许使用下面的 query 字段自定义日志查询语句
|
||||
|
||||
query: '{service_name="fba_server"} | json | traceid="${__span.traceId}"'
|
||||
# 自定义 LogQL 查询语句
|
||||
|
||||
search:
|
||||
hide: false
|
||||
# 是否隐藏搜索功能
|
||||
|
||||
serviceMap:
|
||||
datasourceUid: prometheus
|
||||
# 服务地图数据源
|
||||
# 使用 Prometheus 中的指标数据生成服务依赖图
|
||||
# 需要 Tempo 的 metrics_generator 功能配合
|
||||
|
||||
lokiSearch:
|
||||
datasourceUid: loki
|
||||
# Loki 搜索数据源
|
||||
# 允许在 Tempo 中使用 Loki 进行日志搜索
|
||||
# 实现基于日志内容查找 Trace 的功能
|
||||
40
deploy/backend/grafana/fba_grafana.ini
Normal file
40
deploy/backend/grafana/fba_grafana.ini
Normal file
@@ -0,0 +1,40 @@
|
||||
# ============================================================================
|
||||
# Grafana 主配置文件
|
||||
# 官方文档: https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/
|
||||
# ============================================================================
|
||||
|
||||
# [server] 服务器配置
|
||||
# 用于配置 Grafana HTTP 服务器的基本设置
|
||||
[server]
|
||||
# 协议类型
|
||||
protocol = http
|
||||
|
||||
# HTTP 服务监听端口
|
||||
http_port = 3000
|
||||
|
||||
# [security] 安全配置
|
||||
# 用于配置 Grafana 安全相关的默认设置
|
||||
[security]
|
||||
# 默认 Grafana 管理员用户名
|
||||
admin_user = admin
|
||||
|
||||
# 默认 Grafana 管理员密码
|
||||
admin_password = 123456
|
||||
|
||||
# 如果您将 Grafana 托管在 HTTPS
|
||||
;cookie_secure = true
|
||||
|
||||
# [users] 用户配置
|
||||
# 用于配置用户相关的默认设置
|
||||
[users]
|
||||
# 默认 UI 主题
|
||||
default_theme=system
|
||||
|
||||
# 默认界面语言
|
||||
default_language = zh-Hans
|
||||
|
||||
# [dashboards] 仪表盘配置
|
||||
# 用于配置仪表盘相关的默认设置
|
||||
[dashboards]
|
||||
# 默认首页仪表盘路径
|
||||
default_home_dashboard_path = /etc/grafana/dashboards/fba_server.json
|
||||
13
deploy/backend/grafana/fba_prometheus.yml
Normal file
13
deploy/backend/grafana/fba_prometheus.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
# ============================================================================
|
||||
# Prometheus 配置文件
|
||||
# Prometheus 是云原生监控和告警系统,专注于时序指标数据
|
||||
# 官方文档: https://prometheus.io/docs/prometheus/latest/configuration/configuration/
|
||||
# ============================================================================
|
||||
|
||||
# global: 全局配置
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
# 指标抓取间隔
|
||||
|
||||
evaluation_interval: 15s
|
||||
# 规则评估间隔
|
||||
127
deploy/backend/grafana/fba_tempo.yml
Normal file
127
deploy/backend/grafana/fba_tempo.yml
Normal file
@@ -0,0 +1,127 @@
|
||||
# ============================================================================
|
||||
# Tempo 配置文件
|
||||
# Tempo 是 Grafana 的高性能、低成本分布式链路追踪后端
|
||||
# 官方文档: https://grafana.com/docs/tempo/latest/configuration/
|
||||
# ============================================================================
|
||||
|
||||
# server: HTTP 服务器配置
|
||||
server:
|
||||
http_listen_port: 3200
|
||||
# HTTP API 监听端口
|
||||
# 用于查询 Trace 数据和健康检查
|
||||
|
||||
# distributor: 分发器配置
|
||||
distributor:
|
||||
receivers:
|
||||
# 接收器配置
|
||||
|
||||
otlp:
|
||||
# OpenTelemetry Protocol (OTLP) 接收器
|
||||
# OTLP 是 OpenTelemetry 的原生协议,推荐使用
|
||||
|
||||
protocols:
|
||||
grpc:
|
||||
endpoint: "0.0.0.0:4317"
|
||||
# gRPC 协议端点
|
||||
|
||||
http:
|
||||
endpoint: "0.0.0.0:4318"
|
||||
# HTTP 协议端点
|
||||
|
||||
# storage: 存储配置
|
||||
storage:
|
||||
trace:
|
||||
backend: local
|
||||
# 存储后端类型
|
||||
# 生产环境建议使用对象存储
|
||||
|
||||
wal:
|
||||
path: /tmp/tempo/wal
|
||||
# Write-Ahead Log (WAL) 目录
|
||||
# WAL 用于在数据写入存储前的临时缓存
|
||||
# 确保数据不会因意外重启而丢失
|
||||
# 注意: 生产环境应使用持久化存储路径
|
||||
|
||||
local:
|
||||
path: /tmp/tempo/blocks
|
||||
# 本地存储的数据块目录
|
||||
# 存储压缩后的 Trace 数据块
|
||||
# 仅在 backend: local 时使用
|
||||
|
||||
# metrics_generator: 指标生成器配置
|
||||
# 从 Trace 数据自动生成 Prometheus 指标
|
||||
# 这是实现 Trace 到 Metrics 关联的关键功能
|
||||
metrics_generator:
|
||||
registry:
|
||||
external_labels:
|
||||
source: tempo
|
||||
# 外部标签
|
||||
# 添加到所有生成的指标上
|
||||
|
||||
storage:
|
||||
path: /tmp/tempo/generator/wal
|
||||
# 指标生成器的 WAL 目录
|
||||
# 用于临时存储待发送的指标数据
|
||||
|
||||
remote_write:
|
||||
# 远程写入配置
|
||||
|
||||
- url: http://fba_prometheus:9090/api/v1/write
|
||||
# Prometheus 远程写入 API 地址
|
||||
# 需要 Prometheus 启用 remote-write-receiver 功能
|
||||
|
||||
send_exemplars: true
|
||||
# 发送 Exemplar 数据
|
||||
# Exemplar 将指标数据点与 Trace ID 关联
|
||||
# 实现从指标图表点击跳转到对应 Trace
|
||||
|
||||
traces_storage:
|
||||
path: /tmp/tempo/generator/traces
|
||||
# Trace 数据临时存储路径
|
||||
# 用于指标生成器处理 Trace 数据
|
||||
|
||||
processor:
|
||||
# 处理器配置
|
||||
# 定义如何从 Trace 生成指标
|
||||
|
||||
span_metrics:
|
||||
# Span 指标处理器
|
||||
|
||||
dimensions:
|
||||
# 指标维度(标签)
|
||||
# 这些属性将作为 Prometheus 指标的标签
|
||||
|
||||
- service.name
|
||||
- http.method
|
||||
- http.target
|
||||
- http.status_code
|
||||
|
||||
service_graphs:
|
||||
# 服务图处理器
|
||||
# 生成服务间调用关系的指标
|
||||
# 用于 Grafana 中的服务地图可视化
|
||||
|
||||
dimensions:
|
||||
- service.name
|
||||
|
||||
local_blocks:
|
||||
# 本地块处理器
|
||||
# 处理本地存储的 Trace 数据块
|
||||
|
||||
flush_to_storage: true
|
||||
# 是否将处理后的数据刷新到存储
|
||||
|
||||
# overrides: 覆盖配置
|
||||
overrides:
|
||||
defaults:
|
||||
# 默认配置
|
||||
# 适用于所有租户(单租户模式下为全局配置)
|
||||
|
||||
metrics_generator:
|
||||
processors:
|
||||
# 启用的指标处理器列表
|
||||
# 只有在此列表中的处理器才会运行
|
||||
|
||||
- span-metrics
|
||||
- service-graphs
|
||||
- local-blocks
|
||||
@@ -19,6 +19,8 @@ volumes:
|
||||
name: fba_static_upload
|
||||
fba_rabbitmq:
|
||||
name: fba_rabbitmq
|
||||
fba_prometheus_data:
|
||||
name: fba_prometheus_data
|
||||
|
||||
services:
|
||||
fba_server:
|
||||
@@ -30,6 +32,8 @@ services:
|
||||
- "8001:8001"
|
||||
container_name: fba_server
|
||||
restart: always
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
# 如果你是 mysql 用户,应将 fba_postgres 修改为 fba_mysql
|
||||
depends_on:
|
||||
- fba_postgres
|
||||
@@ -176,6 +180,8 @@ services:
|
||||
# 如果你需要分布式部署 Worker,则必须移除此 container_name 配置
|
||||
container_name: fba_celery_worker
|
||||
restart: always
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
depends_on:
|
||||
- fba_rabbitmq
|
||||
volumes:
|
||||
@@ -199,6 +205,8 @@ services:
|
||||
image: fba_celery_beat:latest
|
||||
container_name: fba_celery_beat
|
||||
restart: always
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
depends_on:
|
||||
- fba_rabbitmq
|
||||
- fba_celery_worker
|
||||
@@ -225,6 +233,8 @@ services:
|
||||
- "8555:8555"
|
||||
container_name: fba_celery_flower
|
||||
restart: always
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
depends_on:
|
||||
- fba_rabbitmq
|
||||
- fba_celery_worker
|
||||
@@ -239,3 +249,100 @@ services:
|
||||
wait-for-it -s fba_rabbitmq:5672 -t 300
|
||||
supervisord -c /etc/supervisor/supervisord.conf
|
||||
supervisorctl restart
|
||||
|
||||
fba_celery_exporter:
|
||||
image: danihodovic/celery-exporter
|
||||
restart: always
|
||||
ports:
|
||||
- "9808:9808"
|
||||
container_name: fba_celery_exporter
|
||||
environment:
|
||||
- CE_BROKER_URL=amqp://guest:guest@fba_rabbitmq:5672//
|
||||
depends_on:
|
||||
- fba_rabbitmq
|
||||
networks:
|
||||
- fba_network
|
||||
|
||||
fba_loki:
|
||||
image: grafana/loki
|
||||
restart: always
|
||||
ports:
|
||||
- "3100:3100"
|
||||
container_name: fba_loki
|
||||
networks:
|
||||
- fba_network
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
|
||||
fba_prometheus:
|
||||
image: prom/prometheus
|
||||
restart: always
|
||||
ports:
|
||||
- "9090:9090"
|
||||
container_name: fba_prometheus
|
||||
depends_on:
|
||||
- fba_loki
|
||||
volumes:
|
||||
- ./deploy/backend/grafana/fba_prometheus.yml:/workspace/fba_prometheus.yml
|
||||
- fba_prometheus_data:/prometheus
|
||||
networks:
|
||||
- fba_network
|
||||
command:
|
||||
- --web.enable-remote-write-receiver
|
||||
- --enable-feature=exemplar-storage
|
||||
- --config.file=/workspace/fba_prometheus.yml
|
||||
|
||||
fba_alloy:
|
||||
image: grafana/alloy
|
||||
restart: always
|
||||
ports:
|
||||
- "4317:4317"
|
||||
- "4318:4318"
|
||||
- "12345:12345"
|
||||
container_name: fba_alloy
|
||||
depends_on:
|
||||
- fba_loki
|
||||
volumes:
|
||||
- ./deploy/backend/grafana/fba_config.alloy:/etc/alloy/fba_config.alloy
|
||||
networks:
|
||||
- fba_network
|
||||
command:
|
||||
- run
|
||||
- /etc/alloy/fba_config.alloy
|
||||
- --server.http.listen-addr=0.0.0.0:12345
|
||||
|
||||
fba_tempo:
|
||||
image: grafana/tempo:latest
|
||||
restart: always
|
||||
ports:
|
||||
- "3200:3200"
|
||||
expose:
|
||||
- 4317
|
||||
- 4318
|
||||
container_name: fba_tempo
|
||||
depends_on:
|
||||
- fba_loki
|
||||
volumes:
|
||||
- ./deploy/backend/grafana/fba_tempo.yml:/etc/tempo/fba_tempo.yml
|
||||
networks:
|
||||
- fba_network
|
||||
command:
|
||||
- -config.file=/etc/tempo/fba_tempo.yml
|
||||
- -auth.enabled=false
|
||||
|
||||
fba_grafana:
|
||||
image: grafana/grafana
|
||||
restart: always
|
||||
ports:
|
||||
- "3000:3000"
|
||||
container_name: fba_grafana
|
||||
depends_on:
|
||||
- fba_loki
|
||||
- fba_prometheus
|
||||
volumes:
|
||||
- ./deploy/backend/grafana/fba_grafana.ini:/etc/grafana/grafana.ini
|
||||
- ./deploy/backend/grafana/dashboards/fba_celery.json:/etc/grafana/dashboards/fba_celery.json
|
||||
- ./deploy/backend/grafana/dashboards/fba_server.json:/etc/grafana/dashboards/fba_server.json
|
||||
- ./deploy/backend/grafana/fba_dashboards.yml:/etc/grafana/provisioning/dashboards/fba_dashboards.yml
|
||||
- ./deploy/backend/grafana/fba_datasource.yml:/etc/grafana/provisioning/datasources/fba_datasource.yml
|
||||
networks:
|
||||
- fba_network
|
||||
|
||||
@@ -36,6 +36,12 @@ dependencies = [
|
||||
"jinja2>=3.1.6",
|
||||
"loguru>=0.7.3",
|
||||
"msgspec>=0.20.0",
|
||||
"opentelemetry-exporter-otlp-proto-grpc>=1.39.0",
|
||||
"opentelemetry-instrumentation-fastapi>=0.60b0",
|
||||
"opentelemetry-instrumentation-logging>=0.60b0",
|
||||
"opentelemetry-instrumentation-sqlalchemy>=0.60b0",
|
||||
"opentelemetry-sdk>=1.39.0",
|
||||
"prometheus-client>=0.23.1",
|
||||
"psutil>=7.1.3",
|
||||
# https://github.com/fastapi-practices/fastapi_best_architecture/issues/887
|
||||
"psycopg[binary]==3.2.10",
|
||||
|
||||
@@ -15,7 +15,9 @@ anyio==4.12.0
|
||||
# starlette
|
||||
# watchfiles
|
||||
asgiref==3.11.0
|
||||
# via fastapi-best-architecture
|
||||
# via
|
||||
# fastapi-best-architecture
|
||||
# opentelemetry-instrumentation-asgi
|
||||
async-timeout==5.0.1 ; python_full_version < '3.11.3'
|
||||
# via
|
||||
# asyncpg
|
||||
@@ -101,12 +103,16 @@ flower==2.0.1
|
||||
# via fastapi-best-architecture
|
||||
gevent==25.9.1
|
||||
# via fastapi-best-architecture
|
||||
googleapis-common-protos==1.72.0
|
||||
# via opentelemetry-exporter-otlp-proto-grpc
|
||||
granian==2.6.0
|
||||
# via fastapi-best-architecture
|
||||
greenlet==3.2.4
|
||||
# via
|
||||
# gevent
|
||||
# sqlalchemy
|
||||
grpcio==1.76.0
|
||||
# via opentelemetry-exporter-otlp-proto-grpc
|
||||
h11==0.16.0
|
||||
# via
|
||||
# httpcore
|
||||
@@ -127,6 +133,8 @@ idna==3.11
|
||||
# anyio
|
||||
# email-validator
|
||||
# httpx
|
||||
importlib-metadata==8.7.0
|
||||
# via opentelemetry-api
|
||||
iniconfig==2.3.0
|
||||
# via pytest
|
||||
ip2loc==1.0.0
|
||||
@@ -153,9 +161,58 @@ mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
msgspec==0.20.0
|
||||
# via fastapi-best-architecture
|
||||
opentelemetry-api==1.39.0
|
||||
# via
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
# opentelemetry-instrumentation
|
||||
# opentelemetry-instrumentation-asgi
|
||||
# opentelemetry-instrumentation-fastapi
|
||||
# opentelemetry-instrumentation-logging
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
# opentelemetry-sdk
|
||||
# opentelemetry-semantic-conventions
|
||||
opentelemetry-exporter-otlp-proto-common==1.39.0
|
||||
# via opentelemetry-exporter-otlp-proto-grpc
|
||||
opentelemetry-exporter-otlp-proto-grpc==1.39.0
|
||||
# via fastapi-best-architecture
|
||||
opentelemetry-instrumentation==0.60b0
|
||||
# via
|
||||
# opentelemetry-instrumentation-asgi
|
||||
# opentelemetry-instrumentation-fastapi
|
||||
# opentelemetry-instrumentation-logging
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
opentelemetry-instrumentation-asgi==0.60b0
|
||||
# via opentelemetry-instrumentation-fastapi
|
||||
opentelemetry-instrumentation-fastapi==0.60b0
|
||||
# via fastapi-best-architecture
|
||||
opentelemetry-instrumentation-logging==0.60b0
|
||||
# via fastapi-best-architecture
|
||||
opentelemetry-instrumentation-sqlalchemy==0.60b0
|
||||
# via fastapi-best-architecture
|
||||
opentelemetry-proto==1.39.0
|
||||
# via
|
||||
# opentelemetry-exporter-otlp-proto-common
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
opentelemetry-sdk==1.39.0
|
||||
# via
|
||||
# fastapi-best-architecture
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
opentelemetry-semantic-conventions==0.60b0
|
||||
# via
|
||||
# opentelemetry-instrumentation
|
||||
# opentelemetry-instrumentation-asgi
|
||||
# opentelemetry-instrumentation-fastapi
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
# opentelemetry-sdk
|
||||
opentelemetry-util-http==0.60b0
|
||||
# via
|
||||
# opentelemetry-instrumentation-asgi
|
||||
# opentelemetry-instrumentation-fastapi
|
||||
packaging==25.0
|
||||
# via
|
||||
# kombu
|
||||
# opentelemetry-instrumentation
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
# pytest
|
||||
pillow==12.0.0
|
||||
# via fast-captcha
|
||||
@@ -163,9 +220,15 @@ pluggy==1.6.0
|
||||
# via pytest
|
||||
prek==0.2.19
|
||||
prometheus-client==0.23.1
|
||||
# via flower
|
||||
# via
|
||||
# fastapi-best-architecture
|
||||
# flower
|
||||
prompt-toolkit==3.0.52
|
||||
# via click-repl
|
||||
protobuf==6.33.2
|
||||
# via
|
||||
# googleapis-common-protos
|
||||
# opentelemetry-proto
|
||||
psutil==7.1.3
|
||||
# via fastapi-best-architecture
|
||||
psycopg==3.2.10
|
||||
@@ -280,6 +343,11 @@ typing-extensions==4.15.0
|
||||
# exceptiongroup
|
||||
# fastapi
|
||||
# fastapi-pagination
|
||||
# grpcio
|
||||
# opentelemetry-api
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
# opentelemetry-sdk
|
||||
# opentelemetry-semantic-conventions
|
||||
# psycopg
|
||||
# pydantic
|
||||
# pydantic-core
|
||||
@@ -328,8 +396,14 @@ websockets==15.0.1
|
||||
# via uvicorn
|
||||
win32-setctime==1.2.0 ; sys_platform == 'win32'
|
||||
# via loguru
|
||||
wrapt==1.17.3
|
||||
# via
|
||||
# opentelemetry-instrumentation
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
wsproto==1.3.2
|
||||
# via simple-websocket
|
||||
zipp==3.23.0
|
||||
# via importlib-metadata
|
||||
zope-event==6.1
|
||||
# via gevent
|
||||
zope-interface==8.1.1
|
||||
|
||||
357
uv.lock
generated
357
uv.lock
generated
@@ -704,6 +704,12 @@ dependencies = [
|
||||
{ name = "jinja2" },
|
||||
{ name = "loguru" },
|
||||
{ name = "msgspec" },
|
||||
{ name = "opentelemetry-exporter-otlp-proto-grpc" },
|
||||
{ name = "opentelemetry-instrumentation-fastapi" },
|
||||
{ name = "opentelemetry-instrumentation-logging" },
|
||||
{ name = "opentelemetry-instrumentation-sqlalchemy" },
|
||||
{ name = "opentelemetry-sdk" },
|
||||
{ name = "prometheus-client" },
|
||||
{ name = "psutil" },
|
||||
{ name = "psycopg", extra = ["binary"] },
|
||||
{ name = "pwdlib" },
|
||||
@@ -758,6 +764,12 @@ requires-dist = [
|
||||
{ name = "jinja2", specifier = ">=3.1.6" },
|
||||
{ name = "loguru", specifier = ">=0.7.3" },
|
||||
{ name = "msgspec", specifier = ">=0.20.0" },
|
||||
{ name = "opentelemetry-exporter-otlp-proto-grpc", specifier = ">=1.39.0" },
|
||||
{ name = "opentelemetry-instrumentation-fastapi", specifier = ">=0.60b0" },
|
||||
{ name = "opentelemetry-instrumentation-logging", specifier = ">=0.60b0" },
|
||||
{ name = "opentelemetry-instrumentation-sqlalchemy", specifier = ">=0.60b0" },
|
||||
{ name = "opentelemetry-sdk", specifier = ">=1.39.0" },
|
||||
{ name = "prometheus-client", specifier = ">=0.23.1" },
|
||||
{ name = "psutil", specifier = ">=7.1.3" },
|
||||
{ name = "psycopg", extras = ["binary"], specifier = "==3.2.10" },
|
||||
{ name = "pwdlib", specifier = ">=0.3.0" },
|
||||
@@ -901,6 +913,18 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/c2/69/a7c4ba2ffbc7c7dbf6d8b4f5d0f0a421f7815d229f4909854266c445a3d4/gevent-25.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:bb63c0d6cb9950cc94036a4995b9cc4667b8915366613449236970f4394f94d7" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "googleapis-common-protos"
|
||||
version = "1.72.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "protobuf" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e5/7b/adfd75544c415c487b33061fe7ae526165241c1ea133f9a9125a56b39fd8/googleapis_common_protos-1.72.0.tar.gz", hash = "sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "granian"
|
||||
version = "2.6.0"
|
||||
@@ -1051,6 +1075,67 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "grpcio"
|
||||
version = "1.76.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b6/e0/318c1ce3ae5a17894d5791e87aea147587c9e702f24122cc7a5c8bbaeeb1/grpcio-1.76.0.tar.gz", hash = "sha256:7be78388d6da1a25c0d5ec506523db58b18be22d9c37d8d3a32c08be4987bd73" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/88/17/ff4795dc9a34b6aee6ec379f1b66438a3789cd1315aac0cbab60d92f74b3/grpcio-1.76.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:65a20de41e85648e00305c1bb09a3598f840422e522277641145a32d42dcefcc" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/4e/ff/35f9b96e3fa2f12e1dcd58a4513a2e2294a001d64dec81677361b7040c9a/grpcio-1.76.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:40ad3afe81676fd9ec6d9d406eda00933f218038433980aa19d401490e46ecde" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/3e/1c/8374990f9545e99462caacea5413ed783014b3b66ace49e35c533f07507b/grpcio-1.76.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:035d90bc79eaa4bed83f524331d55e35820725c9fbb00ffa1904d5550ed7ede3" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/1e/77/36fd7d7c75a6c12542c90a6d647a27935a1ecaad03e0ffdb7c42db6b04d2/grpcio-1.76.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4215d3a102bd95e2e11b5395c78562967959824156af11fa93d18fdd18050990" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/38/f7/e3cdb252492278e004722306c5a8935eae91e64ea11f0af3437a7de2e2b7/grpcio-1.76.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:49ce47231818806067aea3324d4bf13825b658ad662d3b25fada0bdad9b8a6af" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/7e/20/340db7af162ccd20a0893b5f3c4a5d676af7b71105517e62279b5b61d95a/grpcio-1.76.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8cc3309d8e08fd79089e13ed4819d0af72aa935dd8f435a195fd152796752ff2" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/10/f0/b2160addc1487bd8fa4810857a27132fb4ce35c1b330c2f3ac45d697b106/grpcio-1.76.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:971fd5a1d6e62e00d945423a567e42eb1fa678ba89072832185ca836a94daaa6" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/2c/2c/ac6f98aa113c6ef111b3f347854e99ebb7fb9d8f7bb3af1491d438f62af4/grpcio-1.76.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d9adda641db7207e800a7f089068f6f645959f2df27e870ee81d44701dd9db3" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/90/84/7852f7e087285e3ac17a2703bc4129fafee52d77c6c82af97d905566857e/grpcio-1.76.0-cp310-cp310-win32.whl", hash = "sha256:063065249d9e7e0782d03d2bca50787f53bd0fb89a67de9a7b521c4a01f1989b" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/10/30/d3d2adcbb6dd3ff59d6ac3df6ef830e02b437fb5c90990429fd180e52f30/grpcio-1.76.0-cp310-cp310-win_amd64.whl", hash = "sha256:a6ae758eb08088d36812dd5d9af7a9859c05b1e0f714470ea243694b49278e7b" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/a0/00/8163a1beeb6971f66b4bbe6ac9457b97948beba8dd2fc8e1281dce7f79ec/grpcio-1.76.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2e1743fbd7f5fa713a1b0a8ac8ebabf0ec980b5d8809ec358d488e273b9cf02a" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/10/c1/934202f5cf335e6d852530ce14ddb0fef21be612ba9ecbbcbd4d748ca32d/grpcio-1.76.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:a8c2cf1209497cf659a667d7dea88985e834c24b7c3b605e6254cbb5076d985c" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/11/0b/8dec16b1863d74af6eb3543928600ec2195af49ca58b16334972f6775663/grpcio-1.76.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:08caea849a9d3c71a542827d6df9d5a69067b0a1efbea8a855633ff5d9571465" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/d7/64/7b9e6e7ab910bea9d46f2c090380bab274a0b91fb0a2fe9b0cd399fffa12/grpcio-1.76.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f0e34c2079d47ae9f6188211db9e777c619a21d4faba6977774e8fa43b085e48" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/68/86/093c46e9546073cefa789bd76d44c5cb2abc824ca62af0c18be590ff13ba/grpcio-1.76.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8843114c0cfce61b40ad48df65abcfc00d4dba82eae8718fab5352390848c5da" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/f7/b6/5709a3a68500a9c03da6fb71740dcdd5ef245e39266461a03f31a57036d8/grpcio-1.76.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8eddfb4d203a237da6f3cc8a540dad0517d274b5a1e9e636fd8d2c79b5c1d397" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/91/d3/4b1f2bf16ed52ce0b508161df3a2d186e4935379a159a834cb4a7d687429/grpcio-1.76.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:32483fe2aab2c3794101c2a159070584e5db11d0aa091b2c0ea9c4fc43d0d749" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/5c/61/d9043f95f5f4cf085ac5dd6137b469d41befb04bd80280952ffa2a4c3f12/grpcio-1.76.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dcfe41187da8992c5f40aa8c5ec086fa3672834d2be57a32384c08d5a05b4c00" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/36/95/fd9a5152ca02d8881e4dd419cdd790e11805979f499a2e5b96488b85cf27/grpcio-1.76.0-cp311-cp311-win32.whl", hash = "sha256:2107b0c024d1b35f4083f11245c0e23846ae64d02f40b2b226684840260ed054" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/60/9c/5c359c8d4c9176cfa3c61ecd4efe5affe1f38d9bae81e81ac7186b4c9cc8/grpcio-1.76.0-cp311-cp311-win_amd64.whl", hash = "sha256:522175aba7af9113c48ec10cc471b9b9bd4f6ceb36aeb4544a8e2c80ed9d252d" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/bf/05/8e29121994b8d959ffa0afd28996d452f291b48cfc0875619de0bde2c50c/grpcio-1.76.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:81fd9652b37b36f16138611c7e884eb82e0cec137c40d3ef7c3f9b3ed00f6ed8" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/d9/75/11d0e66b3cdf998c996489581bdad8900db79ebd83513e45c19548f1cba4/grpcio-1.76.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:04bbe1bfe3a68bbfd4e52402ab7d4eb59d72d02647ae2042204326cf4bbad280" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/28/50/2f0aa0498bc188048f5d9504dcc5c2c24f2eb1a9337cd0fa09a61a2e75f0/grpcio-1.76.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d388087771c837cdb6515539f43b9d4bf0b0f23593a24054ac16f7a960be16f4" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/66/e5/bbf0bb97d29ede1d59d6588af40018cfc345b17ce979b7b45424628dc8bb/grpcio-1.76.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9f8f757bebaaea112c00dba718fc0d3260052ce714e25804a03f93f5d1c6cc11" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/f5/86/f6ec2164f743d9609691115ae8ece098c76b894ebe4f7c94a655c6b03e98/grpcio-1.76.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:980a846182ce88c4f2f7e2c22c56aefd515daeb36149d1c897f83cf57999e0b6" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/60/bc/8d9d0d8505feccfdf38a766d262c71e73639c165b311c9457208b56d92ae/grpcio-1.76.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f92f88e6c033db65a5ae3d97905c8fea9c725b63e28d5a75cb73b49bda5024d8" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/67/e6/5d6c2fc10b95edf6df9b8f19cf10a34263b7fd48493936fffd5085521292/grpcio-1.76.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4baf3cbe2f0be3289eb68ac8ae771156971848bb8aaff60bad42005539431980" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/3f/c8/dce8ff21c86abe025efe304d9e31fdb0deaaa3b502b6a78141080f206da0/grpcio-1.76.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:615ba64c208aaceb5ec83bfdce7728b80bfeb8be97562944836a7a0a9647d882" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e0/42/ad28191ebf983a5d0ecef90bab66baa5a6b18f2bfdef9d0a63b1973d9f75/grpcio-1.76.0-cp312-cp312-win32.whl", hash = "sha256:45d59a649a82df5718fd9527ce775fd66d1af35e6d31abdcdc906a49c6822958" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/9e/00/7bd478cbb851c04a48baccaa49b75abaa8e4122f7d86da797500cccdd771/grpcio-1.76.0-cp312-cp312-win_amd64.whl", hash = "sha256:c088e7a90b6017307f423efbb9d1ba97a22aa2170876223f9709e9d1de0b5347" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/fc/ed/71467ab770effc9e8cef5f2e7388beb2be26ed642d567697bb103a790c72/grpcio-1.76.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:26ef06c73eb53267c2b319f43e6634c7556ea37672029241a056629af27c10e2" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/2c/85/c6ed56f9817fab03fa8a111ca91469941fb514e3e3ce6d793cb8f1e1347b/grpcio-1.76.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:45e0111e73f43f735d70786557dc38141185072d7ff8dc1829d6a77ac1471468" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/ac/31/2b8a235ab40c39cbc141ef647f8a6eb7b0028f023015a4842933bc0d6831/grpcio-1.76.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:83d57312a58dcfe2a3a0f9d1389b299438909a02db60e2f2ea2ae2d8034909d3" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/bd/64/9784eab483358e08847498ee56faf8ff6ea8e0a4592568d9f68edc97e9e9/grpcio-1.76.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:3e2a27c89eb9ac3d81ec8835e12414d73536c6e620355d65102503064a4ed6eb" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/2b/94/8c12319a6369434e7a184b987e8e9f3b49a114c489b8315f029e24de4837/grpcio-1.76.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61f69297cba3950a524f61c7c8ee12e55c486cb5f7db47ff9dcee33da6f0d3ae" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/15/0f/f12c32b03f731f4a6242f771f63039df182c8b8e2cf8075b245b409259d4/grpcio-1.76.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6a15c17af8839b6801d554263c546c69c4d7718ad4321e3166175b37eaacca77" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/ff/2d/3ec9ce0c2b1d92dd59d1c3264aaec9f0f7c817d6e8ac683b97198a36ed5a/grpcio-1.76.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:25a18e9810fbc7e7f03ec2516addc116a957f8cbb8cbc95ccc80faa072743d03" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/1a/74/fd3317be5672f4856bcdd1a9e7b5e17554692d3db9a3b273879dc02d657d/grpcio-1.76.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:931091142fd8cc14edccc0845a79248bc155425eee9a98b2db2ea4f00a235a42" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/45/bb/ca038cf420f405971f19821c8c15bcbc875505f6ffadafe9ffd77871dc4c/grpcio-1.76.0-cp313-cp313-win32.whl", hash = "sha256:5e8571632780e08526f118f74170ad8d50fb0a48c23a746bef2a6ebade3abd6f" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/41/80/84087dc56437ced7cdd4b13d7875e7439a52a261e3ab4e06488ba6173b0a/grpcio-1.76.0-cp313-cp313-win_amd64.whl", hash = "sha256:f9f7bd5faab55f47231ad8dba7787866b69f5e93bc306e3915606779bbfb4ba8" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/b4/46/39adac80de49d678e6e073b70204091e76631e03e94928b9ea4ecf0f6e0e/grpcio-1.76.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:ff8a59ea85a1f2191a0ffcc61298c571bc566332f82e5f5be1b83c9d8e668a62" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/9c/f5/a4531f7fb8b4e2a60b94e39d5d924469b7a6988176b3422487be61fe2998/grpcio-1.76.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:06c3d6b076e7b593905d04fdba6a0525711b3466f43b3400266f04ff735de0cd" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/4b/1c/de55d868ed7a8bd6acc6b1d6ddc4aa36d07a9f31d33c912c804adb1b971b/grpcio-1.76.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd5ef5932f6475c436c4a55e4336ebbe47bd3272be04964a03d316bbf4afbcbc" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/59/64/99e44c02b5adb0ad13ab3adc89cb33cb54bfa90c74770f2607eea629b86f/grpcio-1.76.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b331680e46239e090f5b3cead313cc772f6caa7d0fc8de349337563125361a4a" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/43/28/40a5be3f9a86949b83e7d6a2ad6011d993cbe9b6bd27bea881f61c7788b6/grpcio-1.76.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2229ae655ec4e8999599469559e97630185fdd53ae1e8997d147b7c9b2b72cba" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/4b/a9/1be18e6055b64467440208a8559afac243c66a8b904213af6f392dc2212f/grpcio-1.76.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:490fa6d203992c47c7b9e4a9d39003a0c2bcc1c9aa3c058730884bbbb0ee9f09" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/0f/55/dba05d3fcc151ce6e81327541d2cc8394f442f6b350fead67401661bf041/grpcio-1.76.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:479496325ce554792dba6548fae3df31a72cef7bad71ca2e12b0e58f9b336bfc" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/4a/45/122df922d05655f63930cf42c9e3f72ba20aadb26c100ee105cad4ce4257/grpcio-1.76.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c9b93f79f48b03ada57ea24725d83a30284a012ec27eab2cf7e50a550cbbbcc" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/4a/6e/0b899b7f6b66e5af39e377055fb4a6675c9ee28431df5708139df2e93233/grpcio-1.76.0-cp314-cp314-win32.whl", hash = "sha256:747fa73efa9b8b1488a95d0ba1039c8e2dca0f741612d80415b1e1c560febf4e" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/19/41/0b430b01a2eb38ee887f88c1f07644a1df8e289353b78e82b37ef988fb64/grpcio-1.76.0-cp314-cp314-win_amd64.whl", hash = "sha256:922fa70ba549fce362d2e2871ab542082d66e2aaf0c19480ea453905b01f384e" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.16.0"
|
||||
@@ -1235,6 +1320,18 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "8.7.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "zipp" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.3.0"
|
||||
@@ -1614,6 +1711,173 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-api"
|
||||
version = "1.39.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "importlib-metadata" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c0/0b/e5428c009d4d9af0515b0a8371a8aaae695371af291f45e702f7969dce6b/opentelemetry_api-1.39.0.tar.gz", hash = "sha256:6130644268c5ac6bdffaf660ce878f10906b3e789f7e2daa5e169b047a2933b9" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/05/85/d831a9bc0a9e0e1a304ff3d12c1489a5fbc9bf6690a15dcbdae372bbca45/opentelemetry_api-1.39.0-py3-none-any.whl", hash = "sha256:3c3b3ca5c5687b1b5b37e5c5027ff68eacea8675241b29f13110a8ffbb8f0459" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-exporter-otlp-proto-common"
|
||||
version = "1.39.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-proto" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/11/cb/3a29ce606b10c76d413d6edd42d25a654af03e73e50696611e757d2602f3/opentelemetry_exporter_otlp_proto_common-1.39.0.tar.gz", hash = "sha256:a135fceed1a6d767f75be65bd2845da344dd8b9258eeed6bc48509d02b184409" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/ef/c6/215edba62d13a3948c718b289539f70e40965bc37fc82ecd55bb0b749c1a/opentelemetry_exporter_otlp_proto_common-1.39.0-py3-none-any.whl", hash = "sha256:3d77be7c4bdf90f1a76666c934368b8abed730b5c6f0547a2ec57feb115849ac" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-exporter-otlp-proto-grpc"
|
||||
version = "1.39.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "googleapis-common-protos" },
|
||||
{ name = "grpcio" },
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-exporter-otlp-proto-common" },
|
||||
{ name = "opentelemetry-proto" },
|
||||
{ name = "opentelemetry-sdk" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7e/62/4db083ee9620da3065eeb559e9fc128f41a1d15e7c48d7c83aafbccd354c/opentelemetry_exporter_otlp_proto_grpc-1.39.0.tar.gz", hash = "sha256:7e7bb3f436006836c0e0a42ac619097746ad5553ad7128a5bd4d3e727f37fc06" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/56/e8/d420b94ffddfd8cff85bb4aa5d98da26ce7935dc3cf3eca6b83cd39ab436/opentelemetry_exporter_otlp_proto_grpc-1.39.0-py3-none-any.whl", hash = "sha256:758641278050de9bb895738f35ff8840e4a47685b7e6ef4a201fe83196ba7a05" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-instrumentation"
|
||||
version = "0.60b0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-semantic-conventions" },
|
||||
{ name = "packaging" },
|
||||
{ name = "wrapt" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/55/3c/bd53dbb42eff93d18e3047c7be11224aa9966ce98ac4cc5bfb860a32c95a/opentelemetry_instrumentation-0.60b0.tar.gz", hash = "sha256:4e9fec930f283a2677a2217754b40aaf9ef76edae40499c165bc7f1d15366a74" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/5c/7b/5b5b9f8cfe727a28553acf9cd287b1d7f706f5c0a00d6e482df55b169483/opentelemetry_instrumentation-0.60b0-py3-none-any.whl", hash = "sha256:aaafa1483543a402819f1bdfb06af721c87d60dd109501f9997332862a35c76a" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-instrumentation-asgi"
|
||||
version = "0.60b0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "asgiref" },
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-instrumentation" },
|
||||
{ name = "opentelemetry-semantic-conventions" },
|
||||
{ name = "opentelemetry-util-http" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b0/0a/715ea7044708d3c215385fb2a1c6ffe429aacb3cd23a348060aaeda52834/opentelemetry_instrumentation_asgi-0.60b0.tar.gz", hash = "sha256:928731218050089dca69f0fe980b8bfe109f384be8b89802d7337372ddb67b91" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/9b/8c/c6c59127fd996107243ca45669355665a7daff578ddafb86d6d2d3b01428/opentelemetry_instrumentation_asgi-0.60b0-py3-none-any.whl", hash = "sha256:9d76a541269452c718a0384478f3291feb650c5a3f29e578fdc6613ea3729cf3" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-instrumentation-fastapi"
|
||||
version = "0.60b0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-instrumentation" },
|
||||
{ name = "opentelemetry-instrumentation-asgi" },
|
||||
{ name = "opentelemetry-semantic-conventions" },
|
||||
{ name = "opentelemetry-util-http" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fe/51/a021a7c929b5103fcb6bfdfa5a99abcaeb3b505faf9e3ee3ec14612c1ef9/opentelemetry_instrumentation_fastapi-0.60b0.tar.gz", hash = "sha256:5d34d67eb634a08bfe9e530680d6177521cd9da79285144e6d5a8f42683ed1b3" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/b1/5a/e238c108eb65a726d75184439377a87d532050036b54e718e4c789b26d1a/opentelemetry_instrumentation_fastapi-0.60b0-py3-none-any.whl", hash = "sha256:415c6602db01ee339276ea4cabe3e80177c9e955631c087f2ef60a75e31bfaee" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-instrumentation-logging"
|
||||
version = "0.60b0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-instrumentation" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/5b/8b/a1aed0b695a58a1f0bdcf90fae5e468cc0fd7de2b74b9816b17e45c38e43/opentelemetry_instrumentation_logging-0.60b0.tar.gz", hash = "sha256:6d87840666669cbbcd53d2230c7a33476862d0bf7f1adc67a95519c6ccfc8281" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/00/89/6d4f5d8d03376637bff5b8d9e91356104a6f1ce9a34a2099bb2f4bf5e2b5/opentelemetry_instrumentation_logging-0.60b0-py3-none-any.whl", hash = "sha256:af75b3020911b9b6a1b4b19819a165eb131ce9bfdd313062d578fc2dc9a5cd0f" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-instrumentation-sqlalchemy"
|
||||
version = "0.60b0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-instrumentation" },
|
||||
{ name = "opentelemetry-semantic-conventions" },
|
||||
{ name = "packaging" },
|
||||
{ name = "wrapt" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8f/52/6a6e8ef8d0430487f1c65fdb81f2001d0b3b68de72f7437b54ff2330de44/opentelemetry_instrumentation_sqlalchemy-0.60b0.tar.gz", hash = "sha256:df9fdc6f48709138343971cef95a055f52d0262331115231bd5d678c1a452891" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e0/08/943c1c650e7826b0462f0a2528d37b9cf717957955df6259b9c25dfcaa51/opentelemetry_instrumentation_sqlalchemy-0.60b0-py3-none-any.whl", hash = "sha256:ff66ac39364bfb38fe127f823b36693c6f2a44f929926863640ac1575583a73f" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-proto"
|
||||
version = "1.39.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "protobuf" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/48/b5/64d2f8c3393cd13ea2092106118f7b98461ba09333d40179a31444c6f176/opentelemetry_proto-1.39.0.tar.gz", hash = "sha256:c1fa48678ad1a1624258698e59be73f990b7fc1f39e73e16a9d08eef65dd838c" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e3/4d/d500e1862beed68318705732d1976c390f4a72ca8009c4983ff627acff20/opentelemetry_proto-1.39.0-py3-none-any.whl", hash = "sha256:1e086552ac79acb501485ff0ce75533f70f3382d43d0a30728eeee594f7bf818" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-sdk"
|
||||
version = "1.39.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-semantic-conventions" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/51/e3/7cd989003e7cde72e0becfe830abff0df55c69d237ee7961a541e0167833/opentelemetry_sdk-1.39.0.tar.gz", hash = "sha256:c22204f12a0529e07aa4d985f1bca9d6b0e7b29fe7f03e923548ae52e0e15dde" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/a4/b4/2adc8bc83eb1055ecb592708efb6f0c520cc2eb68970b02b0f6ecda149cf/opentelemetry_sdk-1.39.0-py3-none-any.whl", hash = "sha256:90cfb07600dfc0d2de26120cebc0c8f27e69bf77cd80ef96645232372709a514" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-semantic-conventions"
|
||||
version = "0.60b0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/71/0e/176a7844fe4e3cb5de604212094dffaed4e18b32f1c56b5258bcbcba85c2/opentelemetry_semantic_conventions-0.60b0.tar.gz", hash = "sha256:227d7aa73cbb8a2e418029d6b6465553aa01cf7e78ec9d0bc3255c7b3ac5bf8f" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/d0/56/af0306666f91bae47db14d620775604688361f0f76a872e0005277311131/opentelemetry_semantic_conventions-0.60b0-py3-none-any.whl", hash = "sha256:069530852691136018087b52688857d97bba61cd641d0f8628d2d92788c4f78a" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-util-http"
|
||||
version = "0.60b0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/38/0d/786a713445cf338131fef3a84fab1378e4b2ef3c3ea348eeb0c915eb804a/opentelemetry_util_http-0.60b0.tar.gz", hash = "sha256:e42b7bb49bba43b6f34390327d97e5016eb1c47949ceaf37c4795472a4e3a82d" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/53/5d/a448862f6d10c95685ed0e703596b6bd1784074e7ad90bffdc550abb7b68/opentelemetry_util_http-0.60b0-py3-none-any.whl", hash = "sha256:4f366f1a48adb74ffa6f80aee26f96882e767e01b03cd1cfb948b6e1020341fe" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "25.0"
|
||||
@@ -1900,6 +2164,21 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "6.33.2"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psutil"
|
||||
version = "7.1.3"
|
||||
@@ -3073,6 +3352,75 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wrapt"
|
||||
version = "1.17.3"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/3f/23/bb82321b86411eb51e5a5db3fb8f8032fd30bd7c2d74bfe936136b2fa1d6/wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/45/69/f3c47642b79485a30a59c63f6d739ed779fb4cc8323205d047d741d55220/wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/d1/71/e7e7f5670c1eafd9e990438e69d8fb46fa91a50785332e06b560c869454f/wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/de/17/9f8f86755c191d6779d7ddead1a53c7a8aa18bccb7cea8e7e72dfa6a8a09/wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/f2/15/dd576273491f9f43dd09fce517f6c2ce6eb4fe21681726068db0d0467096/wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/0c/c4/5eb4ce0d4814521fee7aa806264bf7a114e748ad05110441cd5b8a5c744b/wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/31/4b/819e9e0eb5c8dc86f60dfc42aa4e2c0d6c3db8732bce93cc752e604bb5f5/wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/f8/83/ed6baf89ba3a56694700139698cf703aac9f0f9eb03dab92f57551bd5385/wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/2f/90/ee61d36862340ad7e9d15a02529df6b948676b9a5829fd5e16640156627d/wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/bd/c3/cefe0bd330d389c9983ced15d326f45373f4073c9f4a8c2f99b50bfea329/wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/5d/8f/a32a99fc03e4b37e31b57cb9cefc65050ea08147a8ce12f288616b05ef54/wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/31/57/4930cb8d9d70d59c27ee1332a318c20291749b4fba31f113c2f8ac49a72e/wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/a8/f3/1afd48de81d63dd66e01b263a6fbb86e1b5053b419b9b33d13e1f6d0f7d0/wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/1e/d7/4ad5327612173b144998232f98a85bb24b60c352afb73bc48e3e0d2bdc4e/wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/bb/59/e0adfc831674a65694f18ea6dc821f9fcb9ec82c2ce7e3d73a88ba2e8718/wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/83/88/16b7231ba49861b6f75fc309b11012ede4d6b0a9c90969d9e0db8d991aeb/wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/9a/1e/c4d4f3398ec073012c51d1c8d87f715f56765444e1a4b11e5180577b7e6e/wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wsproto"
|
||||
version = "1.3.2"
|
||||
@@ -3211,6 +3559,15 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.23.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zope-event"
|
||||
version = "6.1"
|
||||
|
||||
Reference in New Issue
Block a user