Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions .riot/requirements/1353fd0.txt

This file was deleted.

22 changes: 0 additions & 22 deletions .riot/requirements/1540a76.txt

This file was deleted.

28 changes: 28 additions & 0 deletions .riot/requirements/18417b5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/18417b5.in
#
attrs==25.4.0
backports-asyncio-runner==1.2.0
coverage[toml]==7.12.0
exceptiongroup==1.3.0
httpretty==1.1.4
hypothesis==6.45.0
iniconfig==2.3.0
mock==5.2.0
msgpack==1.1.2
opentracing==2.4.0
packaging==25.0
pluggy==1.6.0
py-cpuinfo==9.0.0
pygments==2.19.2
pytest==9.0.1
pytest-asyncio==1.3.0
pytest-benchmark==5.2.3
pytest-cov==7.0.0
pytest-mock==3.15.1
sortedcontainers==2.4.0
tomli==2.3.0
typing-extensions==4.15.0
25 changes: 25 additions & 0 deletions .riot/requirements/18569c9.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/18569c9.in
#
attrs==25.4.0
coverage[toml]==7.12.0
httpretty==1.1.4
hypothesis==6.45.0
iniconfig==2.3.0
mock==5.2.0
msgpack==1.1.2
opentracing==2.4.0
packaging==25.0
pluggy==1.6.0
py-cpuinfo==9.0.0
pygments==2.19.2
pytest==9.0.1
pytest-asyncio==1.3.0
pytest-benchmark==5.2.3
pytest-cov==7.0.0
pytest-mock==3.15.1
sortedcontainers==2.4.0
typing-extensions==4.15.0
28 changes: 28 additions & 0 deletions .riot/requirements/191f37c.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/191f37c.in
#
attrs==25.4.0
backports-asyncio-runner==1.2.0
coverage[toml]==7.10.7
exceptiongroup==1.3.0
httpretty==1.1.4
hypothesis==6.45.0
iniconfig==2.1.0
mock==5.2.0
msgpack==1.1.2
opentracing==2.4.0
packaging==25.0
pluggy==1.6.0
py-cpuinfo==9.0.0
pygments==2.19.2
pytest==8.4.2
pytest-asyncio==1.2.0
pytest-benchmark==5.2.3
pytest-cov==7.0.0
pytest-mock==3.15.1
sortedcontainers==2.4.0
tomli==2.3.0
typing-extensions==4.15.0
25 changes: 25 additions & 0 deletions .riot/requirements/197e9b6.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/197e9b6.in
#
attrs==25.4.0
coverage[toml]==7.12.0
httpretty==1.1.4
hypothesis==6.45.0
iniconfig==2.3.0
mock==5.2.0
msgpack==1.1.2
opentracing==2.4.0
packaging==25.0
pluggy==1.6.0
py-cpuinfo==9.0.0
pygments==2.19.2
pytest==9.0.1
pytest-asyncio==1.3.0
pytest-benchmark==5.2.3
pytest-cov==7.0.0
pytest-mock==3.15.1
sortedcontainers==2.4.0
typing-extensions==4.15.0
20 changes: 11 additions & 9 deletions .riot/requirements/1d9ed4a.txt → .riot/requirements/1a30fec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@
# This file is autogenerated by pip-compile with Python 3.14
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/1d9ed4a.in
# pip-compile --allow-unsafe --no-annotate .riot/requirements/1a30fec.in
#
attrs==25.3.0
coverage[toml]==7.10.5
attrs==25.4.0
coverage[toml]==7.12.0
httpretty==1.1.4
hypothesis==6.45.0
iniconfig==2.1.0
iniconfig==2.3.0
mock==5.2.0
msgpack==1.1.1
msgpack==1.1.2
opentracing==2.4.0
packaging==25.0
pluggy==1.6.0
py-cpuinfo==9.0.0
pygments==2.19.2
pytest==8.4.1
pytest-asyncio==1.1.0
pytest-cov==6.2.1
pytest-mock==3.14.1
pytest==9.0.1
pytest-asyncio==1.3.0
pytest-benchmark==5.2.3
pytest-cov==7.0.0
pytest-mock==3.15.1
sortedcontainers==2.4.0
typing-extensions==4.15.0
24 changes: 0 additions & 24 deletions .riot/requirements/1a9b995.txt

