1
+ import copy
1
2
import functools
2
3
import logging
3
4
import os
6
7
7
8
from aws_xray_sdk .core import models , patch_all , xray_recorder
8
9
9
- from ..helper .register import RegisterMeta
10
-
11
10
is_cold_start = True
12
11
logger = logging .getLogger (__name__ )
13
12
logger .setLevel (os .getenv ("LOG_LEVEL" , "INFO" ))
14
13
15
14
16
- class Tracer ( metaclass = RegisterMeta ) :
15
+ class Tracer :
17
16
"""Tracer using AWS-XRay to provide decorators with known defaults for Lambda functions
18
17
19
- When running locally, it honours `POWERTOOLS_TRACE_DISABLED` environment variable
20
- so end user code doesn't have to be modified to run it locally
21
- instead Tracer returns dummy segments/subsegments.
22
-
23
- Tracing is automatically disabled when running locally via via SAM CLI.
18
+ When running locally, it detects whether it's running via SAM CLI,
19
+ and if it is it returns dummy segments/subsegments instead.
24
20
25
- By default, it patches all available libraries supported by X-Ray SDK. \n
21
+ By default, it patches all available libraries supported by X-Ray SDK. Patching is
22
+ automatically disabled when running locally via SAM CLI or by any other means. \n
26
23
Ref: https://docs.aws.amazon.com/xray-sdk-for-python/latest/reference/thirdparty.html
27
24
25
+ Tracer keeps a copy of its configuration as it can be instantiated more than once. This
26
+ is useful when you are using your own middlewares and want to utilize an existing Tracer.
27
+ Make sure to set `auto_patch=False` in subsequent Tracer instances to avoid double patching.
28
+
28
29
Environment variables
29
30
---------------------
30
31
POWERTOOLS_TRACE_DISABLED : str
@@ -39,7 +40,7 @@ class Tracer(metaclass=RegisterMeta):
39
40
auto_patch: bool
40
41
Patch existing imported modules during initialization, by default True
41
42
disabled: bool
42
- Flag to explicitly disable tracing, useful when running locally.
43
+ Flag to explicitly disable tracing, useful when running/testing locally.
43
44
`Env POWERTOOLS_TRACE_DISABLED="true"`
44
45
45
46
Example
@@ -105,7 +106,7 @@ def handler(event: dict, context: Any) -> Dict:
105
106
106
107
# utils.py
107
108
from aws_lambda_powertools.tracing import Tracer
108
- tracer = Tracer.instance ()
109
+ tracer = Tracer()
109
110
...
110
111
111
112
Returns
@@ -119,22 +120,22 @@ def handler(event: dict, context: Any) -> Dict:
119
120
120
121
"""
121
122
123
+ _default_config = {"service" : "service_undefined" , "disabled" : False , "provider" : xray_recorder , "auto_patch" : True }
124
+ _config = copy .copy (_default_config )
125
+
122
126
def __init__ (
123
- self ,
124
- service : str = "service_undefined" ,
125
- disabled : bool = False ,
126
- provider : xray_recorder = xray_recorder ,
127
- auto_patch : bool = True ,
127
+ self , service : str = None , disabled : bool = None , provider : xray_recorder = None , auto_patch : bool = None
128
128
):
129
- self .provider = provider
130
- self .disabled = self .__is_trace_disabled () or disabled
131
- self .service = os .getenv ("POWERTOOLS_SERVICE_NAME" ) or service
132
- self .auto_patch = auto_patch
129
+ self .__build_config (service = service , disabled = disabled , provider = provider , auto_patch = auto_patch )
130
+ self .provider = self ._config ["provider" ]
131
+ self .disabled = self ._config ["disabled" ]
132
+ self .service = self ._config ["service" ]
133
+ self .auto_patch = self ._config ["auto_patch" ]
133
134
134
135
if self .disabled :
135
136
self .__disable_tracing_provider ()
136
137
137
- if auto_patch :
138
+ if self . auto_patch :
138
139
self .patch ()
139
140
140
141
def capture_lambda_handler (self , lambda_handler : Callable [[Dict , Any ], Any ] = None ):
@@ -340,18 +341,17 @@ def end_subsegment(self):
340
341
self .provider .end_subsegment ()
341
342
342
343
def patch (self ):
343
- """Patch modules for instrumentation
344
- """
344
+ """Patch modules for instrumentation"""
345
345
logger .debug ("Patching modules..." )
346
346
347
- is_lambda_emulator = os .getenv ("AWS_SAM_LOCAL" )
348
- is_lambda_env = os .getenv ("LAMBDA_TASK_ROOT" )
347
+ is_lambda_emulator = os .getenv ("AWS_SAM_LOCAL" , False )
348
+ is_lambda_env = os .getenv ("LAMBDA_TASK_ROOT" , False )
349
349
350
350
if self .disabled :
351
351
logger .debug ("Tracing has been disabled, aborting patch" )
352
352
return
353
353
354
- if is_lambda_emulator or not is_lambda_env :
354
+ if is_lambda_emulator or is_lambda_env :
355
355
logger .debug ("Running under SAM CLI env or not in Lambda; aborting patch" )
356
356
return
357
357
@@ -390,3 +390,19 @@ def __is_trace_disabled(self) -> bool:
390
390
return is_lambda_emulator
391
391
392
392
return False
393
+
394
+ def __build_config (
395
+ self , service : str = None , disabled : bool = None , provider : xray_recorder = None , auto_patch : bool = None
396
+ ):
397
+ """ Populates Tracer config for new and existing initializations """
398
+ is_disabled = disabled if disabled is not None else self .__is_trace_disabled ()
399
+ is_service = service if service is not None else os .getenv ("POWERTOOLS_SERVICE_NAME" )
400
+
401
+ self ._config ["provider" ] = provider if provider is not None else self ._config ["provider" ]
402
+ self ._config ["auto_patch" ] = auto_patch if auto_patch is not None else self ._config ["auto_patch" ]
403
+ self ._config ["service" ] = is_service if is_service else self ._config ["service" ]
404
+ self ._config ["disabled" ] = is_disabled if is_disabled else self ._config ["disabled" ]
405
+
406
+ @classmethod
407
+ def _reset_config (cls ):
408
+ cls ._config = copy .copy (cls ._default_config )
0 commit comments