Skip to content

Commit d748c12

Browse files
Extract helper _export_with_retries
1 parent 4dff26d commit d748c12

File tree

1 file changed

+53
-59
lines changed
  • exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter

1 file changed

+53
-59
lines changed

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

Lines changed: 53 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,48 @@ def _export(self, serialized_data: bytes, timeout_sec: float):
226226
)
227227
return resp
228228

229+
def _export_with_retries(
230+
self,
231+
serialized_data: bytes,
232+
deadline_sec: float,
233+
) -> MetricExportResult:
234+
"""Export serialized data with retry logic until success, non-transient error, or exponential backoff maxed out.
235+
236+
Args:
237+
serialized_data: serialized metrics data to export
238+
deadline_sec: timestamp deadline for the export
239+
240+
Returns:
241+
MetricExportResult: SUCCESS if export succeeded, FAILURE otherwise
242+
"""
243+
for retry_num in range(_MAX_RETRYS):
244+
resp = self._export(serialized_data, deadline_sec - time())
245+
if resp.ok:
246+
return MetricExportResult.SUCCESS
247+
248+
# multiplying by a random number between .8 and 1.2 introduces a +/20% jitter to each backoff.
249+
backoff_seconds = 2**retry_num * random.uniform(0.8, 1.2)
250+
if (
251+
not _is_retryable(resp)
252+
or retry_num + 1 == _MAX_RETRYS
253+
or backoff_seconds > (deadline_sec - time())
254+
):
255+
_logger.error(
256+
"Failed to export metrics batch code: %s, reason: %s",
257+
resp.status_code,
258+
resp.text,
259+
)
260+
return MetricExportResult.FAILURE
261+
262+
_logger.warning(
263+
"Transient error %s encountered while exporting metrics batch, retrying in %.2fs.",
264+
resp.reason,
265+
backoff_seconds,
266+
)
267+
sleep(backoff_seconds)
268+
269+
return MetricExportResult.FAILURE
270+
229271
def export(
230272
self,
231273
metrics_data: MetricsData,
@@ -241,71 +283,23 @@ def export(
241283

242284
# If no batch size configured, export as single batch with retries as configured
243285
if self._max_export_batch_size is None:
244-
for retry_num in range(_MAX_RETRYS):
245-
resp = self._export(
246-
serialized_data.SerializeToString(), deadline_sec - time()
247-
)
248-
if resp.ok:
249-
return MetricExportResult.SUCCESS
250-
# multiplying by a random number between .8 and 1.2 introduces a +/20% jitter to each backoff.
251-
backoff_seconds = 2**retry_num * random.uniform(0.8, 1.2)
252-
if (
253-
not _is_retryable(resp)
254-
or retry_num + 1 == _MAX_RETRYS
255-
or backoff_seconds > (deadline_sec - time())
256-
):
257-
_logger.error(
258-
"Failed to export metrics batch code: %s, reason: %s",
259-
resp.status_code,
260-
resp.text,
261-
)
262-
return MetricExportResult.FAILURE
263-
_logger.warning(
264-
"Transient error %s encountered while exporting metrics batch, retrying in %.2fs.",
265-
resp.reason,
266-
backoff_seconds,
267-
)
268-
sleep(backoff_seconds)
286+
return self._export_with_retries(
287+
serialized_data.SerializeToString(), deadline_sec
288+
)
269289

270290
# Else, export in batches of configured size
271291
split_metrics_batches = list(self._split_metrics_data(serialized_data))
272292
export_result = MetricExportResult.SUCCESS
273293

274294
for split_metrics_data in split_metrics_batches:
275-
# Export current batch until success, non-transient error, or retries maxed out
276-
for retry_num in range(_MAX_RETRYS):
277-
split_resp = self._export(
278-
split_metrics_data.SerializeToString(),
279-
deadline_sec - time(),
280-
)
281-
if split_resp.ok:
282-
export_result = MetricExportResult.SUCCESS
283-
# Move on to next batch
284-
break
285-
286-
# multiplying by a random number between .8 and 1.2 introduces a +/20% jitter to each backoff.
287-
backoff_seconds = 2**retry_num * random.uniform(0.8, 1.2)
288-
if (
289-
not _is_retryable(split_resp)
290-
or retry_num + 1 == _MAX_RETRYS
291-
or backoff_seconds > (deadline_sec - time())
292-
):
293-
_logger.error(
294-
"Failed to export metrics batch code: %s, reason: %s",
295-
split_resp.status_code,
296-
split_resp.text,
297-
)
298-
export_result = MetricExportResult.FAILURE
299-
# Don't retry; move on to next batch
300-
break
301-
302-
_logger.warning(
303-
"Transient error %s encountered while exporting metric batch, retrying in %.2fs.",
304-
split_resp.reason,
305-
backoff_seconds,
306-
)
307-
sleep(backoff_seconds)
308-
continue
295+
batch_result = self._export_with_retries(
296+
split_metrics_data.SerializeToString(),
297+
deadline_sec,
298+
)
299+
300+
if batch_result == MetricExportResult.FAILURE:
301+
export_result = MetricExportResult.FAILURE
302+
# Don't retry; move on to next batch
309303

310304
# Return last result after all batches are attempted
311305
return export_result

0 commit comments

Comments
 (0)