Spaces:
Sleeping
Sleeping
| """Logging configuration for TSU-WAVE""" | |
| import logging | |
| import sys | |
| import json | |
| from pathlib import Path | |
| from datetime import datetime | |
| from typing import Optional, Dict, Any | |
| import traceback | |
| class JsonFormatter(logging.Formatter): | |
| """JSON formatter for structured logging""" | |
| def format(self, record): | |
| log_record = { | |
| 'timestamp': datetime.utcnow().isoformat(), | |
| 'level': record.levelname, | |
| 'name': record.name, | |
| 'message': record.getMessage(), | |
| 'module': record.module, | |
| 'line': record.lineno | |
| } | |
| if hasattr(record, 'extra'): | |
| log_record.update(record.extra) | |
| if record.exc_info: | |
| log_record['exception'] = { | |
| 'type': record.exc_info[0].__name__, | |
| 'message': str(record.exc_info[1]), | |
| 'traceback': traceback.format_exception(*record.exc_info) | |
| } | |
| return json.dumps(log_record) | |
| def setup_logging( | |
| name: str = 'tsu-wave', | |
| log_file: Optional[str] = None, | |
| log_level: str = 'INFO', | |
| json_format: bool = False | |
| ) -> logging.Logger: | |
| """Setup logging configuration""" | |
| logger = logging.getLogger(name) | |
| logger.setLevel(getattr(logging, log_level.upper())) | |
| # Remove existing handlers | |
| logger.handlers.clear() | |
| # Console handler | |
| console_handler = logging.StreamHandler(sys.stdout) | |
| if json_format: | |
| console_handler.setFormatter(JsonFormatter()) | |
| else: | |
| console_handler.setFormatter( | |
| logging.Formatter( | |
| '%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| ) | |
| ) | |
| logger.addHandler(console_handler) | |
| # File handler (if specified) | |
| if log_file: | |
| log_path = Path(log_file) | |
| log_path.parent.mkdir(parents=True, exist_ok=True) | |
| file_handler = logging.FileHandler(log_file) | |
| if json_format: | |
| file_handler.setFormatter(JsonFormatter()) | |
| else: | |
| file_handler.setFormatter( | |
| logging.Formatter( | |
| '%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| ) | |
| ) | |
| logger.addHandler(file_handler) | |
| return logger | |
| def get_logger(name: str) -> logging.Logger: | |
| """Get logger instance""" | |
| return logging.getLogger(name) | |
| class LoggerAdapter(logging.LoggerAdapter): | |
| """Logger adapter with extra context""" | |
| def __init__(self, logger, extra=None): | |
| super().__init__(logger, extra or {}) | |
| def process(self, msg, kwargs): | |
| kwargs['extra'] = self.extra | |
| return msg, kwargs | |
| def with_context(self, **context): | |
| """Create new adapter with additional context""" | |
| new_extra = self.extra.copy() | |
| new_extra.update(context) | |
| return LoggerAdapter(self.logger, new_extra) | |
| def log_function_call(logger=None): | |
| """Decorator to log function calls""" | |
| def decorator(func): | |
| def wrapper(*args, **kwargs): | |
| log = logger or logging.getLogger(func.__module__) | |
| # Log function call | |
| log.debug(f"Calling {func.__name__}") | |
| try: | |
| result = func(*args, **kwargs) | |
| log.debug(f"{func.__name__} completed successfully") | |
| return result | |
| except Exception as e: | |
| log.error(f"{func.__name__} failed: {e}", exc_info=True) | |
| raise | |
| return wrapper | |
| return decorator | |
| def log_execution_time(logger=None): | |
| """Decorator to log function execution time""" | |
| def decorator(func): | |
| def wrapper(*args, **kwargs): | |
| log = logger or logging.getLogger(func.__module__) | |
| import time | |
| start = time.time() | |
| try: | |
| result = func(*args, **kwargs) | |
| elapsed = time.time() - start | |
| log.debug(f"{func.__name__} took {elapsed:.3f}s") | |
| return result | |
| except Exception as e: | |
| elapsed = time.time() - start | |
| log.error(f"{func.__name__} failed after {elapsed:.3f}s: {e}") | |
| raise | |
| return wrapper | |
| return decorator | |
| class PerformanceLogger: | |
| """Context manager for performance logging""" | |
| def __init__(self, name: str, logger=None): | |
| self.name = name | |
| self.logger = logger or logging.getLogger(__name__) | |
| self.start_time = None | |
| def __enter__(self): | |
| import time | |
| self.start_time = time.time() | |
| return self | |
| def __exit__(self, exc_type, exc_val, exc_tb): | |
| import time | |
| elapsed = time.time() - self.start_time | |
| if exc_type: | |
| self.logger.error(f"{self.name} failed after {elapsed:.3f}s: {exc_val}") | |
| else: | |
| self.logger.debug(f"{self.name} completed in {elapsed:.3f}s") | |
| def setup_module_logger(module_name: str, log_level: str = 'INFO'): | |
| """Setup logger for a module""" | |
| logger = logging.getLogger(module_name) | |
| logger.setLevel(getattr(logging, log_level.upper())) | |
| # Only add handler if none exists | |
| if not logger.handlers: | |
| handler = logging.StreamHandler(sys.stdout) | |
| handler.setFormatter( | |
| logging.Formatter( | |
| '%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| ) | |
| ) | |
| logger.addHandler(handler) | |
| return logger | |