chatbot-deploy / config /logging_config.py
umar-30's picture
Deploy RAG chatbot backend API
53ae001
Raw History Blame Contribute Delete
3.9 kB
"""
Logging Configuration for RAG Agent API
Provides structured JSON logging for all components of the RAG Agent.
Logs include timestamp, level, component name, message, and contextual data.
Usage:
from config.logging_config import setup_logging, get_logger
setup_logging()
logger = get_logger('rag_agent')
logger.info("Message", extra={"query": "test", "latency_ms": 123})
"""
import logging
import json
import sys
from datetime import datetime
from typing import Any, Dict
class JSONFormatter(logging.Formatter):
"""
Custom formatter that outputs logs as JSON.
Format:
{
"timestamp": "2025-12-21T10:30:00Z",
"level": "INFO",
"component": "rag_agent",
"message": "Query processed",
"context": {"query": "...", "latency_ms": 123}
}
"""
def format(self, record: logging.LogRecord) -> str:
"""
Format log record as JSON string.
Args:
record: LogRecord to format
Returns:
JSON-formatted log string
"""
log_data: Dict[str, Any] = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"level": record.levelname,
"component": record.name,
"message": record.getMessage(),
}
# Add any extra context from the log call
if hasattr(record, 'query'):
log_data['query'] = record.query
if hasattr(record, 'latency_ms'):
log_data['latency_ms'] = record.latency_ms
if hasattr(record, 'tokens_used'):
log_data['tokens_used'] = record.tokens_used
if hasattr(record, 'model'):
log_data['model'] = record.model
if hasattr(record, 'status_code'):
log_data['status_code'] = record.status_code
if hasattr(record, 'error_type'):
log_data['error_type'] = record.error_type
# Include exception info if present
if record.exc_info:
log_data['exception'] = self.formatException(record.exc_info)
return json.dumps(log_data)
def setup_logging(level: str = "INFO", json_format: bool = False) -> None:
"""
Configure logging for the application.
Args:
level: Logging level (DEBUG, INFO, WARNING, ERROR)
json_format: If True, use JSON formatter; otherwise use standard format
Example:
>>> setup_logging(level="DEBUG", json_format=True)
"""
log_level = getattr(logging, level.upper(), logging.INFO)
# Create handler for stdout
handler = logging.StreamHandler(sys.stdout)
if json_format:
handler.setFormatter(JSONFormatter())
else:
# Standard format for development
formatter = logging.Formatter(
'[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
handler.setFormatter(formatter)
# Configure root logger
logging.root.setLevel(log_level)
logging.root.handlers = [handler]
# Set levels for noisy libraries
logging.getLogger('httpx').setLevel(logging.WARNING)
logging.getLogger('httpcore').setLevel(logging.WARNING)
logging.getLogger('openai').setLevel(logging.WARNING)
logging.getLogger('urllib3').setLevel(logging.WARNING)
def get_logger(name: str) -> logging.Logger:
"""
Get a logger instance for a component.
Args:
name: Component name (e.g., 'rag_agent', 'retrieval', 'generation')
Returns:
Logger instance
Example:
>>> logger = get_logger('rag_agent')
>>> logger.info("Processing query", extra={"query": "test"})
"""
return logging.getLogger(name)
# Default setup for imports
if __name__ != "__main__":
setup_logging()