From 451ba05c25bd2fe8522fe8123d696932330dd1cc Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 21 Nov 2025 07:52:27 +0530 Subject: [PATCH] chore: add interceptor in logging config (#55) --- api/logging_config.py | 36 +++++++++++++++++++++++++++++++- ui/public/embed/dograh-widget.js | 8 ++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/api/logging_config.py b/api/logging_config.py index 2e71462..37f5ea3 100644 --- a/api/logging_config.py +++ b/api/logging_config.py @@ -1,13 +1,15 @@ +import logging import os import sys import loguru -from api.constants import ENVIRONMENT, SERIALIZE_LOG_OUTPUT +from api.constants import SERIALIZE_LOG_OUTPUT from api.enums import Environment from api.utils.worker import get_worker_id, is_worker_process from pipecat.utils.context import run_id_var, turn_var +ENVIRONMENT = os.getenv("ENVIRONMENT", Environment.LOCAL.value) ENABLE_TURN_LOGGING = os.getenv("ENABLE_TURN_LOGGING", "false").lower() == "true" # We write different uvicorn forked worker log to a different @@ -18,6 +20,26 @@ LOG_FILE_PATH = os.getenv("LOG_FILE_PATH", None) _logging_initialized = False +class InterceptHandler(logging.Handler): + """ + Intercept standard library logging calls and redirect them to loguru. + This allows us to capture uvicorn and other library logs through loguru. + """ + + def emit(self, record): + # Get corresponding Loguru level if it exists + try: + level = loguru.logger.level(record.levelname).name + except ValueError: + level = record.levelno + + # Use the original record's information instead of trying to find the caller + # This preserves the logger name (e.g., "uvicorn.access") in the logs + loguru.logger.patch(lambda r: r.update(name=record.name)).opt( + exception=record.exc_info + ).log(level, record.getMessage()) + + def inject_run_id(record): """Inject run_id from context variable into log record""" record["extra"]["run_id"] = run_id_var.get() @@ -103,4 +125,16 @@ def setup_logging(): ) loguru.logger = patched + + # Intercept standard library logging (uvicorn, etc.) and redirect to loguru + # Set level to INFO to avoid debug logs from libraries + logging.basicConfig(handlers=[InterceptHandler()], level=logging.INFO, force=True) + + # Specifically intercept uvicorn loggers with INFO level + for logger_name in ["uvicorn", "uvicorn.error", "uvicorn.access"]: + logging_logger = logging.getLogger(logger_name) + logging_logger.handlers = [InterceptHandler()] + logging_logger.setLevel(logging.INFO) + logging_logger.propagate = False + _logging_initialized = True diff --git a/ui/public/embed/dograh-widget.js b/ui/public/embed/dograh-widget.js index 3d38c64..a9c93ea 100644 --- a/ui/public/embed/dograh-widget.js +++ b/ui/public/embed/dograh-widget.js @@ -65,7 +65,13 @@ let apiBaseUrl = DEFAULT_CONFIG.apiBaseUrl; if (apiEndpoint) { // Use the apiEndpoint from URL parameter if provided - apiBaseUrl = apiEndpoint.replace(/\/+$/, ''); // Remove trailing slashes + // Ensure it has a protocol + if (!apiEndpoint.startsWith('http://') && !apiEndpoint.startsWith('https://')) { + // Default to https for production endpoints + apiBaseUrl = 'https://' + apiEndpoint.replace(/\/+$/, ''); + } else { + apiBaseUrl = apiEndpoint.replace(/\/+$/, ''); // Remove trailing slashes + } } else if (scriptUrl.origin.includes('localhost')) { apiBaseUrl = 'http://localhost:8000'; } else {