json logging

This commit is contained in:
2025-12-24 00:26:20 +01:00
parent e2c18b07a5
commit 6654496379
4 changed files with 32 additions and 16 deletions

View File

@@ -13,4 +13,5 @@ dependencies = [
"python-dotenv",
"httpx",
"logfire>=4.16.0",
"python-json-logger>=4.0.0",
]

View File

@@ -7,10 +7,20 @@ import logging
import httpx
import logfire
# Set up logging BEFORE logfire (otherwise basicConfig is ignored)
from pythonjsonlogger import jsonlogger
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
handler = logging.StreamHandler()
handler.setFormatter(jsonlogger.JsonFormatter("%(asctime)s %(name)s %(levelname)s %(message)s"))
logging.basicConfig(
level=getattr(logging, log_level, logging.INFO),
handlers=[handler],
)
logger = logging.getLogger(__name__)
# Configure Logfire for observability
# Uses LOGFIRE_TOKEN in production, or local auth from `logfire auth` in dev
logfire.configure(
project_name='cavepediav2',
environment=os.getenv('ENVIRONMENT', 'development'),
)
logfire.instrument_pydantic_ai()
@@ -19,14 +29,6 @@ logfire.instrument_httpx()
from pydantic_ai import Agent, ModelMessage, RunContext
from pydantic_ai.settings import ModelSettings
# Set up logging based on environment
log_level = logging.DEBUG if os.getenv("DEBUG") else logging.INFO
logging.basicConfig(
level=log_level,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
CAVE_MCP_URL = os.getenv("CAVE_MCP_URL", "https://mcp.caving.dev/mcp")
logger.info(f"Initializing Cavepedia agent with CAVE_MCP_URL={CAVE_MCP_URL}")

View File

@@ -14,13 +14,27 @@ from pydantic_ai.settings import ModelSettings
load_dotenv()
# Set up logging based on environment
log_level = logging.DEBUG if os.getenv("DEBUG") else logging.INFO
from pythonjsonlogger import jsonlogger
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
json_formatter = jsonlogger.JsonFormatter("%(asctime)s %(name)s %(levelname)s %(message)s")
# Configure root logger with JSON
handler = logging.StreamHandler()
handler.setFormatter(json_formatter)
logging.basicConfig(
level=log_level,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
level=getattr(logging, log_level, logging.INFO),
handlers=[handler],
)
logger = logging.getLogger(__name__)
# Apply JSON formatter to uvicorn loggers (works even when run via `uvicorn src.main:app`)
for uvicorn_logger_name in ("uvicorn", "uvicorn.error", "uvicorn.access"):
uvicorn_logger = logging.getLogger(uvicorn_logger_name)
uvicorn_logger.handlers = [handler]
uvicorn_logger.setLevel(getattr(logging, log_level, logging.INFO))
uvicorn_logger.propagate = False
# Validate required environment variables
if not os.getenv("ANTHROPIC_API_KEY"):
logger.error("ANTHROPIC_API_KEY environment variable is required")
@@ -41,12 +55,9 @@ logger.info("Creating AG-UI app...")
async def handle_agent_request(request: Request) -> Response:
"""Handle incoming AG-UI requests with dynamic role-based MCP configuration."""
# Debug: log all incoming headers
logger.info(f"DEBUG: All request headers: {dict(request.headers)}")
# Extract user roles from request headers
roles_header = request.headers.get("x-user-roles", "")
logger.info(f"DEBUG: x-user-roles header value: '{roles_header}'")
user_roles = []
if roles_header:

2
web/agent/uv.lock generated
View File

@@ -236,6 +236,7 @@ dependencies = [
{ name = "openai" },
{ name = "pydantic-ai" },
{ name = "python-dotenv" },
{ name = "python-json-logger" },
{ name = "starlette" },
{ name = "uvicorn" },
]
@@ -249,6 +250,7 @@ requires-dist = [
{ name = "openai" },
{ name = "pydantic-ai" },
{ name = "python-dotenv" },
{ name = "python-json-logger", specifier = ">=4.0.0" },
{ name = "starlette" },
{ name = "uvicorn" },
]