Skip to content

Commit d8788b6

Browse files
authoredFeb 1, 2023
Flush meter provider at end of lambda function handler (#1613)
* Flush meter provider at end of lambda function handler Signed-off-by: Anthony J Mirabella <a9@aneurysm9.com> * Update `force_flush()` check based on PR feedback Signed-off-by: Anthony J Mirabella <a9@aneurysm9.com> --------- Signed-off-by: Anthony J Mirabella <a9@aneurysm9.com>
1 parent 6ed2c56 commit d8788b6

File tree

2 files changed

+37
-8
lines changed
  • instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda

2 files changed

+37
-8
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
([#1553](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1553))
1414
- `opentelemetry/sdk/extension/aws` Implement [`aws.ecs.*`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/cloud_provider/aws/ecs.md) and [`aws.logs.*`](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/cloud_provider/aws/logs/) resource attributes in the `AwsEcsResourceDetector` detector when the ECS Metadata v4 is available
1515
([#1212](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1212))
16+
- `opentelemetry-instrumentation-aws-lambda` Flush `MeterProvider` at end of function invocation.
17+
([#1613](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1613))
1618
- Fix aiohttp bug with unset `trace_configs` ([#1592](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1592))
1719

1820
### Fixed

‎instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py

+35-8
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def lambda_handler(event, context):
4545
The `instrument` method accepts the following keyword args:
4646
4747
tracer_provider (TracerProvider) - an optional tracer provider
48+
meter_provider (MeterProvider) - an optional meter provider
4849
event_context_extractor (Callable) - a function that returns an OTel Trace
4950
Context given the Lambda Event the AWS Lambda was invoked with
5051
this function signature is: def event_context_extractor(lambda_event: Any) -> Context
@@ -68,6 +69,7 @@ def custom_event_context_extractor(lambda_event):
6869

6970
import logging
7071
import os
72+
import time
7173
from importlib import import_module
7274
from typing import Any, Callable, Collection
7375
from urllib.parse import urlencode
@@ -79,6 +81,10 @@ def custom_event_context_extractor(lambda_event):
7981
from opentelemetry.instrumentation.aws_lambda.version import __version__
8082
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
8183
from opentelemetry.instrumentation.utils import unwrap
84+
from opentelemetry.metrics import (
85+
MeterProvider,
86+
get_meter_provider,
87+
)
8288
from opentelemetry.propagate import get_global_textmap
8389
from 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,15 +359,33 @@ def _instrumented_lambda_handler_call(
352359
result.get("statusCode"),
353360
)
354361

362+
now = time.time()
355363
_tracer_provider = tracer_provider or get_tracer_provider()
356-
try:
357-
# NOTE: `force_flush` before function quit in case of Lambda freeze.
358-
# Assumes we are using the OpenTelemetry SDK implementation of the
359-
# `TracerProvider`.
360-
_tracer_provider.force_flush(flush_timeout)
361-
except Exception: # pylint: disable=broad-except
362-
logger.error(
363-
"TracerProvider was missing `force_flush` method. This is necessary in case of a Lambda freeze and would exist in the OTel SDK implementation."
364+
if hasattr(_tracer_provider, "force_flush"):
365+
try:
366+
# NOTE: `force_flush` before function quit in case of Lambda freeze.
367+
_tracer_provider.force_flush(flush_timeout)
368+
except Exception: # pylint: disable=broad-except
369+
logger.exception(
370+
f"TracerProvider failed to flush traces"
371+
)
372+
else:
373+
logger.warning("TracerProvider was missing `force_flush` method. This is necessary in case of a Lambda freeze and would exist in the OTel SDK implementation.")
374+
375+
_meter_provider = meter_provider or get_meter_provider()
376+
if hasattr(_meter_provider, "force_flush"):
377+
rem = flush_timeout - (time.time()-now)*1000
378+
if rem > 0:
379+
try:
380+
# NOTE: `force_flush` before function quit in case of Lambda freeze.
381+
_meter_provider.force_flush(rem)
382+
except Exception: # pylint: disable=broad-except
383+
logger.exception(
384+
f"MeterProvider failed to flush metrics"
385+
)
386+
else:
387+
logger.warning(
388+
"MeterProvider was missing `force_flush` method. This is necessary in case of a Lambda freeze and would exist in the OTel SDK implementation."
364389
)
365390

366391
return result
@@ -385,6 +410,7 @@ def _instrument(self, **kwargs):
385410
Args:
386411
**kwargs: Optional arguments
387412
``tracer_provider``: a TracerProvider, defaults to global
413+
``meter_provider``: a MeterProvider, defaults to global
388414
``event_context_extractor``: a method which takes the Lambda
389415
Event as input and extracts an OTel Context from it. By default,
390416
the context is extracted from the HTTP headers of an API Gateway
@@ -432,6 +458,7 @@ def _instrument(self, **kwargs):
432458
),
433459
tracer_provider=kwargs.get("tracer_provider"),
434460
disable_aws_context_propagation=disable_aws_context_propagation,
461+
meter_provider=kwargs.get("meter_provider"),
435462
)
436463

437464
def _uninstrument(self, **kwargs):

0 commit comments

Comments
 (0)
Please sign in to comment.