You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ext_otel_patch.py 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. """
  2. Patch for OpenTelemetry context detach method to handle None tokens gracefully.
  3. This patch addresses the issue where OpenTelemetry's context.detach() method raises a TypeError
  4. when called with a None token. The error occurs in the contextvars_context.py file where it tries
  5. to call reset() on a None token.
  6. Related GitHub issue: https://github.com/langgenius/dify/issues/18496
  7. Error being fixed:
  8. ```
  9. Traceback (most recent call last):
  10. File "opentelemetry/context/__init__.py", line 154, in detach
  11. _RUNTIME_CONTEXT.detach(token)
  12. File "opentelemetry/context/contextvars_context.py", line 50, in detach
  13. self._current_context.reset(token) # type: ignore
  14. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  15. TypeError: expected an instance of Token, got None
  16. ```
  17. Instead of modifying the third-party package directly, this patch monkey-patches the
  18. context.detach method to gracefully handle None tokens.
  19. """
  20. import logging
  21. from functools import wraps
  22. from opentelemetry import context
  23. logger = logging.getLogger(__name__)
  24. # Store the original detach method
  25. original_detach = context.detach
  26. # Create a patched version that handles None tokens
  27. @wraps(original_detach)
  28. def patched_detach(token):
  29. """
  30. A patched version of context.detach that handles None tokens gracefully.
  31. """
  32. if token is None:
  33. logger.debug("Attempted to detach a None token, skipping")
  34. return
  35. return original_detach(token)
  36. def is_enabled():
  37. """
  38. Check if the extension is enabled.
  39. Always enable this patch to prevent errors even when OpenTelemetry is disabled.
  40. """
  41. return True
  42. def init_app(app):
  43. """
  44. Initialize the OpenTelemetry context patch.
  45. """
  46. # Replace the original detach method with our patched version
  47. context.detach = patched_detach
  48. logger.info("OpenTelemetry context.detach patched to handle None tokens")