2
2
import itertools
3
3
import logging
4
4
import os
5
+ import random
5
6
from distutils .util import strtobool
6
7
from typing import Any , Callable , Dict
7
8
8
- from . import aws_lambda_logging
9
9
from ..helper .models import MetricUnit , build_lambda_context_model , build_metric_unit_from_str
10
+ from . import aws_lambda_logging
10
11
11
12
logger = logging .getLogger (__name__ )
12
13
logger .setLevel (os .getenv ("LOG_LEVEL" , "INFO" ))
13
14
14
15
is_cold_start = True
15
16
16
17
17
- def logger_setup (service : str = "service_undefined" , level : str = "INFO" , ** kwargs ):
18
+ def logger_setup (
19
+ service : str = "service_undefined" , level : str = "INFO" , sampling_rate : float = 0.0 , ** kwargs
20
+ ):
18
21
"""Setups root logger to format statements in JSON.
19
22
20
23
Includes service name and any additional key=value into logs
@@ -26,13 +29,17 @@ def logger_setup(service: str = "service_undefined", level: str = "INFO", **kwar
26
29
service name
27
30
LOG_LEVEL: str
28
31
logging level (e.g. INFO, DEBUG)
32
+ POWERTOOLS_SAMPLE_RATE: str
33
+ samping rate ranging from 0 to 1, float precision
29
34
30
35
Parameters
31
36
----------
32
37
service : str, optional
33
38
service name to be appended in logs, by default "service_undefined"
34
39
level : str, optional
35
40
logging.level, by default "INFO"
41
+ sample_rate: float, optional
42
+ sample rate for debug calls within execution context defaults to 0
36
43
37
44
Example
38
45
-------
@@ -52,21 +59,36 @@ def logger_setup(service: str = "service_undefined", level: str = "INFO", **kwar
52
59
>>>
53
60
>>> def handler(event, context):
54
61
logger.info("Hello")
62
+ :param service:
63
+ :param level:
64
+ :param sampling_rate:
55
65
56
66
"""
57
67
service = os .getenv ("POWERTOOLS_SERVICE_NAME" ) or service
68
+ sampling_rate = os .getenv ("POWERTOOLS_SAMPLE_RATE" ) or sampling_rate
58
69
log_level = os .getenv ("LOG_LEVEL" ) or level
59
70
logger = logging .getLogger (name = service )
71
+
72
+ # sampling a small percentage of requests with debug level, using a float value 0.1 = 10%~
73
+
74
+ try :
75
+ if sampling_rate and random .random () <= float (sampling_rate ):
76
+ log_level = logging .DEBUG
77
+ except ValueError :
78
+ logger .debug ("POWERTOOLS_SAMPLE_RATE provided value {0} is not valid." .format (sampling_rate ))
79
+
60
80
logger .setLevel (log_level )
61
81
62
82
# Patch logger by structuring its outputs as JSON
63
- aws_lambda_logging .setup (level = log_level , service = service , ** kwargs )
83
+ aws_lambda_logging .setup (
84
+ level = log_level , service = service , sampling_rate = sampling_rate , ** kwargs
85
+ )
64
86
65
87
return logger
66
88
67
89
68
90
def logger_inject_lambda_context (
69
- lambda_handler : Callable [[Dict , Any ], Any ] = None , log_event : bool = False
91
+ lambda_handler : Callable [[Dict , Any ], Any ] = None , log_event : bool = False
70
92
):
71
93
"""Decorator to capture Lambda contextual info and inject into struct logging
72
94
@@ -110,6 +132,8 @@ def logger_inject_lambda_context(
110
132
-------
111
133
decorate : Callable
112
134
Decorated lambda handler
135
+ :param log_event:
136
+ :param lambda_handler:
113
137
"""
114
138
115
139
# If handler is None we've been called with parameters
@@ -159,12 +183,12 @@ def __is_cold_start() -> str:
159
183
160
184
161
185
def log_metric (
162
- name : str ,
163
- namespace : str ,
164
- unit : MetricUnit ,
165
- value : float = 0 ,
166
- service : str = "service_undefined" ,
167
- ** dimensions ,
186
+ name : str ,
187
+ namespace : str ,
188
+ unit : MetricUnit ,
189
+ value : float = 0 ,
190
+ service : str = "service_undefined" ,
191
+ ** dimensions ,
168
192
):
169
193
"""Logs a custom metric in a statsD-esque format to stdout.
170
194
0 commit comments