@@ -45,6 +45,7 @@ def lambda_handler(event, context):
4545The `instrument` method accepts the following keyword args:
4646
4747tracer_provider (TracerProvider) - an optional tracer provider
48+ meter_provider (MeterProvider) - an optional meter provider
4849event_context_extractor (Callable) - a function that returns an OTel Trace
4950Context given the Lambda Event the AWS Lambda was invoked with
5051this function signature is: def event_context_extractor(lambda_event: Any) -> Context
@@ -68,6 +69,7 @@ def custom_event_context_extractor(lambda_event):
6869
6970import logging
7071import os
72+ import time
7173from importlib import import_module
7274from typing import Any , Callable , Collection
7375from urllib .parse import urlencode
@@ -79,6 +81,10 @@ def custom_event_context_extractor(lambda_event):
7981from opentelemetry .instrumentation .aws_lambda .version import __version__
8082from opentelemetry .instrumentation .instrumentor import BaseInstrumentor
8183from opentelemetry .instrumentation .utils import unwrap
84+ from opentelemetry .metrics import (
85+ MeterProvider ,
86+ get_meter_provider ,
87+ )
8288from opentelemetry .propagate import get_global_textmap
8389from opentelemetry .propagators .aws .aws_xray_propagator import (
8490 TRACE_HEADER_KEY ,
@@ -274,6 +280,7 @@ def _instrument(
274280 event_context_extractor : Callable [[Any ], Context ],
275281 tracer_provider : TracerProvider = None ,
276282 disable_aws_context_propagation : bool = False ,
283+ meter_provider : MeterProvider = None ,
277284):
278285 def _instrumented_lambda_handler_call (
279286 call_wrapped , instance , args , kwargs
@@ -352,6 +359,7 @@ def _instrumented_lambda_handler_call(
352359 result .get ("statusCode" ),
353360 )
354361
362+ now = time .time ()
355363 _tracer_provider = tracer_provider or get_tracer_provider ()
356364 try :
357365 # NOTE: `force_flush` before function quit in case of Lambda freeze.
@@ -363,6 +371,19 @@ def _instrumented_lambda_handler_call(
363371 "TracerProvider was missing `force_flush` method. This is necessary in case of a Lambda freeze and would exist in the OTel SDK implementation."
364372 )
365373
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+
366387 return result
367388
368389 wrap_function_wrapper (
@@ -385,6 +406,7 @@ def _instrument(self, **kwargs):
385406 Args:
386407 **kwargs: Optional arguments
387408 ``tracer_provider``: a TracerProvider, defaults to global
409+ ``meter_provider``: a MeterProvider, defaults to global
388410 ``event_context_extractor``: a method which takes the Lambda
389411 Event as input and extracts an OTel Context from it. By default,
390412 the context is extracted from the HTTP headers of an API Gateway
@@ -432,6 +454,7 @@ def _instrument(self, **kwargs):
432454 ),
433455 tracer_provider = kwargs .get ("tracer_provider" ),
434456 disable_aws_context_propagation = disable_aws_context_propagation ,
457+ meter_provider = kwargs .get ("meter_provider" ),
435458 )
436459
437460 def _uninstrument (self , ** kwargs ):
0 commit comments