31
31
from opentelemetry .sdk ._metrics .metric_reader import MetricReader
32
32
from opentelemetry .sdk ._metrics .point import AggregationTemporality , Metric
33
33
from opentelemetry .util ._once import Once
34
+ from opentelemetry .util ._time import time_ns
34
35
35
36
_logger = logging .getLogger (__name__ )
36
37
@@ -52,7 +53,12 @@ class MetricExporter(ABC):
52
53
"""
53
54
54
55
@abstractmethod
55
- def export (self , metrics : Sequence [Metric ]) -> "MetricExportResult" :
56
+ def export (
57
+ self ,
58
+ metrics : Sequence [Metric ],
59
+ timeout_millis : Optional [float ] = None ,
60
+ ** kwargs
61
+ ) -> "MetricExportResult" :
56
62
"""Exports a batch of telemetry data.
57
63
58
64
Args:
@@ -63,7 +69,9 @@ def export(self, metrics: Sequence[Metric]) -> "MetricExportResult":
63
69
"""
64
70
65
71
@abstractmethod
66
- def shutdown (self ) -> None :
72
+ def shutdown (
73
+ self , timeout_millis : Optional [float ] = None , ** kwargs
74
+ ) -> None :
67
75
"""Shuts down the exporter.
68
76
69
77
Called when the SDK is shut down.
@@ -87,13 +95,15 @@ def __init__(
87
95
self .out = out
88
96
self .formatter = formatter
89
97
90
- def export (self , metrics : Sequence [Metric ]) -> MetricExportResult :
98
+ def export (
99
+ self , metrics : Sequence [Metric ], * args , ** kwargs
100
+ ) -> MetricExportResult :
91
101
for metric in metrics :
92
102
self .out .write (self .formatter (metric ))
93
103
self .out .flush ()
94
104
return MetricExportResult .SUCCESS
95
105
96
- def shutdown (self ) -> None :
106
+ def shutdown (self , * args , ** kwargs ) -> None :
97
107
pass
98
108
99
109
@@ -127,7 +137,7 @@ def _receive_metrics(self, metrics: Iterable[Metric]):
127
137
with self ._lock :
128
138
self ._metrics = list (metrics )
129
139
130
- def shutdown (self ):
140
+ def shutdown (self , ** kwargs ):
131
141
pass
132
142
133
143
@@ -198,12 +208,20 @@ def _receive_metrics(self, metrics: Iterable[Metric]) -> None:
198
208
return
199
209
token = attach (set_value (_SUPPRESS_INSTRUMENTATION_KEY , True ))
200
210
try :
201
- self ._exporter .export (metrics )
211
+ self ._exporter .export (
212
+ metrics , timeout_millis = self ._export_timeout_millis
213
+ )
202
214
except Exception as e : # pylint: disable=broad-except,invalid-name
203
215
_logger .exception ("Exception while exporting metrics %s" , str (e ))
204
216
detach (token )
205
217
206
- def shutdown (self ):
218
+ def shutdown (
219
+ self , timeout_millis : Optional [float ] = None , ** kwargs
220
+ ) -> None :
221
+ if timeout_millis is None :
222
+ timeout_millis = self ._export_timeout_millis
223
+ deadline_nanos = time_ns () + timeout_millis * 10 ** 3
224
+
207
225
def _shutdown ():
208
226
self ._shutdown = True
209
227
@@ -213,5 +231,5 @@ def _shutdown():
213
231
return
214
232
215
233
self ._shutdown_event .set ()
216
- self ._daemon_thread .join ()
217
- self ._exporter .shutdown ()
234
+ self ._daemon_thread .join (( deadline_nanos - time_ns ()) / 10 ** 9 )
235
+ self ._exporter .shutdown (( deadline_nanos - time_ns ()) / 10 ** 9 )
0 commit comments