Skip to content

Commit 211c49e

Browse files
codebotenDylanRussell
authored andcommitted
bugfix(exporter): ensure response is closed (open-telemetry#4477)
1 parent 4def4ac commit 211c49e

File tree

4 files changed

+68
-21
lines changed

4 files changed

+68
-21
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- Fix intermittent `Connection aborted` error when using otlp/http exporters
11+
([#4477](https://github.com/open-telemetry/opentelemetry-python/pull/4477))
1012
- opentelemetry-sdk: use stable code attributes: `code.function` -> `code.function.name`, `code.lineno` -> `code.line.number`, `code.filepath` -> `code.file.path`
1113
([#4508](https://github.com/open-telemetry/opentelemetry-python/pull/4508))
1214
- Fix serialization of extended attributes for logs signal

exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from typing import Dict, Optional, Sequence
2222

2323
import requests
24+
from requests.exceptions import ConnectionError
2425

2526
from opentelemetry.exporter.otlp.proto.common._log_encoder import encode_logs
2627
from opentelemetry.exporter.otlp.proto.http import (
@@ -128,13 +129,27 @@ def _export(self, serialized_data: bytes, timeout_sec: float):
128129
elif self._compression == Compression.Deflate:
129130
data = zlib.compress(serialized_data)
130131

131-
return self._session.post(
132-
url=self._endpoint,
133-
data=data,
134-
verify=self._certificate_file,
135-
timeout=timeout_sec,
136-
cert=self._client_cert,
137-
)
132+
# By default, keep-alive is enabled in Session's request
133+
# headers. Backends may choose to close the connection
134+
# while a post happens which causes an unhandled
135+
# exception. This try/except will retry the post on such exceptions
136+
try:
137+
resp = self._session.post(
138+
url=self._endpoint,
139+
data=data,
140+
verify=self._certificate_file,
141+
timeout=timeout_sec
142+
cert=self._client_cert,
143+
)
144+
except ConnectionError:
145+
resp = self._session.post(
146+
url=self._endpoint,
147+
data=data,
148+
verify=self._certificate_file,
149+
timeout=timeout_sec
150+
cert=self._client_cert,
151+
)
152+
return resp
138153

139154
@staticmethod
140155
def _retryable(resp: requests.Response) -> bool:

exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import requests
3232
from deprecated import deprecated
33+
from requests.exceptions import ConnectionError
3334

3435
from opentelemetry.exporter.otlp.proto.common._internal import (
3536
_get_resource_data,
@@ -173,13 +174,27 @@ def _export(self, serialized_data: bytes, timeout_sec: float):
173174
elif self._compression == Compression.Deflate:
174175
data = zlib.compress(serialized_data)
175176

176-
return self._session.post(
177-
url=self._endpoint,
178-
data=data,
179-
verify=self._certificate_file,
180-
timeout=timeout_sec,
181-
cert=self._client_cert,
182-
)
177+
# By default, keep-alive is enabled in Session's request
178+
# headers. Backends may choose to close the connection
179+
# while a post happens which causes an unhandled
180+
# exception. This try/except will retry the post on such exceptions
181+
try:
182+
resp = self._session.post(
183+
url=self._endpoint,
184+
data=data,
185+
verify=self._certificate_file,
186+
timeout=timeout_sec,
187+
cert=self._client_cert,
188+
)
189+
except ConnectionError:
190+
resp = self._session.post(
191+
url=self._endpoint,
192+
data=data,
193+
verify=self._certificate_file,
194+
timeout=timeout_sec,
195+
cert=self._client_cert,
196+
)
197+
return resp
183198

184199
@staticmethod
185200
def _retryable(resp: requests.Response) -> bool:

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

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from typing import Dict, Optional, Sequence
2222

2323
import requests
24+
from requests.exceptions import ConnectionError
2425

2526
from opentelemetry.exporter.otlp.proto.common.trace_encoder import (
2627
encode_spans,
@@ -126,13 +127,27 @@ def _export(self, serialized_data: bytes, timeout_sec: float):
126127
elif self._compression == Compression.Deflate:
127128
data = zlib.compress(serialized_data)
128129

129-
return self._session.post(
130-
url=self._endpoint,
131-
data=data,
132-
verify=self._certificate_file,
133-
timeout=timeout_sec,
134-
cert=self._client_cert,
135-
)
130+
# By default, keep-alive is enabled in Session's request
131+
# headers. Backends may choose to close the connection
132+
# while a post happens which causes an unhandled
133+
# exception. This try/except will retry the post on such exceptions
134+
try:
135+
resp = self._session.post(
136+
url=self._endpoint,
137+
data=data,
138+
verify=self._certificate_file,
139+
timeout=timeout_sec,
140+
cert=self._client_cert,
141+
)
142+
except ConnectionError:
143+
resp = self._session.post(
144+
url=self._endpoint,
145+
data=data,
146+
verify=self._certificate_file,
147+
timeout=timeout_sec,
148+
cert=self._client_cert,
149+
)
150+
return resp
136151

137152
@staticmethod
138153
def _retryable(resp: requests.Response) -> bool:

0 commit comments

Comments
 (0)