Refactor: add rxtx debugger log
This commit is contained in:
parent
ea31261bff
commit
0ee3825563
5 changed files with 264 additions and 9 deletions
49
app.py
49
app.py
|
@ -18,6 +18,10 @@ from detector_worker.core.singleton_managers import (
|
||||||
from detector_worker.communication.websocket_handler import WebSocketHandler
|
from detector_worker.communication.websocket_handler import WebSocketHandler
|
||||||
from detector_worker.utils.system_monitor import get_system_metrics
|
from detector_worker.utils.system_monitor import get_system_metrics
|
||||||
from detector_worker.utils.error_handler import ErrorHandler, create_logger
|
from detector_worker.utils.error_handler import ErrorHandler, create_logger
|
||||||
|
from detector_worker.utils.websocket_debug import (
|
||||||
|
setup_websocket_logging, enable_websocket_debug, disable_websocket_debug,
|
||||||
|
get_websocket_debug_status
|
||||||
|
)
|
||||||
|
|
||||||
# Setup logging
|
# Setup logging
|
||||||
logger = create_logger("detector_worker.main", logging.INFO)
|
logger = create_logger("detector_worker.main", logging.INFO)
|
||||||
|
@ -54,6 +58,9 @@ async def lifespan(app: FastAPI):
|
||||||
|
|
||||||
logger.info("Configuration validation passed")
|
logger.info("Configuration validation passed")
|
||||||
|
|
||||||
|
# Setup WebSocket logging based on configuration
|
||||||
|
setup_websocket_logging()
|
||||||
|
|
||||||
# Log startup information
|
# Log startup information
|
||||||
config = config_manager.get_all()
|
config = config_manager.get_all()
|
||||||
logger.info(f"Max streams: {config.get('max_streams', 5)}")
|
logger.info(f"Max streams: {config.get('max_streams', 5)}")
|
||||||
|
@ -211,6 +218,48 @@ async def reload_configuration():
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/debug/websocket")
|
||||||
|
async def get_websocket_debug_status():
|
||||||
|
"""Get current WebSocket debugging status."""
|
||||||
|
try:
|
||||||
|
return get_websocket_debug_status()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error getting WebSocket debug status: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/debug/websocket/enable")
|
||||||
|
async def enable_websocket_debugging():
|
||||||
|
"""Enable WebSocket debugging."""
|
||||||
|
try:
|
||||||
|
enable_websocket_debug()
|
||||||
|
logger.info("WebSocket debugging enabled via API")
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"message": "WebSocket debugging enabled",
|
||||||
|
"status": get_websocket_debug_status()
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error enabling WebSocket debugging: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/debug/websocket/disable")
|
||||||
|
async def disable_websocket_debugging():
|
||||||
|
"""Disable WebSocket debugging."""
|
||||||
|
try:
|
||||||
|
disable_websocket_debug()
|
||||||
|
logger.info("WebSocket debugging disabled via API")
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"message": "WebSocket debugging disabled",
|
||||||
|
"status": get_websocket_debug_status()
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error disabling WebSocket debugging: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ from ..core.exceptions import ValidationError, MessageProcessingError
|
||||||
|
|
||||||
# Setup logging
|
# Setup logging
|
||||||
logger = logging.getLogger("detector_worker.message_processor")
|
logger = logging.getLogger("detector_worker.message_processor")
|
||||||
|
msg_proc_logger = logging.getLogger("websocket.message_processor") # Detailed message processing logger
|
||||||
|
|
||||||
|
|
||||||
class MessageType(Enum):
|
class MessageType(Enum):
|
||||||
|
@ -161,24 +162,31 @@ class MessageProcessor:
|
||||||
Raises:
|
Raises:
|
||||||
MessageProcessingError: If message is invalid
|
MessageProcessingError: If message is invalid
|
||||||
"""
|
"""
|
||||||
|
msg_proc_logger.debug(f"📨 PARSING MESSAGE: {raw_message[:100]}{'...' if len(raw_message) > 100 else ''}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = json.loads(raw_message)
|
data = json.loads(raw_message)
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
|
msg_proc_logger.error(f"❌ JSON PARSE ERROR: {e}")
|
||||||
raise MessageProcessingError(f"Invalid JSON: {e}")
|
raise MessageProcessingError(f"Invalid JSON: {e}")
|
||||||
|
|
||||||
# Validate message structure
|
# Validate message structure
|
||||||
if not isinstance(data, dict):
|
if not isinstance(data, dict):
|
||||||
|
msg_proc_logger.error(f"❌ INVALID MESSAGE STRUCTURE: Expected dict, got {type(data)}")
|
||||||
raise MessageProcessingError("Message must be a JSON object")
|
raise MessageProcessingError("Message must be a JSON object")
|
||||||
|
|
||||||
# Extract message type
|
# Extract message type
|
||||||
msg_type_str = data.get("type")
|
msg_type_str = data.get("type")
|
||||||
if not msg_type_str:
|
if not msg_type_str:
|
||||||
|
msg_proc_logger.error("❌ MISSING MESSAGE TYPE")
|
||||||
raise MessageProcessingError("Missing 'type' field in message")
|
raise MessageProcessingError("Missing 'type' field in message")
|
||||||
|
|
||||||
# Convert to MessageType enum
|
# Convert to MessageType enum
|
||||||
try:
|
try:
|
||||||
msg_type = MessageType(msg_type_str)
|
msg_type = MessageType(msg_type_str)
|
||||||
|
msg_proc_logger.debug(f"✅ PARSED MESSAGE TYPE: {msg_type.value}")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
msg_proc_logger.error(f"❌ UNKNOWN MESSAGE TYPE: {msg_type_str}")
|
||||||
raise MessageProcessingError(f"Unknown message type: {msg_type_str}")
|
raise MessageProcessingError(f"Unknown message type: {msg_type_str}")
|
||||||
|
|
||||||
return msg_type, data
|
return msg_type, data
|
||||||
|
@ -197,13 +205,22 @@ class MessageProcessor:
|
||||||
Raises:
|
Raises:
|
||||||
ValidationError: If validation fails
|
ValidationError: If validation fails
|
||||||
"""
|
"""
|
||||||
|
msg_proc_logger.debug(f"🔍 VALIDATING {msg_type.value} MESSAGE")
|
||||||
|
|
||||||
# Get validator for message type
|
# Get validator for message type
|
||||||
validator = self.validators.get(msg_type)
|
validator = self.validators.get(msg_type)
|
||||||
if not validator:
|
if not validator:
|
||||||
# No validation needed for some message types
|
# No validation needed for some message types
|
||||||
|
msg_proc_logger.debug(f"ℹ️ NO VALIDATION NEEDED FOR {msg_type.value}")
|
||||||
return data.get("payload", {})
|
return data.get("payload", {})
|
||||||
|
|
||||||
return validator(data)
|
try:
|
||||||
|
result = validator(data)
|
||||||
|
msg_proc_logger.debug(f"✅ VALIDATION SUCCESS FOR {msg_type.value}")
|
||||||
|
return result
|
||||||
|
except ValidationError as e:
|
||||||
|
msg_proc_logger.error(f"❌ VALIDATION FAILED FOR {msg_type.value}: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
def _validate_subscribe(self, data: Dict[str, Any]) -> SubscribePayload:
|
def _validate_subscribe(self, data: Dict[str, Any]) -> SubscribePayload:
|
||||||
"""Validate subscribe message."""
|
"""Validate subscribe message."""
|
||||||
|
|
|
@ -32,6 +32,7 @@ from ..utils.system_monitor import get_system_metrics
|
||||||
# Setup logging
|
# Setup logging
|
||||||
logger = logging.getLogger("detector_worker.websocket_handler")
|
logger = logging.getLogger("detector_worker.websocket_handler")
|
||||||
ws_logger = logging.getLogger("websocket")
|
ws_logger = logging.getLogger("websocket")
|
||||||
|
ws_rxtx_logger = logging.getLogger("websocket.rxtx") # Dedicated RX/TX logger
|
||||||
|
|
||||||
# Type definitions for callbacks
|
# Type definitions for callbacks
|
||||||
MessageHandler = Callable[[Dict[str, Any]], asyncio.coroutine]
|
MessageHandler = Callable[[Dict[str, Any]], asyncio.coroutine]
|
||||||
|
@ -109,7 +110,11 @@ class WebSocketHandler:
|
||||||
self.websocket = websocket
|
self.websocket = websocket
|
||||||
self.connected = True
|
self.connected = True
|
||||||
|
|
||||||
logger.info("WebSocket connection accepted")
|
# Log connection details
|
||||||
|
client_host = getattr(websocket.client, 'host', 'unknown')
|
||||||
|
client_port = getattr(websocket.client, 'port', 'unknown')
|
||||||
|
logger.info(f"🔗 WebSocket connection accepted from {client_host}:{client_port}")
|
||||||
|
ws_rxtx_logger.info(f"CONNECT -> Client: {client_host}:{client_port}")
|
||||||
|
|
||||||
# Create concurrent tasks
|
# Create concurrent tasks
|
||||||
stream_task = asyncio.create_task(self._process_streams())
|
stream_task = asyncio.create_task(self._process_streams())
|
||||||
|
@ -126,6 +131,9 @@ class WebSocketHandler:
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self.connected = False
|
self.connected = False
|
||||||
|
client_host = getattr(websocket.client, 'host', 'unknown') if websocket.client else 'unknown'
|
||||||
|
client_port = getattr(websocket.client, 'port', 'unknown') if websocket.client else 'unknown'
|
||||||
|
ws_rxtx_logger.info(f"DISCONNECT -> Client: {client_host}:{client_port}")
|
||||||
await self._cleanup()
|
await self._cleanup()
|
||||||
|
|
||||||
async def _cleanup(self) -> None:
|
async def _cleanup(self) -> None:
|
||||||
|
@ -181,7 +189,9 @@ class WebSocketHandler:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ws_logger.info(f"TX -> {json.dumps(state_data, separators=(',', ':'))}")
|
# Compact JSON for RX/TX logging
|
||||||
|
compact_json = json.dumps(state_data, separators=(',', ':'))
|
||||||
|
ws_rxtx_logger.info(f"TX -> {compact_json}")
|
||||||
await self.websocket.send_json(state_data)
|
await self.websocket.send_json(state_data)
|
||||||
|
|
||||||
await asyncio.sleep(HEARTBEAT_INTERVAL)
|
await asyncio.sleep(HEARTBEAT_INTERVAL)
|
||||||
|
@ -198,16 +208,21 @@ class WebSocketHandler:
|
||||||
while self.connected:
|
while self.connected:
|
||||||
try:
|
try:
|
||||||
text_data = await self.websocket.receive_text()
|
text_data = await self.websocket.receive_text()
|
||||||
ws_logger.info(f"RX <- {text_data}")
|
ws_rxtx_logger.info(f"RX <- {text_data}")
|
||||||
|
|
||||||
data = json.loads(text_data)
|
data = json.loads(text_data)
|
||||||
msg_type = data.get("type")
|
msg_type = data.get("type")
|
||||||
|
|
||||||
|
# Log message processing
|
||||||
|
logger.debug(f"📥 Processing message type: {msg_type}")
|
||||||
|
|
||||||
if msg_type in self.message_handlers:
|
if msg_type in self.message_handlers:
|
||||||
handler = self.message_handlers[msg_type]
|
handler = self.message_handlers[msg_type]
|
||||||
await handler(data)
|
await handler(data)
|
||||||
|
logger.debug(f"✅ Message {msg_type} processed successfully")
|
||||||
else:
|
else:
|
||||||
logger.error(f"Unknown message type: {msg_type}")
|
logger.error(f"❌ Unknown message type: {msg_type}")
|
||||||
|
ws_rxtx_logger.error(f"UNKNOWN_MSG_TYPE -> {msg_type}")
|
||||||
|
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
logger.error("Received invalid JSON message")
|
logger.error("Received invalid JSON message")
|
||||||
|
@ -437,7 +452,7 @@ class WebSocketHandler:
|
||||||
"sessionId": session_id
|
"sessionId": session_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws_logger.info(f"TX -> {json.dumps(response, separators=(',', ':'))}")
|
ws_rxtx_logger.info(f"TX -> {json.dumps(response, separators=(',', ':'))}")
|
||||||
await self.websocket.send_json(response)
|
await self.websocket.send_json(response)
|
||||||
|
|
||||||
logger.info(f"Set session {session_id} for display {display_id}")
|
logger.info(f"Set session {session_id} for display {display_id}")
|
||||||
|
@ -463,7 +478,7 @@ class WebSocketHandler:
|
||||||
"patchData": patch_data
|
"patchData": patch_data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws_logger.info(f"TX -> {json.dumps(response, separators=(',', ':'))}")
|
ws_rxtx_logger.info(f"TX -> {json.dumps(response, separators=(',', ':'))}")
|
||||||
await self.websocket.send_json(response)
|
await self.websocket.send_json(response)
|
||||||
|
|
||||||
async def _handle_set_progression_stage(self, data: Dict[str, Any]) -> None:
|
async def _handle_set_progression_stage(self, data: Dict[str, Any]) -> None:
|
||||||
|
@ -539,7 +554,7 @@ class WebSocketHandler:
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ws_logger.info(f"TX -> {json.dumps(detection_data, separators=(',', ':'))}")
|
ws_rxtx_logger.info(f"TX -> {json.dumps(detection_data, separators=(',', ':'))}")
|
||||||
await self.websocket.send_json(detection_data)
|
await self.websocket.send_json(detection_data)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
if "websocket.close" in str(e):
|
if "websocket.close" in str(e):
|
||||||
|
@ -571,7 +586,7 @@ class WebSocketHandler:
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ws_logger.info(f"TX -> {json.dumps(detection_data, separators=(',', ':'))}")
|
ws_rxtx_logger.info(f"TX -> {json.dumps(detection_data, separators=(',', ':'))}")
|
||||||
await self.websocket.send_json(detection_data)
|
await self.websocket.send_json(detection_data)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
if "websocket.close" in str(e):
|
if "websocket.close" in str(e):
|
||||||
|
|
|
@ -181,6 +181,10 @@ class LoggingConfig:
|
||||||
file_path: Optional[str] = "detector_worker.log"
|
file_path: Optional[str] = "detector_worker.log"
|
||||||
max_file_size_mb: int = 10
|
max_file_size_mb: int = 10
|
||||||
backup_count: int = 5
|
backup_count: int = 5
|
||||||
|
# WebSocket debugging
|
||||||
|
websocket_debug: bool = False
|
||||||
|
websocket_rxtx_log_level: str = "INFO"
|
||||||
|
websocket_message_proc_log_level: str = "DEBUG"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: Dict[str, Any]) -> 'LoggingConfig':
|
def from_dict(cls, data: Dict[str, Any]) -> 'LoggingConfig':
|
||||||
|
@ -244,6 +248,11 @@ class ConfigurationManager:
|
||||||
"session_timeout": 600,
|
"session_timeout": 600,
|
||||||
"models_dir": "models",
|
"models_dir": "models",
|
||||||
"log_level": "INFO",
|
"log_level": "INFO",
|
||||||
|
"logging": {
|
||||||
|
"websocket_debug": False,
|
||||||
|
"websocket_rxtx_log_level": "INFO",
|
||||||
|
"websocket_message_proc_log_level": "DEBUG"
|
||||||
|
},
|
||||||
"database": {
|
"database": {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
|
|
165
detector_worker/utils/websocket_debug.py
Normal file
165
detector_worker/utils/websocket_debug.py
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
"""
|
||||||
|
WebSocket debugging utilities.
|
||||||
|
|
||||||
|
This module provides utilities for configuring WebSocket logging and debugging
|
||||||
|
based on configuration settings.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
from typing import Optional
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ..core.config import get_config_manager
|
||||||
|
|
||||||
|
|
||||||
|
def setup_websocket_logging(
|
||||||
|
enable_debug: Optional[bool] = None,
|
||||||
|
rxtx_log_level: Optional[str] = None,
|
||||||
|
message_proc_log_level: Optional[str] = None,
|
||||||
|
log_file: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Set up WebSocket logging based on configuration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
enable_debug: Enable WebSocket debugging (overrides config)
|
||||||
|
rxtx_log_level: Log level for RX/TX messages (overrides config)
|
||||||
|
message_proc_log_level: Log level for message processing (overrides config)
|
||||||
|
log_file: Optional log file path for WebSocket messages
|
||||||
|
"""
|
||||||
|
# Get configuration
|
||||||
|
config_manager = get_config_manager()
|
||||||
|
logging_config = config_manager.get_logging_config()
|
||||||
|
|
||||||
|
# Use provided values or fall back to config
|
||||||
|
debug_enabled = enable_debug if enable_debug is not None else logging_config.websocket_debug
|
||||||
|
rxtx_level = rxtx_log_level or logging_config.websocket_rxtx_log_level
|
||||||
|
msg_proc_level = message_proc_log_level or logging_config.websocket_message_proc_log_level
|
||||||
|
|
||||||
|
# Configure WebSocket RX/TX logger
|
||||||
|
ws_rxtx_logger = logging.getLogger("websocket.rxtx")
|
||||||
|
ws_rxtx_logger.setLevel(getattr(logging, rxtx_level.upper(), logging.INFO))
|
||||||
|
|
||||||
|
# Configure WebSocket message processor logger
|
||||||
|
ws_msg_proc_logger = logging.getLogger("websocket.message_processor")
|
||||||
|
ws_msg_proc_logger.setLevel(getattr(logging, msg_proc_level.upper(), logging.DEBUG))
|
||||||
|
|
||||||
|
# Configure main WebSocket logger
|
||||||
|
ws_logger = logging.getLogger("websocket")
|
||||||
|
ws_logger.setLevel(logging.DEBUG if debug_enabled else logging.INFO)
|
||||||
|
|
||||||
|
# Set up console handler for debugging if not already present
|
||||||
|
if debug_enabled and not ws_rxtx_logger.handlers:
|
||||||
|
# Create console handler
|
||||||
|
console_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
console_handler.setLevel(getattr(logging, rxtx_level.upper(), logging.INFO))
|
||||||
|
|
||||||
|
# Create formatter for WebSocket messages
|
||||||
|
formatter = logging.Formatter(
|
||||||
|
"%(asctime)s | WEBSOCKET | %(name)s | %(message)s",
|
||||||
|
datefmt="%Y-%m-%d %H:%M:%S"
|
||||||
|
)
|
||||||
|
console_handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
# Add handler to both WebSocket loggers
|
||||||
|
ws_rxtx_logger.addHandler(console_handler)
|
||||||
|
ws_msg_proc_logger.addHandler(console_handler)
|
||||||
|
|
||||||
|
# Set up file handler if log file is specified
|
||||||
|
if log_file:
|
||||||
|
log_path = Path(log_file)
|
||||||
|
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# Create file handler
|
||||||
|
file_handler = logging.FileHandler(log_path)
|
||||||
|
file_handler.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
# Create detailed formatter for file output
|
||||||
|
file_formatter = logging.Formatter(
|
||||||
|
"%(asctime)s | %(levelname)s | %(name)s | %(message)s"
|
||||||
|
)
|
||||||
|
file_handler.setFormatter(file_formatter)
|
||||||
|
|
||||||
|
# Add to all WebSocket loggers
|
||||||
|
ws_rxtx_logger.addHandler(file_handler)
|
||||||
|
ws_msg_proc_logger.addHandler(file_handler)
|
||||||
|
ws_logger.addHandler(file_handler)
|
||||||
|
|
||||||
|
# Log configuration status
|
||||||
|
main_logger = logging.getLogger("detector_worker.websocket_debug")
|
||||||
|
main_logger.info(f"WebSocket debugging configured: "
|
||||||
|
f"enabled={debug_enabled}, "
|
||||||
|
f"rxtx_level={rxtx_level}, "
|
||||||
|
f"msg_proc_level={msg_proc_level}, "
|
||||||
|
f"log_file={log_file}")
|
||||||
|
|
||||||
|
|
||||||
|
def enable_websocket_debug() -> None:
|
||||||
|
"""Enable WebSocket debugging with default settings."""
|
||||||
|
setup_websocket_logging(
|
||||||
|
enable_debug=True,
|
||||||
|
rxtx_log_level="INFO",
|
||||||
|
message_proc_log_level="DEBUG"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def disable_websocket_debug() -> None:
|
||||||
|
"""Disable WebSocket debugging."""
|
||||||
|
# Set all WebSocket loggers to WARNING level to reduce noise
|
||||||
|
ws_loggers = [
|
||||||
|
"websocket",
|
||||||
|
"websocket.rxtx",
|
||||||
|
"websocket.message_processor"
|
||||||
|
]
|
||||||
|
|
||||||
|
for logger_name in ws_loggers:
|
||||||
|
logger = logging.getLogger(logger_name)
|
||||||
|
logger.setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
# Remove all handlers
|
||||||
|
for handler in logger.handlers[:]:
|
||||||
|
logger.removeHandler(handler)
|
||||||
|
|
||||||
|
|
||||||
|
def get_websocket_debug_status() -> dict:
|
||||||
|
"""
|
||||||
|
Get current WebSocket debugging status.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary with debugging status information
|
||||||
|
"""
|
||||||
|
config_manager = get_config_manager()
|
||||||
|
logging_config = config_manager.get_logging_config()
|
||||||
|
|
||||||
|
# Check current logger levels
|
||||||
|
ws_rxtx_logger = logging.getLogger("websocket.rxtx")
|
||||||
|
ws_msg_proc_logger = logging.getLogger("websocket.message_processor")
|
||||||
|
ws_logger = logging.getLogger("websocket")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"config": {
|
||||||
|
"websocket_debug": logging_config.websocket_debug,
|
||||||
|
"websocket_rxtx_log_level": logging_config.websocket_rxtx_log_level,
|
||||||
|
"websocket_message_proc_log_level": logging_config.websocket_message_proc_log_level
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"websocket_logger_level": logging.getLevelName(ws_logger.level),
|
||||||
|
"rxtx_logger_level": logging.getLevelName(ws_rxtx_logger.level),
|
||||||
|
"msg_proc_logger_level": logging.getLevelName(ws_msg_proc_logger.level),
|
||||||
|
"handler_count": {
|
||||||
|
"websocket": len(ws_logger.handlers),
|
||||||
|
"rxtx": len(ws_rxtx_logger.handlers),
|
||||||
|
"msg_proc": len(ws_msg_proc_logger.handlers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def log_websocket_stats() -> None:
|
||||||
|
"""Log WebSocket communication statistics."""
|
||||||
|
logger = logging.getLogger("websocket.stats")
|
||||||
|
|
||||||
|
# This could be extended to track actual message counts
|
||||||
|
# For now, just log the current status
|
||||||
|
status = get_websocket_debug_status()
|
||||||
|
logger.info(f"WebSocket Debug Status: {status}")
|
Loading…
Add table
Add a link
Reference in a new issue