Full support for gui & algorithm

This commit is contained in:
Xuwznln
2025-10-19 22:35:02 +08:00
parent 83459923e8
commit 996a23832e
12 changed files with 1158 additions and 119 deletions

View File

@@ -83,6 +83,7 @@ Contents
client
communication
events
logging
.. toctree::
:maxdepth: 1

325
docs/logging.rst Normal file
View File

@@ -0,0 +1,325 @@
Logging System
==============
Overview
--------
Elevator Saga uses a unified logging system with colored output and multiple log levels. The logging system provides consistent, filterable output across all components.
Log Levels
----------
The logger supports four log levels with distinct colors:
* **DEBUG** - Gray/Bright Black - Detailed debugging information
* **INFO** - Cyan - General informational messages
* **WARNING** - Yellow - Warning messages
* **ERROR** - Red - Error messages
Configuration
-------------
Environment Variable
~~~~~~~~~~~~~~~~~~~~
The default log level is controlled by the ``ELEVATOR_LOG_LEVEL`` environment variable:
.. code-block:: bash
# Set log level to DEBUG (default)
export ELEVATOR_LOG_LEVEL=DEBUG
# Set log level to INFO (less verbose)
export ELEVATOR_LOG_LEVEL=INFO
# Set log level to WARNING (only warnings and errors)
export ELEVATOR_LOG_LEVEL=WARNING
# Set log level to ERROR (only errors)
export ELEVATOR_LOG_LEVEL=ERROR
If not set, the default is **DEBUG** mode.
Programmatic Control
~~~~~~~~~~~~~~~~~~~~
You can also control the log level programmatically:
.. code-block:: python
from elevator_saga.utils.logger import LogLevel, set_log_level
# Set to INFO level
set_log_level(LogLevel.INFO)
# Set to DEBUG level
set_log_level(LogLevel.DEBUG)
Basic Usage
-----------
Simple Logging
~~~~~~~~~~~~~~
.. code-block:: python
from elevator_saga.utils.logger import debug, info, warning, error
# Simple messages
info("Server started successfully")
warning("Connection timeout")
error("Failed to load configuration")
debug("Processing tick 42")
With Prefix
~~~~~~~~~~~
Add a prefix to identify the source of the log message:
.. code-block:: python
# Server logs
info("Client registered", prefix="SERVER")
debug("Algorithm client processed tick 42", prefix="SERVER")
# Client logs
info("API Client initialized", prefix="CLIENT")
warning("Command ignored", prefix="CLIENT")
# Controller logs
info("启动 MyController 算法", prefix="CONTROLLER")
error("模拟运行错误", prefix="CONTROLLER")
Advanced Usage
--------------
Custom Logger
~~~~~~~~~~~~~
Create a custom logger instance with specific settings:
.. code-block:: python
from elevator_saga.utils.logger import get_logger, LogLevel
# Get a custom logger
logger = get_logger("MyComponent", min_level=LogLevel.WARNING)
logger.info("This will not appear (level too low)")
logger.warning("This will appear")
logger.error("This will appear")
Color Output
~~~~~~~~~~~~
The logger automatically detects if output is to a TTY (terminal) and enables colors. When redirecting to files or pipes, colors are automatically disabled for clean output.
Log Format
----------
All log messages follow a consistent format::
LEVEL [PREFIX] message
Examples:
.. code-block:: text
DEBUG [SERVER] Algorithm client registered: abc-123
INFO [SERVER] Loading traffic from test_case_01.json
WARNING [SERVER] GUI client: timeout waiting for tick 42
ERROR [CLIENT] Reset failed: Connection refused
INFO [CONTROLLER] 启动 MyController 算法
Component Prefixes
------------------
Standard prefixes used throughout the system:
* **SERVER** - Simulator server logs
* **CLIENT** - API client logs
* **CONTROLLER** - Controller/algorithm logs
You can use any prefix that makes sense for your component.
API Reference
-------------
Functions
~~~~~~~~~
.. py:function:: debug(message: str, prefix: Optional[str] = None) -> None
Log a DEBUG level message.
:param message: The message to log
:param prefix: Optional prefix to identify the source
.. py:function:: info(message: str, prefix: Optional[str] = None) -> None
Log an INFO level message.
:param message: The message to log
:param prefix: Optional prefix to identify the source
.. py:function:: warning(message: str, prefix: Optional[str] = None) -> None
Log a WARNING level message.
:param message: The message to log
:param prefix: Optional prefix to identify the source
.. py:function:: error(message: str, prefix: Optional[str] = None) -> None
Log an ERROR level message.
:param message: The message to log
:param prefix: Optional prefix to identify the source
.. py:function:: set_log_level(level: LogLevel) -> None
Set the global log level.
:param level: The minimum log level to display
.. py:function:: get_logger(name: str = "ElevatorSaga", min_level: Optional[LogLevel] = None) -> Logger
Get or create the global logger instance.
:param name: Name of the logger
:param min_level: Minimum log level (defaults to ELEVATOR_LOG_LEVEL or DEBUG)
:return: Logger instance
Classes
~~~~~~~
.. py:class:: LogLevel
Enumeration of available log levels.
.. py:attribute:: DEBUG
:value: 0
Debug level - most verbose
.. py:attribute:: INFO
:value: 1
Info level - general information
.. py:attribute:: WARNING
:value: 2
Warning level - warnings only
.. py:attribute:: ERROR
:value: 3
Error level - errors only
.. py:method:: from_string(level_str: str) -> LogLevel
:classmethod:
Convert a string to a LogLevel.
:param level_str: String representation (case-insensitive)
:return: Corresponding LogLevel (defaults to DEBUG if invalid)
.. py:class:: Logger
The main logger class.
.. py:method:: __init__(name: str = "ElevatorSaga", min_level: LogLevel = LogLevel.INFO, use_color: bool = True)
Initialize a logger instance.
:param name: Logger name
:param min_level: Minimum level to log
:param use_color: Whether to use colored output
.. py:method:: debug(message: str, prefix: Optional[str] = None) -> None
Log a DEBUG message.
.. py:method:: info(message: str, prefix: Optional[str] = None) -> None
Log an INFO message.
.. py:method:: warning(message: str, prefix: Optional[str] = None) -> None
Log a WARNING message.
.. py:method:: error(message: str, prefix: Optional[str] = None) -> None
Log an ERROR message.
.. py:method:: set_level(level: LogLevel) -> None
Change the minimum log level.
Best Practices
--------------
1. **Use appropriate levels**:
* DEBUG for detailed state changes and internal operations
* INFO for significant events (startup, completion, etc.)
* WARNING for unexpected but recoverable situations
* ERROR for failures and exceptions
2. **Use prefixes consistently**:
* Always use the same prefix for the same component
* Use uppercase for standard prefixes (SERVER, CLIENT, CONTROLLER)
3. **Keep messages concise**:
* One log message per event
* Include relevant context (IDs, values, etc.)
* Avoid multi-line messages
4. **Set appropriate default level**:
* Use DEBUG for development
* Use INFO for production
* Use WARNING for minimal logging
5. **Avoid logging in tight loops**:
* Excessive logging can impact performance
* Consider conditional logging or sampling
Examples
--------
Server Startup
~~~~~~~~~~~~~~
.. code-block:: python
from elevator_saga.utils.logger import info, debug
info("Elevator simulation server (Async) running on http://127.0.0.1:8000", prefix="SERVER")
info("Using Quart (async Flask) for better concurrency", prefix="SERVER")
debug("Found 5 traffic files: ['test01.json', 'test02.json', ...]", prefix="SERVER")
Client Operations
~~~~~~~~~~~~~~~~~
.. code-block:: python
from elevator_saga.utils.logger import info, warning, error
info("Client registered successfully with ID: xyz-789", prefix="CLIENT")
warning("Client type 'gui' cannot send control commands", prefix="CLIENT")
error("Reset failed: Connection refused", prefix="CLIENT")
Controller Logic
~~~~~~~~~~~~~~~~
.. code-block:: python
from elevator_saga.utils.logger import info, debug
info("启动 MyController 算法", prefix="CONTROLLER")
debug("Updated traffic info - max_tick: 1000", prefix="CONTROLLER")
info("停止 MyController 算法", prefix="CONTROLLER")