Skip to content

Commit 2d662ac

Browse files
authored
feat(ci-visibility): gzip agentless request payload (#13301)
1 parent 601c0bd commit 2d662ac

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

ddtrace/internal/ci_visibility/writer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def __init__(
160160
# self._report_metrics = report_metrics,
161161
reuse_connections=reuse_connections,
162162
headers=headers,
163+
use_gzip=not use_evp,
163164
)
164165

165166
def stop(self, timeout=None):

ddtrace/internal/writer/writer.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import abc
22
import binascii
33
from collections import defaultdict
4+
import gzip
45
import logging
56
import os
67
import sys
@@ -152,13 +153,15 @@ def __init__(
152153
reuse_connections: Optional[bool] = None,
153154
headers: Optional[Dict[str, str]] = None,
154155
report_metrics: bool = True,
156+
use_gzip: bool = False,
155157
) -> None:
156158
if processing_interval is None:
157159
processing_interval = config._trace_writer_interval_seconds
158160
if timeout is None:
159161
timeout = agent_config.trace_agent_timeout_seconds
160162
super(HTTPWriter, self).__init__(interval=processing_interval)
161163
self.intake_url = intake_url
164+
self._intake_accepts_gzip = use_gzip
162165
self._buffer_size = buffer_size
163166
self._max_payload_size = max_payload_size
164167
self._headers = headers or {}
@@ -369,8 +372,20 @@ def _flush_queue_with_client(self, client: WriterClientBase, raise_exc: bool = F
369372
n_traces = len(client.encoder)
370373
try:
371374
encoded, n_traces = client.encoder.encode()
375+
372376
if encoded is None:
373377
return
378+
379+
# Should gzip the payload if intake accepts it
380+
if self._intake_accepts_gzip:
381+
original_size = len(encoded)
382+
# Replace the value to send with the gzipped the value
383+
encoded = gzip.compress(encoded, compresslevel=6)
384+
log.debug("Original size in bytes: %s, Compressed size: %s", original_size, len(encoded))
385+
386+
# And add the header
387+
self._headers["Content-Encoding"] = "gzip"
388+
374389
except Exception:
375390
# FIXME(munir): if client.encoder raises an Exception n_traces may not be accurate due to race conditions
376391
log.error("failed to encode trace with encoder %r", client.encoder, exc_info=True)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- |
4+
CI Visibility: This introduces the ability to gzip the payload when using the agentless setup, incurring in less network bandwith consumption.

tests/integration/test_integration_civisibility.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ def test_civisibility_intake_with_apikey():
7373

7474
@pytest.mark.subprocess()
7575
def test_civisibility_intake_payloads():
76+
import gzip
77+
7678
import mock
7779

7880
from ddtrace.internal.ci_visibility.constants import COVERAGE_TAG_NAME
@@ -101,10 +103,10 @@ def test_civisibility_intake_payloads():
101103
t.shutdown()
102104
assert 2 <= conn.request.call_count <= 3
103105
assert conn.request.call_args_list[0].args[1] == "api/v2/citestcycle"
104-
assert (
105-
b"svc-no-cov" in conn.request.call_args_list[0].args[2]
106+
assert b"svc-no-cov" in gzip.decompress(
107+
conn.request.call_args_list[0].args[2]
106108
), "requests to the cycle endpoint should include non-coverage spans"
107109
assert conn.request.call_args_list[1].args[1] == "api/v2/citestcov"
108-
assert (
109-
b"svc-no-cov" not in conn.request.call_args_list[1].args[2]
110+
assert b"svc-no-cov" not in gzip.decompress(
111+
conn.request.call_args_list[1].args[2]
110112
), "requests to the coverage endpoint should not include non-coverage spans"

0 commit comments

Comments
 (0)