diff --git a/backend/utils/__init__.py b/backend/utils/__init__.py index dd7ee44cc..a93f712f3 100644 --- a/backend/utils/__init__.py +++ b/backend/utils/__init__.py @@ -1 +1,3 @@ -# Utils package +from . import traceroot_wrapper + +__all__ = ['traceroot_wrapper'] diff --git a/utils/traceroot_wrapper.py b/backend/utils/traceroot_wrapper.py similarity index 83% rename from utils/traceroot_wrapper.py rename to backend/utils/traceroot_wrapper.py index ac03e6c3a..5ad9c8e32 100644 --- a/utils/traceroot_wrapper.py +++ b/backend/utils/traceroot_wrapper.py @@ -1,9 +1,16 @@ from pathlib import Path from typing import Callable import logging -import traceroot from dotenv import load_dotenv +# Try to import traceroot, but handle gracefully if not available +try: + import traceroot + TRACEROOT_AVAILABLE = True +except ImportError: + TRACEROOT_AVAILABLE = False + traceroot = None + # Auto-detect module name based on caller's path def _get_module_name(): """Automatically detect if this is being called from backend or server.""" @@ -26,7 +33,7 @@ env_path = Path(__file__).resolve().parents[1] / '.env' load_dotenv(env_path) -if traceroot.init(): +if TRACEROOT_AVAILABLE and traceroot.init(): from traceroot.logger import get_logger as _get_traceroot_logger trace = traceroot.trace @@ -69,7 +76,10 @@ else: # Log fallback mode _fallback_logger = logging.getLogger("traceroot_wrapper") - _fallback_logger.warning("TraceRoot not initialized - using Python logging as fallback") + if TRACEROOT_AVAILABLE: + _fallback_logger.warning("TraceRoot available but not initialized - using Python logging as fallback") + else: + _fallback_logger.warning("TraceRoot not available - using Python logging as fallback") __all__ = ['trace', 'get_logger', 'is_enabled'] diff --git a/server/utils/__init__.py b/server/utils/__init__.py index e69de29bb..a93f712f3 100644 --- a/server/utils/__init__.py +++ b/server/utils/__init__.py @@ -0,0 +1,3 @@ +from . import traceroot_wrapper + +__all__ = ['traceroot_wrapper'] diff --git a/server/utils/traceroot_wrapper.py b/server/utils/traceroot_wrapper.py new file mode 100644 index 000000000..5ad9c8e32 --- /dev/null +++ b/server/utils/traceroot_wrapper.py @@ -0,0 +1,85 @@ +from pathlib import Path +from typing import Callable +import logging +from dotenv import load_dotenv + +# Try to import traceroot, but handle gracefully if not available +try: + import traceroot + TRACEROOT_AVAILABLE = True +except ImportError: + TRACEROOT_AVAILABLE = False + traceroot = None + +# Auto-detect module name based on caller's path +def _get_module_name(): + """Automatically detect if this is being called from backend or server.""" + import inspect + frame = inspect.currentframe() + try: + # Go up the stack to find the caller + caller_frame = frame.f_back.f_back if frame and frame.f_back else None + if caller_frame: + caller_file = caller_frame.f_globals.get('__file__', '') + if 'backend' in caller_file: + return 'backend' + elif 'server' in caller_file: + return 'server' + finally: + del frame + return 'unknown' + +env_path = Path(__file__).resolve().parents[1] / '.env' + +load_dotenv(env_path) + +if TRACEROOT_AVAILABLE and traceroot.init(): + from traceroot.logger import get_logger as _get_traceroot_logger + + trace = traceroot.trace + + def get_logger(name: str = __name__): + """Get TraceRoot logger instance.""" + return _get_traceroot_logger(name) + + def is_enabled() -> bool: + """Check if TraceRoot is enabled.""" + return True + + # Log successful initialization + module_name = _get_module_name() + _init_logger = _get_traceroot_logger("traceroot_wrapper") + _init_logger.info("TraceRoot initialized successfully", extra={"backend": "traceroot", "service_module": module_name}) +else: + # No-op implementations when TraceRoot is not configured + def trace(*args, **kwargs): + """No-op trace decorator.""" + def decorator(func: Callable) -> Callable: + return func + return decorator + + def get_logger(name: str = __name__): + """Get standard Python logger when TraceRoot is disabled.""" + logger = logging.getLogger(name) + if not logger.handlers: + # Configure basic logging if no handlers exist + handler = logging.StreamHandler() + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.INFO) + return logger + + def is_enabled() -> bool: + """Check if TraceRoot is enabled.""" + return False + + # Log fallback mode + _fallback_logger = logging.getLogger("traceroot_wrapper") + if TRACEROOT_AVAILABLE: + _fallback_logger.warning("TraceRoot available but not initialized - using Python logging as fallback") + else: + _fallback_logger.warning("TraceRoot not available - using Python logging as fallback") + + +__all__ = ['trace', 'get_logger', 'is_enabled'] diff --git a/utils/__init__.py b/utils/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -