Skip to content

Commit ab87f30

Browse files
authored
chore(tracer): deprecate Tracer.writer (#3223)
The `Tracer.writer` will be removed from the public API in v1.0 so is deprecated here.
1 parent ee11ad0 commit ab87f30

File tree

26 files changed

+196
-141
lines changed

26 files changed

+196
-141
lines changed

benchmarks/threading/scenario.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def write(self, spans=None):
2525
# type: (Optional[List[Span]]) -> None
2626
pass
2727

28+
def flush_queue(self):
29+
# type: () -> None
30+
pass
31+
2832

2933
@bm.register
3034
class Threading(bm.Scenario):

ddtrace/contrib/httplib/patch.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ def should_skip_request(pin, request):
165165
if not pin or not pin.enabled():
166166
return True
167167

168-
if hasattr(pin.tracer.writer, "agent_url"):
169-
parsed = parse.urlparse(pin.tracer.writer.agent_url)
168+
agent_url = pin.tracer.agent_trace_url
169+
if agent_url:
170+
parsed = parse.urlparse(agent_url)
170171
return request.host == parsed.hostname and request.port == parsed.port
171172
return False
172173

ddtrace/contrib/rq/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def traced_perform_job(rq, pin, func, instance, args, kwargs):
177177
finally:
178178
# Force flush to agent since the process `os.exit()`s
179179
# immediately after this method returns
180-
pin.tracer.writer.flush_queue()
180+
pin.tracer.flush()
181181

182182

183183
@trace_utils.with_traced_module

ddtrace/internal/debug.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ def collect(tracer):
4949

5050
from ddtrace.internal.runtime.runtime_metrics import RuntimeWorker
5151

52-
if isinstance(tracer.writer, LogWriter):
52+
if isinstance(tracer._writer, LogWriter):
5353
agent_url = "AGENTLESS"
5454
agent_error = None
55-
elif isinstance(tracer.writer, AgentWriter):
56-
writer = tracer.writer
55+
elif isinstance(tracer._writer, AgentWriter):
56+
writer = tracer._writer
5757
agent_url = writer.agent_url
5858
try:
5959
writer.write([])

ddtrace/internal/writer.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ def write(self, spans=None):
173173
# type: (Optional[List[Span]]) -> None
174174
pass
175175

176+
@abc.abstractmethod
177+
def flush_queue(self):
178+
# type: () -> None
179+
pass
180+
176181

177182
class LogWriter(TraceWriter):
178183
def __init__(
@@ -210,6 +215,10 @@ def write(self, spans=None):
210215
self.out.write(encoded + "\n")
211216
self.out.flush()
212217

218+
def flush_queue(self):
219+
# type: () -> None
220+
pass
221+
213222

214223
class AgentWriter(periodic.PeriodicService, TraceWriter):
215224
"""Writer to the Datadog Agent.

ddtrace/profiling/profiler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ def _build_default_exporters(self):
146146
)
147147
endpoint = self.ENDPOINT_TEMPLATE.format(os.environ.get("DD_SITE", "datadoghq.com"))
148148
else:
149-
if isinstance(self.tracer.writer, writer.AgentWriter):
150-
endpoint = self.tracer.writer.agent_url
149+
if isinstance(self.tracer._writer, writer.AgentWriter):
150+
endpoint = self.tracer._writer.agent_url
151151
else:
152152
endpoint = agent.get_trace_url()
153153

ddtrace/tracer.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
from .sampler import RateByServiceSampler
6262
from .sampler import RateSampler
6363
from .span import Span
64+
from .vendor.debtcollector import removals
6465

6566

6667
log = get_logger(__name__)
@@ -147,7 +148,7 @@ def __init__(
147148
report_metrics=config.health_metrics_enabled,
148149
sync_mode=self._use_sync_mode(),
149150
)
150-
self.writer = writer # type: TraceWriter
151+
self._writer = writer # type: TraceWriter
151152

152153
# DD_TRACER_... should be deprecated after version 1.0.0 is released
153154
pfe_default_value = False
@@ -351,8 +352,8 @@ def configure(
351352
if any(x is not None for x in [hostname, port, uds_path, https]):
352353
# If any of the parts of the URL have updated, merge them with
353354
# the previous writer values.
354-
if isinstance(self.writer, AgentWriter):
355-
prev_url_parsed = compat.parse.urlparse(self.writer.agent_url)
355+
if isinstance(self._writer, AgentWriter):
356+
prev_url_parsed = compat.parse.urlparse(self._writer.agent_url)
356357
else:
357358
prev_url_parsed = compat.parse.urlparse("")
358359

@@ -369,26 +370,26 @@ def configure(
369370
port = prev_url_parsed.port
370371
scheme = "https" if https else "http"
371372
url = "%s://%s:%s" % (scheme, hostname, port)
372-
elif isinstance(self.writer, AgentWriter):
373+
elif isinstance(self._writer, AgentWriter):
373374
# Reuse the URL from the previous writer if there was one.
374-
url = self.writer.agent_url
375+
url = self._writer.agent_url
375376
else:
376377
# No URL parts have updated and there's no previous writer to
377378
# get the URL from.
378379
url = None
379380

380381
try:
381-
self.writer.stop()
382+
self._writer.stop()
382383
except service.ServiceStatusError:
383384
# It's possible the writer never got started in the first place :(
384385
pass
385386

386387
if writer is not None:
387-
self.writer = writer
388+
self._writer = writer
388389
elif url:
389390
# Verify the URL and create a new AgentWriter with it.
390391
agent.verify_url(url)
391-
self.writer = AgentWriter(
392+
self._writer = AgentWriter(
392393
url,
393394
sampler=self.sampler,
394395
priority_sampler=self.priority_sampler,
@@ -397,11 +398,11 @@ def configure(
397398
sync_mode=self._use_sync_mode(),
398399
api_version=api_version,
399400
)
400-
elif writer is None and isinstance(self.writer, LogWriter):
401+
elif writer is None and isinstance(self._writer, LogWriter):
401402
# No need to do anything for the LogWriter.
402403
pass
403-
if isinstance(self.writer, AgentWriter):
404-
self.writer.dogstatsd = get_dogstatsd_client(self._dogstatsd_url) # type: ignore[has-type]
404+
if isinstance(self._writer, AgentWriter):
405+
self._writer.dogstatsd = get_dogstatsd_client(self._dogstatsd_url) # type: ignore[has-type]
405406
self._initialize_span_processors()
406407

407408
if context_provider is not None:
@@ -436,7 +437,7 @@ def _child_after_fork(self):
436437
self._services = set()
437438

438439
# Re-create the background writer thread
439-
self.writer = self.writer.recreate()
440+
self._writer = self._writer.recreate()
440441
self._initialize_span_processors()
441442

442443
self._new_process = True
@@ -671,8 +672,8 @@ def _initialize_span_processors(self, appsec_enabled=asbool(get_env("appsec", "e
671672
partial_flush_enabled=self._partial_flush_enabled,
672673
partial_flush_min_spans=self._partial_flush_min_spans,
673674
trace_processors=trace_processors,
674-
writer=self.writer,
675-
)
675+
writer=self._writer,
676+
),
676677
] # type: List[SpanProcessor]
677678

678679
if appsec_enabled:
@@ -811,7 +812,24 @@ def write(self, spans):
811812
return
812813

813814
if spans is not None:
814-
self.writer.write(spans=spans)
815+
self._writer.write(spans=spans)
816+
817+
@removals.removed_property(message="Use Tracer.flush instead to flush buffered traces to agent", version="1.0.0")
818+
def writer(self):
819+
return self._writer
820+
821+
@property
822+
def agent_trace_url(self):
823+
# type: () -> Optional[str]
824+
"""Trace agent url"""
825+
if isinstance(self._writer, AgentWriter):
826+
return self._writer.agent_url
827+
828+
return None
829+
830+
def flush(self):
831+
"""Flush the buffer of the trace writer. This does nothing if an unbuffered trace writer is used."""
832+
self._writer.flush_queue()
815833

816834
@deprecated(message="Manually setting service info is no longer necessary", version="1.0.0")
817835
def set_service_info(self, *args, **kwargs):
@@ -974,7 +992,7 @@ def shutdown(self, timeout=None):
974992
:type timeout: :obj:`int` | :obj:`float` | :obj:`None`
975993
"""
976994
try:
977-
self.writer.stop(timeout=timeout)
995+
self._writer.stop(timeout=timeout)
978996
except service.ServiceStatusError:
979997
# It's possible the writer never got started in the first place :(
980998
pass

docs/spelling_wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ submodules
143143
timestamp
144144
tweens
145145
uWSGI
146+
unbuffered
146147
unicode
147148
uninstrumented
148149
unix
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
Add :py:attr:`ddtrace.Tracer.agent_trace_url` and :py:meth:`ddtrace.Tracer.flush`.
5+
deprecations:
6+
- |
7+
:py:attr:`ddtrace.Tracer.writer` is deprecated. To force flushing of buffered traces to the agent, use :py:meth:`ddtrace.Tracer.flush` instead.

tests/benchmarks/test_encoding.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_dd_origin_tagging_spans_via_encoder(benchmark, trace_size):
109109
with tracer.trace("") as span:
110110
span.set_tag("tag", "value")
111111
pass
112-
trace = tracer.writer.pop()
112+
trace = tracer.pop()
113113

114114
def _(trace):
115115
trace_encoder.put(trace)

0 commit comments

Comments
 (0)