This file was deleted.

22 changes: 0 additions & 22 deletions .riot/requirements/2644218.txt

This file was deleted.

25 changes: 25 additions & 0 deletions .riot/requirements/278c26c.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --allow-unsafe --no-annotate .riot/requirements/278c26c.in
#
attrs==25.4.0
coverage[toml]==7.12.0
httpretty==1.1.4
hypothesis==6.45.0
iniconfig==2.3.0
mock==5.2.0
msgpack==1.1.2
opentracing==2.4.0
packaging==25.0
pluggy==1.6.0
py-cpuinfo==9.0.0
pygments==2.19.2
pytest==9.0.1
pytest-asyncio==1.3.0
pytest-benchmark==5.2.3
pytest-cov==7.0.0
pytest-mock==3.15.1
sortedcontainers==2.4.0
typing-extensions==4.15.0
24 changes: 0 additions & 24 deletions .riot/requirements/5c95c1a.txt

This file was deleted.

13 changes: 10 additions & 3 deletions ddtrace/debugging/_origin/span.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from ddtrace.internal.packages import is_user_code
from ddtrace.internal.safety import _isinstance
from ddtrace.internal.settings.code_origin import config as co_config
from ddtrace.internal.wrapping.context import WrappingContext
from ddtrace.internal.wrapping.context import LazyWrappingContext
from ddtrace.trace import Span


Expand Down Expand Up @@ -111,7 +111,14 @@ class EntrySpanLocation:
probe: EntrySpanProbe


class EntrySpanWrappingContext(WrappingContext):
class EntrySpanWrappingContext(LazyWrappingContext):
"""Entry span wrapping context.

This context is lazy to avoid paid any upfront instrumentation costs for
large functions that might not get invoked. Instead, the actual wrapping
will be performed on the first invocation.
"""

__enabled__ = False
__priority__ = 199

Expand Down Expand Up @@ -227,7 +234,7 @@ def instrument_view(cls, f: t.Union[FunctionType, MethodType]) -> None:

_f = t.cast(FunctionType, f)
if not EntrySpanWrappingContext.is_wrapped(_f):
log.debug("Patching entrypoint %r for code origin", f)
log.debug("Lazy wrapping entrypoint %r for code origin", f)
EntrySpanWrappingContext(cls.__uploader__, _f).wrap()

@classmethod
Expand Down
3 changes: 0 additions & 3 deletions ddtrace/internal/utils/inspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ def undecorated(f: FunctionType, name: str, path: Path) -> FunctionType:
def match(g):
return g.__code__.co_name == name and resolved_code_origin(g.__code__) == path

if _isinstance(f, FunctionType) and match(f):
return f

seen_functions = {f}
q = deque([f]) # FIFO: use popleft and append

Expand Down
1 change: 1 addition & 0 deletions riotfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT
"httpretty": latest,
"typing-extensions": latest,
"pytest-asyncio": latest,
"pytest-benchmark": latest,
},
pys=select_pys(),
),
Expand Down
41 changes: 41 additions & 0 deletions tests/debugging/origin/test_span.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,44 @@ def entry_call(self):
entry.get_tag("_dd.code_origin.frames.0.method")
== "SpanProbeTestCase.test_span_origin_entry_method.<locals>.App.entry_call"
)


def test_instrument_view_benchmark(benchmark):
Comment thread
P403n1x87 marked this conversation as resolved.
"""Benchmark instrument_view performance when wrapping functions."""
MockSpanCodeOriginProcessorEntry.enable()

try:

def setup():
"""Create a unique function to wrap for each iteration."""

# Create a more realistic view function similar to Flask views
# with decorators, imports, and more complex code
def realistic_view(request_arg, *args, **kwargs):
"""A realistic view function with actual code."""
import json
import os # noqa

data = {"status": "ok", "items": []}
for i in range(10):
item = {
"id": i,
"name": f"item_{i}",
"value": i * 100,
}
data["items"].append(item)

result = json.dumps(data)
return result

return (realistic_view,), {}

# Benchmark the wrapping operation
benchmark.pedantic(
MockSpanCodeOriginProcessorEntry.instrument_view,
setup=setup,
rounds=100,
)

finally:
MockSpanCodeOriginProcessorEntry.disable()
Loading
Loading