diff --git a/config.py b/config.py index cb86628..3146e06 100644 --- a/config.py +++ b/config.py @@ -23,23 +23,23 @@ class LangfuseConfig(BaseSettings): def __init__(self, **data): try: - logger.info("Initializing LangfuseConfig with data: %s", data) + logger.info("Initializing LangfuseConfig with data: {}", data) logger.info("Environment variables:") - logger.info("LANGFUSE_PUBLIC_KEY: %s", os.getenv('LANGFUSE_PUBLIC_KEY')) - logger.info("LANGFUSE_SECRET_KEY: %s", os.getenv('LANGFUSE_SECRET_KEY')) - logger.info("LANGFUSE_HOST: %s", os.getenv('LANGFUSE_HOST')) + logger.info("LANGFUSE_PUBLIC_KEY: {}", os.getenv('LANGFUSE_PUBLIC_KEY')) + logger.info("LANGFUSE_SECRET_KEY: {}", os.getenv('LANGFUSE_SECRET_KEY')) + logger.info("LANGFUSE_HOST: {}", os.getenv('LANGFUSE_HOST')) super().__init__(**data) logger.info("LangfuseConfig initialized successfully") - logger.info("Public Key: %s", self.public_key) - logger.info("Secret Key: %s", self.secret_key) - logger.info("Host: %s", self.host) + logger.info("Public Key: {}", self.public_key) + logger.info("Secret Key: {}", self.secret_key) + logger.info("Host: {}", self.host) except Exception as e: - logger.error("Failed to initialize LangfuseConfig: %s", e) + logger.error("Failed to initialize LangfuseConfig: {}", e) logger.error("Current environment variables:") - logger.error("LANGFUSE_PUBLIC_KEY: %s", os.getenv('LANGFUSE_PUBLIC_KEY')) - logger.error("LANGFUSE_SECRET_KEY: %s", os.getenv('LANGFUSE_SECRET_KEY')) - logger.error("LANGFUSE_HOST: %s", os.getenv('LANGFUSE_HOST')) + logger.error("LANGFUSE_PUBLIC_KEY: {}", os.getenv('LANGFUSE_PUBLIC_KEY')) + logger.error("LANGFUSE_SECRET_KEY: {}", os.getenv('LANGFUSE_SECRET_KEY')) + logger.error("LANGFUSE_HOST: {}", os.getenv('LANGFUSE_HOST')) raise model_config = ConfigDict( @@ -89,15 +89,15 @@ class Settings: try: logger.info("Initializing LogConfig") self.log = LogConfig() - logger.info("LogConfig initialized: %s", self.log.model_dump()) + logger.info("LogConfig initialized: {}", self.log.model_dump()) logger.info("Initializing LLMConfig") self.llm = LLMConfig() - logger.info("LLMConfig initialized: %s", self.llm.model_dump()) + logger.info("LLMConfig initialized: {}", self.llm.model_dump()) logger.info("Initializing LangfuseConfig") self.langfuse = LangfuseConfig() - logger.info("LangfuseConfig initialized: %s", self.langfuse.model_dump()) + logger.info("LangfuseConfig initialized: {}", self.langfuse.model_dump()) logger.info("Validating configuration") self._validate() @@ -107,15 +107,15 @@ class Settings: self._init_langfuse() logger.info("Configuration initialized successfully") except Exception as e: - logger.error(f"Configuration initialization failed: {e}") + logger.error("Configuration initialization failed: {}", e) logger.error("Current configuration state:") - logger.error("LogConfig: %s", self.log.model_dump() if hasattr(self, 'log') else 'Not initialized') - logger.error("LLMConfig: %s", self.llm.model_dump() if hasattr(self, 'llm') else 'Not initialized') - logger.error("LangfuseConfig: %s", self.langfuse.model_dump() if hasattr(self, 'langfuse') else 'Not initialized') + logger.error("LogConfig: {}", self.log.model_dump() if hasattr(self, 'log') else 'Not initialized') + logger.error("LLMConfig: {}", self.llm.model_dump() if hasattr(self, 'llm') else 'Not initialized') + logger.error("LangfuseConfig: {}", self.langfuse.model_dump() if hasattr(self, 'langfuse') else 'Not initialized') raise def _validate(self): - logger.info(f"LLM mode set to: '{self.llm.mode}'") + logger.info("LLM mode set to: '{}'", self.llm.mode) if self.llm.mode == 'openai': if not self.llm.openai_api_key: @@ -140,6 +140,11 @@ class Settings: if not all([self.langfuse.public_key, self.langfuse.secret_key, self.langfuse.host]): raise ValueError("Missing required Langfuse credentials") + logger.debug("Initializing Langfuse client with:") + logger.debug("Public Key: {}", self.langfuse.public_key) + logger.debug("Secret Key: {}", self.langfuse.secret_key) + logger.debug("Host: {}", self.langfuse.host) + # Initialize Langfuse client self.langfuse_client = Langfuse( public_key=self.langfuse.public_key, @@ -147,6 +152,14 @@ class Settings: host=self.langfuse.host ) + # Test Langfuse connection + try: + self.langfuse_client.auth_check() + logger.debug("Langfuse connection test successful") + except Exception as e: + logger.error("Langfuse connection test failed: {}", e) + raise + # Initialize CallbackHandler self.langfuse_handler = CallbackHandler( public_key=self.langfuse.public_key, @@ -156,10 +169,10 @@ class Settings: logger.info("Langfuse client and handler initialized successfully") except ValueError as e: - logger.warning(f"Langfuse configuration error: {e}. Disabling Langfuse.") + logger.warning("Langfuse configuration error: {}. Disabling Langfuse.", e) self.langfuse.enabled = False except Exception as e: - logger.error(f"Failed to initialize Langfuse: {e}") + logger.error("Failed to initialize Langfuse: {}", e) self.langfuse.enabled = False def _start_watcher(self): @@ -173,7 +186,7 @@ class Settings: self._validate() logger.info("Configuration reloaded successfully") except Exception as e: - logger.error(f"Error reloading configuration: {e}") + logger.error("Error reloading configuration: {}", e) Thread(target=watch_config, daemon=True).start() @@ -181,6 +194,6 @@ class Settings: try: settings = Settings() except ValueError as e: - logger.error(f"FATAL: {e}") + logger.error("FATAL: {}", e) logger.error("Application shutting down due to configuration error.") sys.exit(1) \ No newline at end of file diff --git a/jira-webhook-llm.py b/jira-webhook-llm.py index 8a0c421..ef06d7a 100644 --- a/jira-webhook-llm.py +++ b/jira-webhook-llm.py @@ -1,3 +1,6 @@ +from dotenv import load_dotenv +load_dotenv() + from fastapi import FastAPI, Request, HTTPException from pydantic import BaseModel from fastapi.responses import JSONResponse @@ -14,6 +17,9 @@ from webhooks.handlers import JiraWebhookHandler from llm.models import JiraWebhookPayload from logging_config import configure_logging +# Initialize logging first +configure_logging(log_level="DEBUG") + try: app = FastAPI() logger.info("FastAPI application initialized") @@ -21,9 +27,6 @@ except Exception as e: logger.error(f"Error initializing FastAPI: {str(e)}") raise -# Initialize logging -configure_logging(log_level=settings.log.level) - def retry(max_retries: int = 3, delay: float = 1.0): """Decorator for retrying failed operations""" def decorator(func): diff --git a/logging_config.py b/logging_config.py index 2085822..17a929e 100644 --- a/logging_config.py +++ b/logging_config.py @@ -1,13 +1,13 @@ import sys -from loguru import logger - -logger.configure( - extra={"request_id": "N/A"} -) import os from pathlib import Path from datetime import datetime from typing import Optional +from loguru import logger + +# Initialize logger with default configuration +logger.remove() +logger.add(sys.stderr, level="WARNING", format="{message}") def configure_logging(log_level: str = "INFO", log_dir: Optional[str] = None): """Configure structured logging for the application""" @@ -22,7 +22,7 @@ def configure_logging(log_level: str = "INFO", log_dir: Optional[str] = None): # Log file path with timestamp log_file = Path(log_dir) / f"jira-webhook-llm_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log" - # Remove default logger + # Remove any existing loggers logger.remove() # Add console logger @@ -30,7 +30,9 @@ def configure_logging(log_level: str = "INFO", log_dir: Optional[str] = None): sys.stdout, level=log_level, format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {extra[request_id]} | {message}", - colorize=True + colorize=True, + backtrace=True, + diagnose=True ) # Add file logger @@ -40,7 +42,12 @@ def configure_logging(log_level: str = "INFO", log_dir: Optional[str] = None): format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {extra[request_id]} | {message}", rotation="100 MB", retention="30 days", - compression="zip" + compression="zip", + backtrace=True, + diagnose=True ) + # Configure default extras + logger.configure(extra={"request_id": "N/A"}) + logger.info("Logging configured successfully") \ No newline at end of file