Skip to content

Commit 12df2e6

Browse files
committed
Adding features
- Adding testing on multiple versions - Adding `_untracked_export_rate` to control how many untracked spans we send
1 parent 932511c commit 12df2e6

File tree

4 files changed

+62
-13
lines changed

4 files changed

+62
-13
lines changed

.circleci/config.yml

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ orbs:
1010
workflows:
1111
sample:
1212
jobs:
13-
- build-and-test
13+
- test-38
14+
- test-37
15+
- test-36
1416

1517

1618
jobs:
17-
build-and-test:
19+
test-38:
1820
docker:
1921
- image: cimg/python:3.8
2022
steps:
@@ -26,3 +28,27 @@ jobs:
2628
- run:
2729
name: Run tests
2830
command: pytest
31+
test-37:
32+
docker:
33+
- image: cimg/python:3.7
34+
steps:
35+
- checkout
36+
- run:
37+
name: installpackages
38+
command: |
39+
make testsuite.install
40+
- run:
41+
name: Run tests
42+
command: pytest
43+
test-36:
44+
docker:
45+
- image: cimg/python:3.6
46+
steps:
47+
- checkout
48+
- run:
49+
name: installpackages
50+
command: |
51+
make testsuite.install
52+
- run:
53+
name: Run tests
54+
command: pytest

codecovopentelem/__init__.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import json
22
import logging
33
import random
4-
import re
54
import urllib.parse
65
from base64 import b64encode
76
from decimal import Decimal
87
from io import StringIO
9-
from typing import Optional, Tuple
8+
from typing import Optional, Tuple, Pattern
109

1110
import coverage
1211
import requests
@@ -43,7 +42,7 @@ def __init__(
4342
self,
4443
cov_storage: CodecovCoverageStorageManager,
4544
sample_rate: Decimal,
46-
name_regex: re.Pattern = None,
45+
name_regex: Pattern = None,
4746
):
4847
self._cov_storage = cov_storage
4948
self._sample_rate = sample_rate
@@ -71,11 +70,13 @@ def __init__(
7170
repository_token: str,
7271
profiling_identifier: str,
7372
codecov_endpoint: str,
73+
untracked_export_rate: float,
7474
):
7575
self._cov_storage = cov_storage
7676
self._repository_token = repository_token
7777
self._profiling_identifier = profiling_identifier
7878
self._codecov_endpoint = codecov_endpoint
79+
self._untracked_export_rate = untracked_export_rate
7980

8081
def _load_codecov_dict(self, span, cov):
8182
k = StringIO()
@@ -92,17 +93,20 @@ def _load_codecov_dict(self, span, cov):
9293
return coverage_dict
9394

9495
def export(self, spans):
95-
data = []
96+
tracked_spans = []
9697
untracked_spans = []
9798
for span in spans:
9899
span_id = span.context.span_id
99100
cov = self._cov_storage.pop_cov_for_span(span_id)
100101
s = json.loads(span.to_json())
101102
if cov is not None:
102103
s["codecov"] = self._load_codecov_dict(span, cov)
103-
data.append(s)
104+
tracked_spans.append(s)
104105
else:
105-
untracked_spans.append(s)
106+
if random.random() < self._untracked_export_rate:
107+
untracked_spans.append(s)
108+
if not tracked_spans:
109+
return SpanExportResult.SUCCESS
106110
url = urllib.parse.urljoin(self._codecov_endpoint, "/profiling/uploads")
107111
res = requests.post(
108112
url,
@@ -118,7 +122,7 @@ def export(self, spans):
118122
requests.put(
119123
location,
120124
headers={"Content-Type": "application/txt"},
121-
data=json.dumps({"spans": data, "untracked": untracked_spans}).encode(),
125+
data=json.dumps({"spans": tracked_spans, "untracked": untracked_spans}).encode(),
122126
)
123127
return SpanExportResult.SUCCESS
124128

@@ -127,7 +131,7 @@ def get_codecov_opentelemetry_instances(
127131
repository_token: str,
128132
profiling_identifier: str,
129133
sample_rate: float,
130-
name_regex: Optional[re.Pattern],
134+
name_regex: Optional[Pattern],
131135
codecov_endpoint: str = None,
132136
writeable_folder: str = None,
133137
) -> Tuple[CodecovCoverageGenerator, CoverageExporter]:
@@ -139,7 +143,7 @@ def get_codecov_opentelemetry_instances(
139143
repository_token (str): The profiling-capable authentication token
140144
profiling_identifier (str): The identifier for what profiling one is doing
141145
sample_rate (float): The sampling rate for codecov
142-
name_regex (Optional[re.Pattern]): A regex to filter which spans should be
146+
name_regex (Optional[Pattern]): A regex to filter which spans should be
143147
sampled
144148
codecov_endpoint (str, optional): For configuring the endpoint in case
145149
the user is in enterprise (not supported yet). Default is "https://api.codecov.io/"
@@ -151,7 +155,13 @@ def get_codecov_opentelemetry_instances(
151155
codecov_endpoint = "https://api.codecov.io"
152156
manager = CodecovCoverageStorageManager(writeable_folder)
153157
generator = CodecovCoverageGenerator(manager, sample_rate, name_regex)
158+
# untracked rate set to make it so we export roughly as many tracked and untracked spans
159+
untracked_export_rate = sample_rate / (1 - sample_rate) if sample_rate < 1 else 0
154160
exporter = CoverageExporter(
155-
manager, repository_token, profiling_identifier, codecov_endpoint
161+
manager,
162+
repository_token,
163+
profiling_identifier,
164+
codecov_endpoint,
165+
untracked_export_rate,
156166
)
157167
return (generator, exporter)

tests/test_exporter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def test_export_span(mocker, mocked_responses):
4141
content_type="application/json",
4242
)
4343
exporter = CoverageExporter(
44-
cov_storage, repository_token, profiling_identifier, codecov_endpoint
44+
cov_storage, repository_token, profiling_identifier, codecov_endpoint, 1
4545
)
4646
span = mocker.MagicMock(to_json=mocker.MagicMock(return_value="{}"))
4747
assert exporter.export([span])

tox.ini

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# content of: tox.ini , put in same dir as setup.py
2+
[tox]
3+
envlist = py36,py37,py38,py39
4+
5+
[testenv]
6+
# install pytest in the virtualenv where commands will be executed
7+
deps =
8+
pytest
9+
responses
10+
pytest-mock==3.6
11+
commands =
12+
# NOTE: you can run any command line tool here - not just tests
13+
pytest

0 commit comments

Comments
 (0)