| """
|
| Structured Logger for Voice Agent
|
| Provides JSON-formatted logging for better observability
|
| """
|
| import logging
|
| import json
|
| from datetime import datetime
|
| import sys
|
|
|
| class JsonFormatter(logging.Formatter):
|
| """Format logs as JSON"""
|
| def format(self, record):
|
| log_data = {
|
| "timestamp": datetime.now().isoformat(),
|
| "level": record.levelname,
|
| "message": record.getMessage(),
|
| "module": record.module,
|
| "function": record.funcName,
|
| "line": record.lineno
|
| }
|
|
|
|
|
| if hasattr(record, 'user_id'):
|
| log_data['user_id'] = record.user_id
|
| if hasattr(record, 'session_id'):
|
| log_data['session_id'] = record.session_id
|
| if hasattr(record, 'duration'):
|
| log_data['duration'] = record.duration
|
| if hasattr(record, 'error'):
|
| log_data['error'] = record.error
|
|
|
| return json.dumps(log_data)
|
|
|
| class StructuredLogger:
|
| """Structured logger with JSON output"""
|
| def __init__(self, name="voice-agent"):
|
| self.logger = logging.getLogger(name)
|
| self.logger.setLevel(logging.INFO)
|
|
|
|
|
| self.logger.handlers = []
|
|
|
|
|
| handler = logging.StreamHandler(sys.stdout)
|
| handler.setFormatter(JsonFormatter())
|
| self.logger.addHandler(handler)
|
|
|
| def info(self, message, **kwargs):
|
| """Log info message with optional context"""
|
| extra = {k: v for k, v in kwargs.items()}
|
| self.logger.info(message, extra=extra)
|
|
|
| def error(self, message, **kwargs):
|
| """Log error message with optional context"""
|
| extra = {k: v for k, v in kwargs.items()}
|
| self.logger.error(message, extra=extra)
|
|
|
| def warning(self, message, **kwargs):
|
| """Log warning message with optional context"""
|
| extra = {k: v for k, v in kwargs.items()}
|
| self.logger.warning(message, extra=extra)
|
|
|
| def debug(self, message, **kwargs):
|
| """Log debug message with optional context"""
|
| extra = {k: v for k, v in kwargs.items()}
|
| self.logger.debug(message, extra=extra)
|
|
|
|
|
| logger = StructuredLogger()
|
|
|