78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
import functools
|
|
import logging
|
|
import logging.config
|
|
from typing import Any
|
|
|
|
# Global logger instance used throughout the app
|
|
log = logging.getLogger('root')
|
|
|
|
def get_logger(name: str):
|
|
"""Returns a logger instance by name."""
|
|
return logging.getLogger(name)
|
|
|
|
def setup_logging(settings: Any):
|
|
"""
|
|
Configures logging based on provided settings.
|
|
Moving this here prevents immediate execution on module import.
|
|
"""
|
|
log_file_path = getattr(settings, 'LOG_PATH', {}).get('app', '/logs/aether_api.log')
|
|
|
|
try:
|
|
logging.config.dictConfig({
|
|
'version': 1,
|
|
'disable_existing_loggers': False, # Critical to not kill FastAPI/Uvicorn loggers
|
|
'formatters': {
|
|
'default': {'format': '[%(asctime)s] %(levelname)s @ %(module)s.%(funcName)s()#%(lineno)d: %(message)s'},
|
|
'long': {'format': '[%(asctime)s] %(levelname)s @ %(module)s.%(funcName)s()#%(lineno)d: %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S'},
|
|
'short': {'format': '[%(asctime)s] %(levelname)s @ %(module)s.%(funcName)s()#%(lineno)d: %(message)s', 'datefmt': '%H:%M:%S'},
|
|
},
|
|
'handlers': {
|
|
'console': {
|
|
'class': 'logging.StreamHandler',
|
|
'stream': 'ext://sys.stderr',
|
|
'formatter': 'short',
|
|
},
|
|
'log_file_all': {
|
|
'level': 'NOTSET',
|
|
'class': 'logging.handlers.RotatingFileHandler',
|
|
'formatter': 'long',
|
|
'filename': log_file_path,
|
|
'maxBytes': 10485760, # 10 MB
|
|
'backupCount': 9
|
|
},
|
|
},
|
|
'loggers': {
|
|
'uvicorn': {'handlers': ['console'], 'level': 'INFO'},
|
|
},
|
|
'root': {
|
|
'handlers': ['log_file_all'],
|
|
'level': 'WARNING',
|
|
}
|
|
})
|
|
log.info(f"Logging successfully configured. Path: {log_file_path}")
|
|
except Exception as e:
|
|
print(f"Error configuring logging: {e}")
|
|
logging.basicConfig(level=logging.WARNING)
|
|
|
|
def logger_reset(func):
|
|
"""
|
|
Decorator to log function entry/exit and reset log levels.
|
|
"""
|
|
@functools.wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
# Local safer access to root logger
|
|
root_log = logging.getLogger('root')
|
|
|
|
if func.__name__ not in ['redis_lookup_id_random', 'sql_enable_part', 'sql_hidden_part']:
|
|
root_log.info(f'*** Function: "{func.__name__}()"')
|
|
|
|
root_log.debug(f'*** Function Positional Args: {args}\nFunction Key Args: {kwargs}')
|
|
init_log_level = root_log.level
|
|
|
|
returned_result = func(*args, **kwargs)
|
|
|
|
# Reset level in case it was changed during func execution
|
|
root_log.setLevel(init_log_level)
|
|
return returned_result
|
|
return wrapper
|