ishaq101's picture
[NOTICKET] Demo agentic agent
bef5e76
"""Structured logging middleware with structlog."""
import structlog
from functools import wraps
from typing import Callable, Any
import time
def configure_logging():
"""Configure structured logging."""
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.processors.UnicodeDecoder(),
structlog.processors.JSONRenderer()
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
cache_logger_on_first_use=True,
)
def get_logger(name: str) -> structlog.stdlib.BoundLogger:
"""Get a configured logger."""
return structlog.get_logger(name)
def log_execution(logger: structlog.stdlib.BoundLogger):
"""Decorator to log function execution."""
def decorator(func: Callable) -> Callable:
@wraps(func)
async def async_wrapper(*args, **kwargs) -> Any:
start_time = time.time()
logger.info(f"Starting {func.__name__}")
try:
result = await func(*args, **kwargs)
duration = time.time() - start_time
logger.info(f"Completed {func.__name__}", duration=duration)
return result
except Exception as e:
duration = time.time() - start_time
logger.error(f"Error in {func.__name__}", error=str(e), duration=duration)
raise
@wraps(func)
def sync_wrapper(*args, **kwargs) -> Any:
start_time = time.time()
logger.info(f"Starting {func.__name__}")
try:
result = func(*args, **kwargs)
duration = time.time() - start_time
logger.info(f"Completed {func.__name__}", duration=duration)
return result
except Exception as e:
duration = time.time() - start_time
logger.error(f"Error in {func.__name__}", error=str(e), duration=duration)
raise
return async_wrapper if hasattr(func, '__call__') and hasattr(func, '__code__') and func.__code__.co_flags & 0x80 else sync_wrapper
return decorator