LightRAG/lightrag/api/gunicorn_config.py
clssck 69358d830d test(lightrag,examples,api): comprehensive ruff formatting and type hints
Format entire codebase with ruff and add type hints across all modules:
- Apply ruff formatting to all Python files (121 files, 17K insertions)
- Add type hints to function signatures throughout lightrag core and API
- Update test suite with improved type annotations and docstrings
- Add pyrightconfig.json for static type checking configuration
- Create prompt_optimized.py and test_extraction_prompt_ab.py test files
- Update ruff.toml and .gitignore for improved linting configuration
- Standardize code style across examples, reproduce scripts, and utilities
2025-12-05 15:17:06 +01:00

160 lines
4.9 KiB
Python

# gunicorn_config.py
import logging
import os
from lightrag.constants import (
DEFAULT_LOG_BACKUP_COUNT,
DEFAULT_LOG_FILENAME,
DEFAULT_LOG_MAX_BYTES,
)
from lightrag.kg.shared_storage import finalize_share_data
from lightrag.utils import get_env_value, setup_logger
# Get log directory path from environment variable
log_dir = os.getenv('LOG_DIR', os.getcwd())
log_file_path = os.path.abspath(os.path.join(log_dir, DEFAULT_LOG_FILENAME))
# Ensure log directory exists
os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
# Get log file max size and backup count from environment variables
log_max_bytes = get_env_value('LOG_MAX_BYTES', DEFAULT_LOG_MAX_BYTES, int)
log_backup_count = get_env_value('LOG_BACKUP_COUNT', DEFAULT_LOG_BACKUP_COUNT, int)
# These variables will be set by run_with_gunicorn.py
workers = None
bind = None
loglevel = None
certfile = None
keyfile = None
timeout = None
keepalive = None
# Enable preload_app option
preload_app = True
# Use Uvicorn worker
worker_class = 'uvicorn.workers.UvicornWorker'
# Other Gunicorn configurations
# Logging configuration
errorlog = os.getenv('ERROR_LOG', log_file_path) # Default write to lightrag.log
accesslog = os.getenv('ACCESS_LOG', log_file_path) # Default write to lightrag.log
logconfig_dict = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'standard',
'stream': 'ext://sys.stdout',
},
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'standard',
'filename': log_file_path,
'maxBytes': log_max_bytes,
'backupCount': log_backup_count,
'encoding': 'utf8',
},
},
'filters': {
'path_filter': {
'()': 'lightrag.utils.LightragPathFilter',
},
},
'loggers': {
'lightrag': {
'handlers': ['console', 'file'],
'level': loglevel.upper() if loglevel else 'INFO',
'propagate': False,
},
'gunicorn': {
'handlers': ['console', 'file'],
'level': loglevel.upper() if loglevel else 'INFO',
'propagate': False,
},
'gunicorn.error': {
'handlers': ['console', 'file'],
'level': loglevel.upper() if loglevel else 'INFO',
'propagate': False,
},
'gunicorn.access': {
'handlers': ['console', 'file'],
'level': loglevel.upper() if loglevel else 'INFO',
'propagate': False,
'filters': ['path_filter'],
},
},
}
def on_starting(server):
"""
Executed when Gunicorn starts, before forking the first worker processes
You can use this function to do more initialization tasks for all processes
"""
print('=' * 80)
print(f'GUNICORN MASTER PROCESS: on_starting jobs for {workers} worker(s)')
print(f'Process ID: {os.getpid()}')
print('=' * 80)
# Memory usage monitoring
try:
import psutil
process = psutil.Process(os.getpid())
memory_info = process.memory_info()
msg = f'Memory usage after initialization: {memory_info.rss / 1024 / 1024:.2f} MB'
print(msg)
except ImportError:
print('psutil not installed, skipping memory usage reporting')
# Log the location of the LightRAG log file
print(f'LightRAG log file: {log_file_path}\n')
print('Gunicorn initialization complete, forking workers...\n')
def on_exit(server):
"""
Executed when Gunicorn is shutting down.
This is a good place to release shared resources.
"""
print('=' * 80)
print('GUNICORN MASTER PROCESS: Shutting down')
print(f'Process ID: {os.getpid()}')
print('Finalizing shared storage...')
finalize_share_data()
print('Gunicorn shutdown complete')
print('=' * 80)
def post_fork(server, worker):
"""
Executed after a worker has been forked.
This is a good place to set up worker-specific configurations.
"""
# Set up main loggers
log_level = loglevel.upper() if loglevel else 'INFO'
setup_logger('uvicorn', log_level, add_filter=False, log_file_path=log_file_path)
setup_logger('uvicorn.access', log_level, add_filter=True, log_file_path=log_file_path)
setup_logger('lightrag', log_level, add_filter=True, log_file_path=log_file_path)
# Set up lightrag submodule loggers
for name in logging.root.manager.loggerDict:
if name.startswith('lightrag.'):
setup_logger(name, log_level, add_filter=True, log_file_path=log_file_path)
# Disable uvicorn.error logger
uvicorn_error_logger = logging.getLogger('uvicorn.error')
uvicorn_error_logger.handlers = []
uvicorn_error_logger.setLevel(logging.CRITICAL)
uvicorn_error_logger.propagate = False