server.py: Добавлено детальное логирование

This commit is contained in:
2025-12-25 15:01:29 +05:00
parent a1bb30fb72
commit 02a003fdef

View File

@@ -1,11 +1,13 @@
from __future__ import annotations
import json
from types import SimpleNamespace
import loguru
import asyncio
from types import SimpleNamespace
from weakref import WeakValueDictionary, WeakSet, finalize
from collections import UserDict
from uuid import uuid4
from loguru import logger
from fastapi import WebSocket, FastAPI, WebSocketDisconnect, WebSocketException
from .event import call_event
@@ -19,7 +21,6 @@ class TopicWeakDict(UserDict):
super().__setitem__(key, value)
class Server:
_logger: loguru.Logger = loguru.logger
_static_tokens: list[str] = []
_temp_tokens: list[str] = []
_server_connection: WebSocket | None = None
@@ -60,6 +61,16 @@ class Server:
data = json.dumps(data)
# Меняем синтаксис под Squirrel
data = data.replace("'", '\\"').replace('True', 'true').replace('False', 'false')
logs_connection_list = [f"{item.client.host}:{item.client.port}" for item in connection_list]
logger.info(
'Отправлено новое сообщение по каналу WebSocket',
log_type = 'PyG2O',
receivers = logs_connection_list,
message_uuid = data[uuid],
message_data = data,
)
asyncio.create_task(cls._async_send(connection_list, data))
return request
@@ -118,7 +129,11 @@ class Server:
await connection.accept()
await cls._subscribe(['all'], connection)
cls._logger.info('WebSocket клиент подключился')
logger.info(
'WebSocket клиент подключился',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
)
try:
while True:
@@ -127,16 +142,37 @@ class Server:
message_data = json.loads(data)
asyncio.create_task(cls._process_message(connection, message_data))
except json.JSONDecodeError as e:
cls._logger.exception(f'Ошибка декодирования JSON: {e}')
logger.info(
'Ошибка декодирования JSON сообщения',
log_type = 'PyG2O',
description = e,
message_data = data,
connection = f"{connection.client.host}:{connection.client.port}",
)
except WebSocketDisconnect:
cls._logger.info('WebSocket клиент отключился')
if connection == cls._server_connection:
cls._server_connection = None
logger.info(
'WebSocket G2O сервер отключился',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
)
else:
playerid = next((key for key, values in cls._registered_clients.items() if connection in values), None)
if playerid is not None: cls._registered_clients[playerid].remove(connection)
logger.info(
'WebSocket клиент отключился',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
playerid = playerid,
)
except WebSocketException as e:
cls._logger.exception(f'Ошибка WebSocket подключения: {e}')
logger.exception(
'Ошибка при обработке WebSocket сообщения',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
description = e,
)
@classmethod
async def _process_message(cls, connection: WebSocket, message: dict):
@@ -162,26 +198,75 @@ class Server:
cls._registered_clients[playerid].append(connection)
except KeyError:
cls._registered_clients[playerid] = [connection]
logs_connection_list = [f"{item.client.host}:{item.client.port}" for item in cls._registered_clients[playerid]]
logger.info(
'Зарегистрирован новый WebSocket клиент',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
playerid = playerid,
total_playerid_connections = logs_connection_list,
)
case {'event': 'register_server'}:
if cls._server_connection is None:
cls._server_connection = connection
logger.info(
'Зарегистрирован новый WebSocket G2O сервер',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
)
case {'event': 'sq_response', 'uuid': uuid, 'data': data}:
try:
cls._requests[uuid].set_result(data)
logger.info(
'Получен ответ от G2O сервера (sq_response)',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
message_uuid = uuid,
message_data = data,
)
except KeyError:
...
logger.warning(
'Получен неожиданный ответ от G2O сервера',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
message_uuid = uuid,
message_data = data,
)
case {'event': event, 'uuid': uuid, **kwargs}:
try:
cls._requests[uuid].set_result(SimpleNamespace(**kwargs))
logger.info(
'Получен ответ от клиента',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
message_event = event,
message_uuid = uuid,
message_data = kwargs,
)
except KeyError:
kwargs['uuid'] = uuid
kwargs['connection'] = connection
playerid = next((key for key, values in cls._registered_clients.items() if connection in values), None)
if playerid is not None: kwargs['playerid'] = playerid
asyncio.create_task(call_event(event, **kwargs))
logger.info(
'Получено сообщение от сервера' if connection == cls._server_connection else 'Получено сообщение от клиента',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
message_event = event,
message_uuid = uuid,
message_data = kwargs,
)
case _:
logger.error(
'Получено неподдерживаемое сообщение от сервера' if connection == cls._server_connection else 'Получено неподдерживаемое сообщение от клиента',
log_type = 'PyG2O',
connection = f"{connection.client.host}:{connection.client.port}",
message_data = message,
)
raise ValueError(f'Неподдерживаемый тип PyG2O сообщения: {message}')