Skip to content

Commit eb7125d

Browse files
author
alrex
authored
Pass OTLP metadata as tuple instead of string (#1507)
1 parent ff1a058 commit eb7125d

File tree

6 files changed

+72
-7
lines changed

6 files changed

+72
-7
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4141
([#1486](https://github.com/open-telemetry/opentelemetry-python/pull/1486))
4242
- Recreate span on every run of a `start_as_current_span`-decorated function
4343
([#1451](https://github.com/open-telemetry/opentelemetry-python/pull/1451))
44+
- `opentelemetry-exporter-otlp` Headers are now passed in as tuple as metadata, instead of a
45+
string, which was incorrect.
46+
([#1507](https://github.com/open-telemetry/opentelemetry-python/pull/1507))
4447

4548
## [0.16b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.16b1) - 2020-11-26
4649
### Added

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def __init__(
151151
endpoint: Optional[str] = None,
152152
insecure: Optional[bool] = None,
153153
credentials: Optional[ChannelCredentials] = None,
154-
headers: Optional[str] = None,
154+
headers: Optional[Sequence] = None,
155155
timeout: Optional[int] = None,
156156
compression: str = None,
157157
):
@@ -169,6 +169,10 @@ def __init__(
169169
insecure = False
170170

171171
self._headers = headers or Configuration().EXPORTER_OTLP_HEADERS
172+
if isinstance(self._headers, str):
173+
self._headers = tuple(
174+
tuple(item.split("=")) for item in self._headers.split(",")
175+
)
172176
self._timeout = (
173177
timeout
174178
or Configuration().EXPORTER_OTLP_TIMEOUT

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def __init__(
139139
endpoint: Optional[str] = None,
140140
insecure: Optional[bool] = None,
141141
credentials: Optional[ChannelCredentials] = None,
142-
headers: Optional[str] = None,
142+
headers: Optional[Sequence] = None,
143143
timeout: Optional[int] = None,
144144
):
145145
if insecure is None:

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def __init__(
6969
endpoint: Optional[str] = None,
7070
insecure: Optional[bool] = None,
7171
credentials: Optional[ChannelCredentials] = None,
72-
headers: Optional[str] = None,
72+
headers: Optional[Sequence] = None,
7373
timeout: Optional[int] = None,
7474
):
7575
if insecure is None:

exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py

+31-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def tearDown(self):
7373
"OTEL_EXPORTER_OTLP_METRIC_ENDPOINT": "collector:55680",
7474
"OTEL_EXPORTER_OTLP_METRIC_CERTIFICATE": THIS_DIR
7575
+ "/fixtures/test.cert",
76-
"OTEL_EXPORTER_OTLP_METRIC_HEADERS": "key1:value1;key2:value2",
76+
"OTEL_EXPORTER_OTLP_METRIC_HEADERS": "key1=value1,key2=value2",
7777
"OTEL_EXPORTER_OTLP_METRIC_TIMEOUT": "10",
7878
},
7979
)
@@ -85,7 +85,7 @@ def test_env_variables(self, mock_exporter_mixin):
8585
_, kwargs = mock_exporter_mixin.call_args_list[0]
8686

8787
self.assertEqual(kwargs["endpoint"], "collector:55680")
88-
self.assertEqual(kwargs["headers"], "key1:value1;key2:value2")
88+
self.assertEqual(kwargs["headers"], "key1=value1,key2=value2")
8989
self.assertEqual(kwargs["timeout"], 10)
9090
self.assertIsNotNone(kwargs["credentials"])
9191
self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
@@ -102,6 +102,35 @@ def test_no_credentials_error(
102102
OTLPMetricsExporter(insecure=False)
103103
self.assertTrue(mock_ssl_channel.called)
104104

105+
@patch.dict(
106+
"os.environ",
107+
{"OTEL_EXPORTER_OTLP_METRIC_HEADERS": "key1=value1,key2=value2"},
108+
)
109+
@patch("opentelemetry.exporter.otlp.exporter.ssl_channel_credentials")
110+
@patch("opentelemetry.exporter.otlp.exporter.secure_channel")
111+
# pylint: disable=unused-argument
112+
def test_otlp_headers_from_env(self, mock_ssl_channel, mock_secure):
113+
exporter = OTLPMetricsExporter()
114+
# pylint: disable=protected-access
115+
self.assertEqual(
116+
exporter._headers, (("key1", "value1"), ("key2", "value2")),
117+
)
118+
exporter = OTLPMetricsExporter(
119+
headers=(("key3", "value3"), ("key4", "value4"))
120+
)
121+
# pylint: disable=protected-access
122+
self.assertEqual(
123+
exporter._headers, (("key3", "value3"), ("key4", "value4")),
124+
)
125+
126+
@patch("opentelemetry.exporter.otlp.exporter.ssl_channel_credentials")
127+
@patch("opentelemetry.exporter.otlp.exporter.secure_channel")
128+
# pylint: disable=unused-argument
129+
def test_otlp_headers(self, mock_ssl_channel, mock_secure):
130+
exporter = OTLPMetricsExporter()
131+
# pylint: disable=protected-access
132+
self.assertIsNone(exporter._headers, None)
133+
105134
@patch("opentelemetry.sdk.metrics.export.aggregate.time_ns")
106135
def test_translate_counter_export_record(self, mock_time_ns):
107136
mock_time_ns.configure_mock(**{"return_value": 1})

exporter/opentelemetry-exporter-otlp/tests/test_otlp_trace_exporter.py

+31-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def tearDown(self):
172172
"OTEL_EXPORTER_OTLP_SPAN_ENDPOINT": "collector:55680",
173173
"OTEL_EXPORTER_OTLP_SPAN_CERTIFICATE": THIS_DIR
174174
+ "/fixtures/test.cert",
175-
"OTEL_EXPORTER_OTLP_SPAN_HEADERS": "key1:value1;key2:value2",
175+
"OTEL_EXPORTER_OTLP_SPAN_HEADERS": "key1=value1,key2=value2",
176176
"OTEL_EXPORTER_OTLP_SPAN_TIMEOUT": "10",
177177
},
178178
)
@@ -184,7 +184,7 @@ def test_env_variables(self, mock_exporter_mixin):
184184
_, kwargs = mock_exporter_mixin.call_args_list[0]
185185

186186
self.assertEqual(kwargs["endpoint"], "collector:55680")
187-
self.assertEqual(kwargs["headers"], "key1:value1;key2:value2")
187+
self.assertEqual(kwargs["headers"], "key1=value1,key2=value2")
188188
self.assertEqual(kwargs["timeout"], 10)
189189
self.assertIsNotNone(kwargs["credentials"])
190190
self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
@@ -199,6 +199,35 @@ def test_no_credentials_error(
199199
OTLPSpanExporter(insecure=False)
200200
self.assertTrue(mock_ssl_channel.called)
201201

202+
@patch.dict(
203+
"os.environ",
204+
{"OTEL_EXPORTER_OTLP_SPAN_HEADERS": "key1=value1,key2=value2"},
205+
)
206+
@patch("opentelemetry.exporter.otlp.exporter.ssl_channel_credentials")
207+
@patch("opentelemetry.exporter.otlp.exporter.secure_channel")
208+
# pylint: disable=unused-argument
209+
def test_otlp_headers_from_env(self, mock_ssl_channel, mock_secure):
210+
exporter = OTLPSpanExporter()
211+
# pylint: disable=protected-access
212+
self.assertEqual(
213+
exporter._headers, (("key1", "value1"), ("key2", "value2"))
214+
)
215+
exporter = OTLPSpanExporter(
216+
headers=(("key3", "value3"), ("key4", "value4"))
217+
)
218+
# pylint: disable=protected-access
219+
self.assertEqual(
220+
exporter._headers, (("key3", "value3"), ("key4", "value4"))
221+
)
222+
223+
@patch("opentelemetry.exporter.otlp.exporter.ssl_channel_credentials")
224+
@patch("opentelemetry.exporter.otlp.exporter.secure_channel")
225+
# pylint: disable=unused-argument
226+
def test_otlp_headers(self, mock_ssl_channel, mock_secure):
227+
exporter = OTLPSpanExporter()
228+
# pylint: disable=protected-access
229+
self.assertIsNone(exporter._headers, None)
230+
202231
@patch("opentelemetry.exporter.otlp.exporter.expo")
203232
@patch("opentelemetry.exporter.otlp.exporter.sleep")
204233
def test_unavailable(self, mock_sleep, mock_expo):

0 commit comments

Comments
 (0)