@@ -45,6 +45,7 @@ def lambda_handler(event, context):
45
45
The `instrument` method accepts the following keyword args:
46
46
47
47
tracer_provider (TracerProvider) - an optional tracer provider
48
+ meter_provider (MeterProvider) - an optional meter provider
48
49
event_context_extractor (Callable) - a function that returns an OTel Trace
49
50
Context given the Lambda Event the AWS Lambda was invoked with
50
51
this function signature is: def event_context_extractor(lambda_event: Any) -> Context
@@ -68,6 +69,7 @@ def custom_event_context_extractor(lambda_event):
68
69
69
70
import logging
70
71
import os
72
+ import time
71
73
from importlib import import_module
72
74
from typing import Any , Callable , Collection
73
75
from urllib .parse import urlencode
@@ -79,6 +81,10 @@ def custom_event_context_extractor(lambda_event):
79
81
from opentelemetry .instrumentation .aws_lambda .version import __version__
80
82
from opentelemetry .instrumentation .instrumentor import BaseInstrumentor
81
83
from opentelemetry .instrumentation .utils import unwrap
84
+ from opentelemetry .metrics import (
85
+ MeterProvider ,
86
+ get_meter_provider ,
87
+ )
82
88
from opentelemetry .propagate import get_global_textmap
83
89
from opentelemetry .propagators .aws .aws_xray_propagator import (
84
90
TRACE_HEADER_KEY ,
@@ -274,6 +280,7 @@ def _instrument(
274
280
event_context_extractor : Callable [[Any ], Context ],
275
281
tracer_provider : TracerProvider = None ,
276
282
disable_aws_context_propagation : bool = False ,
283
+ meter_provider : MeterProvider = None ,
277
284
):
278
285
def _instrumented_lambda_handler_call (
279
286
call_wrapped , instance , args , kwargs
@@ -352,6 +359,7 @@ def _instrumented_lambda_handler_call(
352
359
result .get ("statusCode" ),
353
360
)
354
361
362
+ now = time .time ()
355
363
_tracer_provider = tracer_provider or get_tracer_provider ()
356
364
try :
357
365
# NOTE: `force_flush` before function quit in case of Lambda freeze.
@@ -363,6 +371,19 @@ def _instrumented_lambda_handler_call(
363
371
"TracerProvider was missing `force_flush` method. This is necessary in case of a Lambda freeze and would exist in the OTel SDK implementation."
364
372
)
365
373
374
+ rem = flush_timeout - (time .time ()- now )* 1000
375
+ if rem > 0 :
376
+ _meter_provider = meter_provider or get_meter_provider ()
377
+ try :
378
+ # NOTE: `force_flush` before function quit in case of Lambda freeze.
379
+ # Assumes we are using the OpenTelemetry SDK implementation of the
380
+ # `MeterProvider`.
381
+ _meter_provider .force_flush (rem )
382
+ except Exception : # pylint: disable=broad-except
383
+ logger .error (
384
+ "MeterProvider was missing `force_flush` method. This is necessary in case of a Lambda freeze and would exist in the OTel SDK implementation."
385
+ )
386
+
366
387
return result
367
388
368
389
wrap_function_wrapper (
@@ -385,6 +406,7 @@ def _instrument(self, **kwargs):
385
406
Args:
386
407
**kwargs: Optional arguments
387
408
``tracer_provider``: a TracerProvider, defaults to global
409
+ ``meter_provider``: a MeterProvider, defaults to global
388
410
``event_context_extractor``: a method which takes the Lambda
389
411
Event as input and extracts an OTel Context from it. By default,
390
412
the context is extracted from the HTTP headers of an API Gateway
@@ -432,6 +454,7 @@ def _instrument(self, **kwargs):
432
454
),
433
455
tracer_provider = kwargs .get ("tracer_provider" ),
434
456
disable_aws_context_propagation = disable_aws_context_propagation ,
457
+ meter_provider = kwargs .get ("meter_provider" ),
435
458
)
436
459
437
460
def _uninstrument (self , ** kwargs ):
0 commit comments