import os
import threading
import sys
import logging
import logfire
from loguru import logger
# Filter class to suppress specific SSE parsing errors from Cohere SDK
class SSEErrorFilter(logging.Filter):
def filter(self, record):
# Suppress the "[DONE]" JSON parsing error from httpx-sse/cohere
if (
"Failed to parse SSE data field as JSON" in record.getMessage()
and "[DONE]" in record.getMessage()
):
return False
return True
class SingletonLogger:
_instance = None
_lock = threading.Lock()
def __new__(cls, log_file="app.log"):
if not cls._instance:
with cls._lock:
if not cls._instance:
cls._instance = super(SingletonLogger, cls).__new__(cls)
cls._instance._init_logger(log_file)
return cls._instance
def _init_logger(self, log_file):
logger.remove() # Remove default console handler
send_to_logfire = os.getenv("SEND_TO_LOGFIRE", "false").lower() in (
"1",
"true",
"yes",
)
logfire.configure(
token=os.getenv("LOGFIRE_TOKEN"),
send_to_logfire=send_to_logfire,
service_name=os.getenv("OTEL_SERVICE_NAME", "arxiver-backend"),
service_version=os.getenv("OTEL_SERVICE_VERSION", "0.0.1"),
environment=os.getenv("ENVIRONMENT", "development"),
)
if send_to_logfire:
logger.configure(handlers=[logfire.loguru_handler()])
# Filter function for loguru to suppress SSE [DONE] parsing errors
def filter_sse_errors(record):
message = record.get("message", "")
if (
"Failed to parse SSE data field as JSON" in message
and "[DONE]" in message
):
return False
return True
logger.add(
sys.stderr,
format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} - {message}",
backtrace=True,
filter=filter_sse_errors,
)
# Apply SSE error filter to suppress Cohere's [DONE] parsing warnings
sse_filter = SSEErrorFilter()
# Apply filter to httpx-sse and cohere loggers
for logger_name in ["httpx_sse", "cohere", "httpx"]:
lib_logger = logging.getLogger(logger_name)
lib_logger.addFilter(sse_filter)
# Also apply to root logger to catch any other instances
logging.getLogger().addFilter(sse_filter)
self.logger = logger
def get_logger(self):
return self.logger