mirror of
https://github.com/ZGCA-Forge/Elevator.git
synced 2025-12-14 13:04:41 +00:00
326 lines
8.0 KiB
ReStructuredText
326 lines
8.0 KiB
ReStructuredText
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("å<EFBFBD>¯åЍ MyController 算法", prefix="CONTROLLER")
|
||
error("模拟è¿<EFBFBD>行错误", 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("å<EFBFBD>¯åЍ MyController 算法", prefix="CONTROLLER")
|
||
debug("Updated traffic info - max_tick: 1000", prefix="CONTROLLER")
|
||
info("å<EFBFBD>œæ¢ MyController 算法", prefix="CONTROLLER")
|