mirror of
https://github.com/aljazceru/enclava.git
synced 2025-12-17 23:44:24 +01:00
clean commit
This commit is contained in:
153
backend/app/core/logging.py
Normal file
153
backend/app/core/logging.py
Normal file
@@ -0,0 +1,153 @@
|
||||
"""
|
||||
Logging configuration
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from typing import Any, Dict
|
||||
import structlog
|
||||
from structlog.stdlib import LoggerFactory
|
||||
|
||||
from app.core.config import settings
|
||||
|
||||
|
||||
def setup_logging() -> None:
|
||||
"""Setup structured logging"""
|
||||
|
||||
# Configure structlog
|
||||
structlog.configure(
|
||||
processors=[
|
||||
structlog.stdlib.filter_by_level,
|
||||
structlog.stdlib.add_logger_name,
|
||||
structlog.stdlib.add_log_level,
|
||||
structlog.stdlib.PositionalArgumentsFormatter(),
|
||||
structlog.processors.StackInfoRenderer(),
|
||||
structlog.processors.format_exc_info,
|
||||
structlog.processors.UnicodeDecoder(),
|
||||
structlog.processors.JSONRenderer() if settings.LOG_FORMAT == "json" else structlog.dev.ConsoleRenderer(),
|
||||
],
|
||||
context_class=dict,
|
||||
logger_factory=LoggerFactory(),
|
||||
wrapper_class=structlog.stdlib.BoundLogger,
|
||||
cache_logger_on_first_use=True,
|
||||
)
|
||||
|
||||
# Configure standard logging
|
||||
logging.basicConfig(
|
||||
format="%(message)s",
|
||||
stream=sys.stdout,
|
||||
level=getattr(logging, settings.LOG_LEVEL.upper()),
|
||||
)
|
||||
|
||||
# Set specific loggers
|
||||
logging.getLogger("uvicorn").setLevel(logging.WARNING)
|
||||
logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
|
||||
logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)
|
||||
|
||||
|
||||
def get_logger(name: str) -> structlog.stdlib.BoundLogger:
|
||||
"""Get a structured logger"""
|
||||
return structlog.get_logger(name)
|
||||
|
||||
|
||||
class RequestContextFilter(logging.Filter):
|
||||
"""Add request context to log records"""
|
||||
|
||||
def filter(self, record: logging.LogRecord) -> bool:
|
||||
# Add request context if available
|
||||
from contextvars import ContextVar
|
||||
|
||||
request_id: ContextVar[str] = ContextVar("request_id", default="")
|
||||
user_id: ContextVar[str] = ContextVar("user_id", default="")
|
||||
|
||||
record.request_id = request_id.get()
|
||||
record.user_id = user_id.get()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def log_request(
|
||||
method: str,
|
||||
path: str,
|
||||
status_code: int,
|
||||
processing_time: float,
|
||||
user_id: str = None,
|
||||
request_id: str = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Log HTTP request"""
|
||||
logger = get_logger("api.request")
|
||||
|
||||
log_data = {
|
||||
"method": method,
|
||||
"path": path,
|
||||
"status_code": status_code,
|
||||
"processing_time": processing_time,
|
||||
"user_id": user_id,
|
||||
"request_id": request_id,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
if status_code >= 500:
|
||||
logger.error("Request failed", **log_data)
|
||||
elif status_code >= 400:
|
||||
logger.warning("Request error", **log_data)
|
||||
else:
|
||||
logger.info("Request completed", **log_data)
|
||||
|
||||
|
||||
def log_security_event(
|
||||
event_type: str,
|
||||
user_id: str = None,
|
||||
ip_address: str = None,
|
||||
details: Dict[str, Any] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Log security event"""
|
||||
logger = get_logger("security")
|
||||
|
||||
log_data = {
|
||||
"event_type": event_type,
|
||||
"user_id": user_id,
|
||||
"ip_address": ip_address,
|
||||
"details": details or {},
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
logger.warning("Security event", **log_data)
|
||||
|
||||
|
||||
def log_module_event(
|
||||
module_id: str,
|
||||
event_type: str,
|
||||
details: Dict[str, Any] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Log module event"""
|
||||
logger = get_logger("module")
|
||||
|
||||
log_data = {
|
||||
"module_id": module_id,
|
||||
"event_type": event_type,
|
||||
"details": details or {},
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
logger.info("Module event", **log_data)
|
||||
|
||||
|
||||
def log_api_request(
|
||||
endpoint: str,
|
||||
params: Dict[str, Any] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Log API request for modules endpoints"""
|
||||
logger = get_logger("api.module")
|
||||
|
||||
log_data = {
|
||||
"endpoint": endpoint,
|
||||
"params": params or {},
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
logger.info("API request", **log_data)
|
||||
Reference in New Issue
Block a user