diff --git a/sample.env b/sample.env index 75fbe31..19c7b57 100644 --- a/sample.env +++ b/sample.env @@ -32,8 +32,11 @@ LANGFUSE_HOST="https://cloud.langfuse.com" # Trace context file for distributed tracing (optional) # Used for linking traces between fastomop and omcp across processes -# Default: Uses system temp directory (e.g., /tmp/ on Unix, %TEMP% on Windows) +# Default behavior (cross-platform): +# - Windows: Uses %TEMP%\.fastomop_langfuse_trace_context.json +# - macOS/Linux: Uses /tmp/.fastomop_langfuse_trace_context.json # Only set this if you need a custom location or for cross-service coordination +# IMPORTANT: fastomop and omcp must use the same file path for trace propagation to work #LANGFUSE_TRACE_CONTEXT_FILE=/tmp/.fastomop_langfuse_trace_context.json # ============================================================================ diff --git a/src/omcp/config.py b/src/omcp/config.py index cd9b888..7f5213d 100644 --- a/src/omcp/config.py +++ b/src/omcp/config.py @@ -4,9 +4,15 @@ from dotenv import load_dotenv from langfuse import Langfuse from langfuse import observe +from opentelemetry.propagate import set_global_textmap +from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator load_dotenv() +# Configure OpenTelemetry W3C Trace Context propagator +# This is required for cross-process trace propagation with Langfuse V3 +set_global_textmap(TraceContextTextMapPropagator()) + # Global configuration variables ENABLE_LOGGING = os.environ.get("ENABLE_LOGGING", "true").lower() == "true" ENABLE_LANGFUSE = os.environ.get("ENABLE_LANGFUSE", "true").lower() == "true" diff --git a/src/omcp/trace_context.py b/src/omcp/trace_context.py index 1132262..4222237 100644 --- a/src/omcp/trace_context.py +++ b/src/omcp/trace_context.py @@ -9,14 +9,22 @@ """ import os -import tempfile import json +import platform +import tempfile from pathlib import Path from typing import Optional, Dict # Shared trace context file path (same as fastomop) -default_path = Path(tempfile.gettempdir()) / ".fastomop_langfuse_trace_context.json" +# Use platform-specific temp directory for cross-platform compatibility +if platform.system() == "Windows": + default_path = Path(tempfile.gettempdir()) / ".fastomop_langfuse_trace_context.json" +else: + # On Unix-like systems (macOS/Linux), use /tmp for consistency across processes + # tempfile.gettempdir() can return different paths in different contexts on macOS + default_path = Path("/tmp") / ".fastomop_langfuse_trace_context.json" + TRACE_CONTEXT_FILE = Path( os.environ.get("LANGFUSE_TRACE_CONTEXT_FILE", str(default_path)) ) @@ -44,10 +52,16 @@ def read_trace_context() -> Dict[str, Optional[str]]: # Backward compatibility: also read old trace_id format "trace_id": context.get("trace_id"), } - except Exception: + except Exception as e: # Non-critical error, return empty context - # Don't log here to avoid noise, caller can decide how to handle None values - pass + # Only log if file exists but can't be read (actual error) + if TRACE_CONTEXT_FILE.exists(): + import logging + + logger = logging.getLogger("omcp") + logger.warning( + f"Failed to read trace context from {TRACE_CONTEXT_FILE}: {e}" + ) return { "traceparent": None,