Skip to content

Commit

Permalink
Merge branch 'main' into christophe-papazian/cmdi_support
Browse files Browse the repository at this point in the history
  • Loading branch information
christophe-papazian authored Jan 9, 2025
2 parents abf2434 + 75bed24 commit 08a2f53
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 18 deletions.
19 changes: 12 additions & 7 deletions ddtrace/_trace/tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,18 +940,23 @@ def trace(
)

def current_root_span(self) -> Optional[Span]:
"""Returns the root span of the current execution.
"""Returns the local root span of the current execution/process.
This is useful for attaching information related to the trace as a
whole without needing to add to child spans.
Note: This cannot be used to access the true root span of the trace
in a distributed tracing setup if the actual root span occurred in
another execution/process.
This is useful for attaching information to the local root span
of the current execution/process, which is often also service
entry span.
For example::
# get the root span
root_span = tracer.current_root_span()
# get the local root span
local_root_span = tracer.current_root_span()
# set the host just once on the root span
if root_span:
root_span.set_tag('host', '127.0.0.1')
if local_root_span:
local_root_span.set_tag('host', '127.0.0.1')
"""
span = self.current_span()
if span is None:
Expand Down
14 changes: 10 additions & 4 deletions ddtrace/internal/telemetry/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,17 @@ def send_event(self, request: Dict) -> Optional[httplib.HTTPResponse]:
conn.request("POST", self._endpoint, rb_json, headers)
resp = get_connection_response(conn)
if resp.status < 300:
log.debug("sent %d in %.5fs to %s. response: %s", len(rb_json), sw.elapsed(), self.url, resp.status)
log.debug(
"Instrumentation Telemetry sent %d in %.5fs to %s. response: %s",
len(rb_json),
sw.elapsed(),
self.url,
resp.status,
)
else:
log.debug("failed to send telemetry to %s. response: %s", self.url, resp.status)
except Exception:
log.debug("failed to send telemetry to %s.", self.url, exc_info=True)
log.debug("Failed to send Instrumentation Telemetry to %s. response: %s", self.url, resp.status)
except Exception as e:
log.debug("Failed to send Instrumentation Telemetry to %s. Error: %s", self.url, str(e))
finally:
if conn is not None:
conn.close()
Expand Down
30 changes: 24 additions & 6 deletions tests/contrib/elasticsearch/test_elasticsearch.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime
from http.client import HTTPConnection
from importlib import import_module
import json
import time

import pytest
Expand Down Expand Up @@ -167,7 +168,12 @@ def test_elasticsearch(self):
es.index(id=10, body={"name": "ten", "created": datetime.date(2016, 1, 1)}, **args)
es.index(id=11, body={"name": "eleven", "created": datetime.date(2016, 2, 1)}, **args)
es.index(id=12, body={"name": "twelve", "created": datetime.date(2016, 3, 1)}, **args)
result = es.search(sort=["name:desc"], size=100, body={"query": {"match_all": {}}}, **args)
result = es.search(
sort={"name": {"order": "desc", "unmapped_type": "keyword"}},
size=100,
body={"query": {"match_all": {}}},
**args,
)

assert len(result["hits"]["hits"]) == 3, result
spans = self.get_spans()
Expand All @@ -183,13 +189,25 @@ def test_elasticsearch(self):
assert url.endswith("/_search")
assert url == span.get_tag("elasticsearch.url")
if elasticsearch.__version__ >= (8, 0, 0):
assert span.get_tag("elasticsearch.body").replace(" ", "") == '{"query":{"match_all":{}},"size":100}'
assert set(span.get_tag("elasticsearch.params").split("&")) == {"sort=name%3Adesc"}
assert set(span.get_tag(http.QUERY_STRING).split("&")) == {"sort=name%3Adesc"}
# Key order is not consistent, parse into dict to compare
body = json.loads(span.get_tag("elasticsearch.body"))
assert body == {
"query": {"match_all": {}},
"sort": {"name": {"order": "desc", "unmapped_type": "keyword"}},
"size": 100,
}
assert not span.get_tag("elasticsearch.params")
assert not span.get_tag(http.QUERY_STRING)
else:
assert span.get_tag("elasticsearch.body").replace(" ", "") == '{"query":{"match_all":{}}}'
assert set(span.get_tag("elasticsearch.params").split("&")) == {"sort=name%3Adesc", "size=100"}
assert set(span.get_tag(http.QUERY_STRING).split("&")) == {"sort=name%3Adesc", "size=100"}
assert set(span.get_tag("elasticsearch.params").split("&")) == {
"sort=%7B%27name%27%3A+%7B%27order%27%3A+%27desc%27%2C+%27unmapped_type%27%3A+%27keyword%27%7D%7D",
"size=100",
}
assert set(span.get_tag(http.QUERY_STRING).split("&")) == {
"sort=%7B%27name%27%3A+%7B%27order%27%3A+%27desc%27%2C+%27unmapped_type%27%3A+%27keyword%27%7D%7D",
"size=100",
}
assert span.get_tag("component") == "elasticsearch"
assert span.get_tag("span.kind") == "client"

Expand Down
8 changes: 8 additions & 0 deletions tests/contrib/urllib3/test_urllib3.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from ddtrace.ext import http
from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME
from ddtrace.pin import Pin
from ddtrace.settings.asm import config as asm_config
from tests.contrib.config import HTTPBIN_CONFIG
from tests.opentracer.utils import init_tracer
from tests.utils import TracerTestCase
Expand Down Expand Up @@ -527,12 +528,16 @@ def test_distributed_tracing_disabled(self):
timeout=mock.ANY,
)

@pytest.mark.skip(reason="urlib3 does not set the ASM Manual keep tag so x-datadog headers are not propagated")
def test_distributed_tracing_apm_opt_out_true(self):
"""Tests distributed tracing headers are passed by default"""
# Check that distributed tracing headers are passed down; raise an error rather than make the
# request since we don't care about the response at all
config.urllib3["distributed_tracing"] = True
self.tracer.enabled = False
# Ensure the ASM SpanProcessor is set
self.tracer.configure(appsec_standalone_enabled=True, appsec_enabled=True)
assert asm_config._apm_opt_out
with mock.patch(
"urllib3.connectionpool.HTTPConnectionPool._make_request", side_effect=ValueError
) as m_make_request:
Expand Down Expand Up @@ -580,6 +585,9 @@ def test_distributed_tracing_apm_opt_out_false(self):
"""Test with distributed tracing disabled does not propagate the headers"""
config.urllib3["distributed_tracing"] = True
self.tracer.enabled = False
# Ensure the ASM SpanProcessor is set.
self.tracer.configure(appsec_standalone_enabled=False, appsec_enabled=True)
assert not asm_config._apm_opt_out
with mock.patch(
"urllib3.connectionpool.HTTPConnectionPool._make_request", side_effect=ValueError
) as m_make_request:
Expand Down
2 changes: 1 addition & 1 deletion tests/telemetry/test_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ def test_send_failing_request(mock_status, telemetry_writer):
telemetry_writer.periodic(force_flush=True)
# asserts unsuccessful status code was logged
log.debug.assert_called_with(
"failed to send telemetry to %s. response: %s",
"Failed to send Instrumentation Telemetry to %s. response: %s",
telemetry_writer._client.url,
mock_status,
)
Expand Down

0 comments on commit 08a2f53

Please sign in to comment.