17
17
from abc import ABC , abstractmethod
18
18
from enum import Enum
19
19
from os import environ , linesep
20
+ from socket import timeout
20
21
from sys import stdout
21
22
from threading import Event , RLock , Thread
22
23
from typing import IO , Callable , Dict , Iterable , List , Optional , Sequence
31
32
from opentelemetry .sdk ._metrics .metric_reader import MetricReader
32
33
from opentelemetry .sdk ._metrics .point import AggregationTemporality , Metric
33
34
from opentelemetry .util ._once import Once
35
+ from opentelemetry .util ._time import time_ns
34
36
35
37
_logger = logging .getLogger (__name__ )
36
38
@@ -53,8 +55,11 @@ class MetricExporter(ABC):
53
55
54
56
@abstractmethod
55
57
def export (
56
- self , metrics : Sequence [Metric ], * args , ** kwargs
57
- ) -> "MetricExportResult" :
58
+ self ,
59
+ metrics : Sequence [Metric ],
60
+ timeout_millis : float = 10_000 ,
61
+ ** kwargs ,
62
+ ) -> MetricExportResult :
58
63
"""Exports a batch of telemetry data.
59
64
60
65
Args:
@@ -65,7 +70,7 @@ def export(
65
70
"""
66
71
67
72
@abstractmethod
68
- def shutdown (self , * args , ** kwargs ) -> None :
73
+ def shutdown (self , timeout_millis : float = 10_000 , ** kwargs ) -> None :
69
74
"""Shuts down the exporter.
70
75
71
76
Called when the SDK is shut down.
@@ -90,14 +95,17 @@ def __init__(
90
95
self .formatter = formatter
91
96
92
97
def export (
93
- self , metrics : Sequence [Metric ], * args , ** kwargs
98
+ self ,
99
+ metrics : Sequence [Metric ],
100
+ timeout_millis : float = 10_000 ,
101
+ ** kwargs ,
94
102
) -> MetricExportResult :
95
103
for metric in metrics :
96
104
self .out .write (self .formatter (metric ))
97
105
self .out .flush ()
98
106
return MetricExportResult .SUCCESS
99
107
100
- def shutdown (self , * args , ** kwargs ) -> None :
108
+ def shutdown (self , timeout_millis : float = 10_000 , ** kwargs ) -> None :
101
109
pass
102
110
103
111
@@ -127,11 +135,16 @@ def get_metrics(self) -> List[Metric]:
127
135
self ._metrics = []
128
136
return metrics
129
137
130
- def _receive_metrics (self , metrics : Iterable [Metric ], * args , ** kwargs ):
138
+ def _receive_metrics (
139
+ self ,
140
+ metrics : Iterable [Metric ],
141
+ timeout_millis : float = 10_000 ,
142
+ ** kwargs ,
143
+ ) -> None :
131
144
with self ._lock :
132
145
self ._metrics = list (metrics )
133
146
134
- def shutdown (self , * args , ** kwargs ):
147
+ def shutdown (self , timeout_millis : float = 10_000 , ** kwargs ) -> None :
135
148
pass
136
149
137
150
@@ -193,23 +206,28 @@ def _at_fork_reinit(self):
193
206
def _ticker (self ) -> None :
194
207
interval_secs = self ._export_interval_millis / 1e3
195
208
while not self ._shutdown_event .wait (interval_secs ):
196
- self .collect ()
209
+ self .collect (timeout_millis = self . _export_timeout_millis )
197
210
# one last collection below before shutting down completely
198
- self .collect ()
211
+ self .collect (timeout_millis = self . _export_interval_millis )
199
212
200
213
def _receive_metrics (
201
- self , metrics : Iterable [Metric ], * args , ** kwargs
214
+ self ,
215
+ metrics : Iterable [Metric ],
216
+ timeout_millis : float = 10_000 ,
217
+ ** kwargs ,
202
218
) -> None :
203
219
if metrics is None :
204
220
return
205
221
token = attach (set_value (_SUPPRESS_INSTRUMENTATION_KEY , True ))
206
222
try :
207
- self ._exporter .export (metrics )
223
+ self ._exporter .export (metrics , timeout_millis = timeout_millis )
208
224
except Exception as e : # pylint: disable=broad-except,invalid-name
209
225
_logger .exception ("Exception while exporting metrics %s" , str (e ))
210
226
detach (token )
211
227
212
- def shutdown (self , * args , ** kwargs ):
228
+ def shutdown (self , timeout_millis : float = 10_000 , ** kwargs ) -> None :
229
+ deadline_ns = time_ns () + timeout_millis * 10 ** 6
230
+
213
231
def _shutdown ():
214
232
self ._shutdown = True
215
233
@@ -219,5 +237,5 @@ def _shutdown():
219
237
return
220
238
221
239
self ._shutdown_event .set ()
222
- self ._daemon_thread .join ()
223
- self ._exporter .shutdown ()
240
+ self ._daemon_thread .join (timeout = ( deadline_ns - time_ns ()) / 10 ** 9 )
241
+ self ._exporter .shutdown (timeout = ( deadline_ns - time_ns ()) / 10 ** 6 )
0 commit comments