5
5
import logging
6
6
import os
7
7
from distutils .util import strtobool
8
- from typing import Any , Callable , Dict , List , Tuple
8
+ from typing import Any , Callable , Dict , List , Optional , Tuple
9
9
10
10
import aws_xray_sdk
11
11
import aws_xray_sdk .core
12
12
13
+ from aws_lambda_powertools .shared .constants import TRACER_CAPTURE_ERROR_ENV , TRACER_CAPTURE_RESPONSE_ENV
14
+ from aws_lambda_powertools .shared .functions import resolve_env_var_choice
15
+
13
16
is_cold_start = True
14
17
logger = logging .getLogger (__name__ )
15
18
@@ -233,8 +236,8 @@ def patch(self, modules: Tuple[str] = None):
233
236
def capture_lambda_handler (
234
237
self ,
235
238
lambda_handler : Callable [[Dict , Any ], Any ] = None ,
236
- capture_response : bool = True ,
237
- capture_error : bool = True ,
239
+ capture_response : Optional [ bool ] = None ,
240
+ capture_error : Optional [ bool ] = None ,
238
241
):
239
242
"""Decorator to create subsegment for lambda handlers
240
243
@@ -246,7 +249,7 @@ def capture_lambda_handler(
246
249
lambda_handler : Callable
247
250
Method to annotate on
248
251
capture_response : bool, optional
249
- Instructs tracer to not include handler's response as metadata, by default True
252
+ Instructs tracer to not include handler's response as metadata
250
253
capture_error : bool, optional
251
254
Instructs tracer to not include handler's error as metadata, by default True
252
255
@@ -281,10 +284,8 @@ def handler(event, context):
281
284
282
285
lambda_handler_name = lambda_handler .__name__
283
286
284
- capture_response_env_option = str (os .getenv ("POWERTOOLS_TRACER_CAPTURE_RESPONSE" , "false" ))
285
- capture_error_env_option = str (os .getenv ("POWERTOOLS_TRACER_CAPTURE_ERROR" , "false" ))
286
- capture_response = strtobool (capture_response_env_option ) or capture_response
287
- capture_error = strtobool (capture_error_env_option ) or capture_error
287
+ capture_response = resolve_env_var_choice (env = TRACER_CAPTURE_RESPONSE_ENV , choice = capture_response )
288
+ capture_error = resolve_env_var_choice (env = TRACER_CAPTURE_ERROR_ENV , choice = capture_error )
288
289
289
290
@functools .wraps (lambda_handler )
290
291
def decorate (event , context ):
@@ -316,7 +317,9 @@ def decorate(event, context):
316
317
317
318
return decorate
318
319
319
- def capture_method (self , method : Callable = None , capture_response : bool = True , capture_error : bool = True ):
320
+ def capture_method (
321
+ self , method : Callable = None , capture_response : Optional [bool ] = None , capture_error : Optional [bool ] = None
322
+ ):
320
323
"""Decorator to create subsegment for arbitrary functions
321
324
322
325
It also captures both response and exceptions as metadata
@@ -335,7 +338,7 @@ def capture_method(self, method: Callable = None, capture_response: bool = True,
335
338
method : Callable
336
339
Method to annotate on
337
340
capture_response : bool, optional
338
- Instructs tracer to not include method's response as metadata, by default True
341
+ Instructs tracer to not include method's response as metadata
339
342
capture_error : bool, optional
340
343
Instructs tracer to not include handler's error as metadata, by default True
341
344
@@ -475,28 +478,31 @@ async def async_tasks():
475
478
476
479
method_name = f"{ method .__name__ } "
477
480
481
+ capture_response = resolve_env_var_choice (env = TRACER_CAPTURE_RESPONSE_ENV , choice = capture_response )
482
+ capture_error = resolve_env_var_choice (env = TRACER_CAPTURE_ERROR_ENV , choice = capture_error )
483
+
478
484
if inspect .iscoroutinefunction (method ):
479
485
return self ._decorate_async_function (
480
- method = method , capture_response = capture_response , capture_error = True , method_name = method_name
486
+ method = method , capture_response = capture_response , capture_error = capture_error , method_name = method_name
481
487
)
482
488
elif inspect .isgeneratorfunction (method ):
483
489
return self ._decorate_generator_function (
484
- method = method , capture_response = capture_response , capture_error = True , method_name = method_name
490
+ method = method , capture_response = capture_response , capture_error = capture_error , method_name = method_name
485
491
)
486
492
elif hasattr (method , "__wrapped__" ) and inspect .isgeneratorfunction (method .__wrapped__ ):
487
493
return self ._decorate_generator_function_with_context_manager (
488
- method = method , capture_response = capture_response , capture_error = True , method_name = method_name
494
+ method = method , capture_response = capture_response , capture_error = capture_error , method_name = method_name
489
495
)
490
496
else :
491
497
return self ._decorate_sync_function (
492
- method = method , capture_response = capture_response , capture_error = True , method_name = method_name
498
+ method = method , capture_response = capture_response , capture_error = capture_error , method_name = method_name
493
499
)
494
500
495
501
def _decorate_async_function (
496
502
self ,
497
503
method : Callable = None ,
498
- capture_response : bool = True ,
499
- capture_error : bool = True ,
504
+ capture_response : Optional [ bool ] = None ,
505
+ capture_error : Optional [ bool ] = None ,
500
506
method_name : str = None ,
501
507
):
502
508
@functools .wraps (method )
@@ -522,8 +528,8 @@ async def decorate(*args, **kwargs):
522
528
def _decorate_generator_function (
523
529
self ,
524
530
method : Callable = None ,
525
- capture_response : bool = True ,
526
- capture_error : bool = True ,
531
+ capture_response : Optional [ bool ] = None ,
532
+ capture_error : Optional [ bool ] = None ,
527
533
method_name : str = None ,
528
534
):
529
535
@functools .wraps (method )
@@ -549,8 +555,8 @@ def decorate(*args, **kwargs):
549
555
def _decorate_generator_function_with_context_manager (
550
556
self ,
551
557
method : Callable = None ,
552
- capture_response : bool = True ,
553
- capture_error : bool = True ,
558
+ capture_response : Optional [ bool ] = None ,
559
+ capture_error : Optional [ bool ] = None ,
554
560
method_name : str = None ,
555
561
):
556
562
@functools .wraps (method )
@@ -577,8 +583,8 @@ def decorate(*args, **kwargs):
577
583
def _decorate_sync_function (
578
584
self ,
579
585
method : Callable = None ,
580
- capture_response : bool = True ,
581
- capture_error : bool = True ,
586
+ capture_response : Optional [ bool ] = None ,
587
+ capture_error : Optional [ bool ] = None ,
582
588
method_name : str = None ,
583
589
):
584
590
@functools .wraps (method )
@@ -609,7 +615,7 @@ def _add_response_as_metadata(
609
615
method_name : str = None ,
610
616
data : Any = None ,
611
617
subsegment : aws_xray_sdk .core .models .subsegment = None ,
612
- capture_response : bool = True ,
618
+ capture_response : Optional [ bool ] = None ,
613
619
):
614
620
"""Add response as metadata for given subsegment
615
621
@@ -622,7 +628,7 @@ def _add_response_as_metadata(
622
628
subsegment : aws_xray_sdk.core.models.subsegment, optional
623
629
existing subsegment to add metadata on, by default None
624
630
capture_response : bool, optional
625
- Do not include response as metadata, by default True
631
+ Do not include response as metadata
626
632
"""
627
633
if data is None or not capture_response or subsegment is None :
628
634
return
@@ -634,7 +640,7 @@ def _add_full_exception_as_metadata(
634
640
method_name : str = None ,
635
641
error : Exception = None ,
636
642
subsegment : aws_xray_sdk .core .models .subsegment = None ,
637
- capture_error : bool = True ,
643
+ capture_error : Optional [ bool ] = None ,
638
644
):
639
645
"""Add full exception object as metadata for given subsegment
640
646
@@ -649,7 +655,7 @@ def _add_full_exception_as_metadata(
649
655
capture_error : bool, optional
650
656
Do not include error as metadata, by default True
651
657
"""
652
- if error is None or not capture_error or subsegment is None :
658
+ if not capture_error :
653
659
return
654
660
655
661
subsegment .put_metadata (key = f"{ method_name } error" , value = error , namespace = self ._config ["service" ])
0 commit comments