|
4 | 4 | from typing import List
|
5 | 5 | from typing import Optional
|
6 | 6 | from typing import Tuple
|
| 7 | +from typing import TypeVar |
7 | 8 | import weakref
|
8 | 9 |
|
9 | 10 | import dd_trace_api
|
| 11 | +from wrapt.importer import when_imported |
10 | 12 |
|
11 | 13 | import ddtrace
|
| 14 | +from ddtrace.internal.logger import get_logger |
| 15 | +from ddtrace.internal.wrapping.context import WrappingContext |
12 | 16 |
|
13 | 17 |
|
14 | 18 | _DD_HOOK_NAME = "dd.hook"
|
15 | 19 | _TRACER_KEY = "Tracer"
|
16 | 20 | _STUB_TO_REAL = weakref.WeakKeyDictionary()
|
17 | 21 | _STUB_TO_REAL[dd_trace_api.tracer] = ddtrace.tracer
|
| 22 | +log = get_logger(__name__) |
| 23 | +T = TypeVar("T") |
| 24 | + |
| 25 | + |
| 26 | +class DDTraceAPIWrappingContextBase(WrappingContext): |
| 27 | + def _handle_return(self) -> None: |
| 28 | + method_name = self.__frame__.f_code.co_name |
| 29 | + stub_self = self.get_local("self") |
| 30 | + api_return_value = self.get_local("retval") |
| 31 | + _call_on_real_instance(stub_self, method_name, api_return_value, self.get_local("name")) |
| 32 | + |
| 33 | + def _handle_enter(self) -> None: |
| 34 | + pass |
| 35 | + |
| 36 | + def __enter__(self) -> "DDTraceAPIWrappingContextBase": |
| 37 | + super().__enter__() |
| 38 | + |
| 39 | + try: |
| 40 | + self._handle_enter() |
| 41 | + except Exception: # noqa: E722 |
| 42 | + log.debug("Error handling dd_trace_api instrumentation enter", exc_info=True) |
| 43 | + |
| 44 | + return self |
| 45 | + |
| 46 | + def __return__(self, value: T) -> T: |
| 47 | + """Always return the original value no matter what our instrumentation does""" |
| 48 | + try: |
| 49 | + self._handle_return() |
| 50 | + except Exception: # noqa: E722 |
| 51 | + log.debug("Error handling instrumentation return", exc_info=True) |
| 52 | + |
| 53 | + return value |
18 | 54 |
|
19 | 55 |
|
20 | 56 | def _proxy_span_arguments(args: List, kwargs: Dict) -> Tuple[List, Dict]:
|
@@ -57,12 +93,17 @@ def get_version() -> str:
|
57 | 93 | def patch(tracer=None):
|
58 | 94 | if getattr(dd_trace_api, "__datadog_patch", False):
|
59 | 95 | return
|
60 |
| - dd_trace_api.__datadog_patch = True |
61 | 96 | _STUB_TO_REAL[dd_trace_api.tracer] = tracer
|
62 |
| - if not getattr(dd_trace_api, "__dd_has_audit_hook", False): |
| 97 | + if False and not getattr(dd_trace_api, "__dd_has_audit_hook", False): |
63 | 98 | addaudithook(_hook)
|
64 | 99 | dd_trace_api.__dd_has_audit_hook = True
|
65 | 100 |
|
| 101 | + @when_imported("dd_trace_api") |
| 102 | + def _(m): |
| 103 | + DDTraceAPIWrappingContextBase(m.Tracer.start_span).wrap() |
| 104 | + |
| 105 | + dd_trace_api.__datadog_patch = True |
| 106 | + |
66 | 107 |
|
67 | 108 | def unpatch():
|
68 | 109 | if not getattr(dd_trace_api, "__datadog_patch", False):
|
|
0 commit comments