refactor: consolidate logging to shared aitbc-core package and upgrade database dependencies
- Upgrade SQLAlchemy to 2.0.47 with asyncio extras in blockchain-node and coordinator-api - Add asyncpg >=0.29.0 for PostgreSQL async support - Remove uvloop as optional dependency, make it required >=0.22.0 - Delete duplicate logger.py from blockchain-node (117 lines) - Refactor coordinator-api logging to use shared aitbc.logging from aitbc-core package - Add aitbc-core package dependency to coordinator
This commit is contained in:
@@ -1,101 +1,3 @@
|
||||
"""
|
||||
Logging configuration for the AITBC Coordinator API
|
||||
from aitbc.logging import get_logger, setup_logger
|
||||
|
||||
Provides structured JSON logging for better observability and log parsing.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, Optional
|
||||
from pythonjsonlogger import jsonlogger
|
||||
|
||||
|
||||
class StructuredLogFormatter(jsonlogger.JsonFormatter):
|
||||
"""Custom JSON formatter for structured logging."""
|
||||
|
||||
def add_fields(self, log_record: Dict[str, Any], record: logging.LogRecord, message_dict: Dict[str, Any]) -> None:
|
||||
super().add_fields(log_record, record, message_dict)
|
||||
log_record['timestamp'] = datetime.utcnow().isoformat() + 'Z'
|
||||
log_record['service'] = 'aitbc-coordinator-api'
|
||||
log_record['level'] = record.levelname
|
||||
log_record['logger'] = record.name
|
||||
log_record['module'] = record.module
|
||||
log_record['function'] = record.funcName
|
||||
log_record['line'] = record.lineno
|
||||
|
||||
if record.exc_info:
|
||||
log_record['exception'] = self.format_exception(record.exc_info)
|
||||
|
||||
@staticmethod
|
||||
def format_exception(exc_info) -> Optional[Dict[str, Any]]:
|
||||
"""Format exception info for JSON output."""
|
||||
if exc_info is None:
|
||||
return None
|
||||
import traceback
|
||||
return {
|
||||
'type': exc_info[0].__name__ if exc_info[0] else None,
|
||||
'message': str(exc_info[1]) if exc_info[1] else None,
|
||||
'traceback': traceback.format_exception(*exc_info) if exc_info[0] else None
|
||||
}
|
||||
|
||||
|
||||
class AuditLogger:
|
||||
"""Audit logger for tracking sensitive operations."""
|
||||
|
||||
def __init__(self, logger: logging.Logger):
|
||||
self.logger = logger
|
||||
|
||||
def log(self, action: str, user_id: Optional[str] = None, resource_id: Optional[str] = None,
|
||||
details: Optional[Dict[str, Any]] = None, success: bool = True) -> None:
|
||||
"""Log an audit event."""
|
||||
self.logger.info(
|
||||
"audit_event",
|
||||
extra={
|
||||
'audit': {
|
||||
'action': action,
|
||||
'user_id': user_id,
|
||||
'resource_id': resource_id,
|
||||
'details': details or {},
|
||||
'success': success
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def setup_logging(level: str = "INFO", json_format: bool = True) -> None:
|
||||
"""Setup structured logging for the application."""
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.handlers.clear()
|
||||
|
||||
if json_format:
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(StructuredLogFormatter(
|
||||
'%(timestamp)s %(level)s %(message)s'
|
||||
))
|
||||
else:
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(
|
||||
logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
)
|
||||
|
||||
root_logger.addHandler(handler)
|
||||
root_logger.setLevel(getattr(logging, level.upper()))
|
||||
|
||||
logging.getLogger('uvicorn').setLevel(level)
|
||||
logging.getLogger('uvicorn.access').setLevel(level)
|
||||
|
||||
|
||||
def get_logger(name: str) -> logging.Logger:
|
||||
"""Get a logger instance."""
|
||||
return logging.getLogger(name)
|
||||
|
||||
|
||||
def get_audit_logger(name: str = "audit") -> AuditLogger:
|
||||
"""Get an audit logger instance."""
|
||||
return AuditLogger(get_logger(name))
|
||||
|
||||
|
||||
# Initialize default logging on import
|
||||
setup_logging()
|
||||
__all__ = ["get_logger", "setup_logger"]
|
||||
|
||||
Reference in New Issue
Block a user