18
18
19
19
import awslambdaric .bootstrap as bootstrap
20
20
from awslambdaric .lambda_runtime_exception import FaultException
21
- from awslambdaric .lambda_runtime_log_utils import LogFormat
21
+ from awslambdaric .lambda_runtime_log_utils import LogFormat , _get_log_level_from_env_var
22
22
from awslambdaric .lambda_runtime_marshaller import LambdaMarshaller
23
23
24
24
@@ -927,7 +927,7 @@ def test_log_error_framed_log_sink(self):
927
927
content = f .read ()
928
928
929
929
frame_type = int .from_bytes (content [:4 ], "big" )
930
- self .assertEqual (frame_type , 0xA55A0003 )
930
+ self .assertEqual (frame_type , 0xA55A0017 )
931
931
932
932
length = int .from_bytes (content [4 :8 ], "big" )
933
933
self .assertEqual (length , len (expected_logged_error .encode ("utf8" )))
@@ -973,7 +973,7 @@ def test_log_error_indentation_framed_log_sink(self):
973
973
content = f .read ()
974
974
975
975
frame_type = int .from_bytes (content [:4 ], "big" )
976
- self .assertEqual (frame_type , 0xA55A0003 )
976
+ self .assertEqual (frame_type , 0xA55A0017 )
977
977
978
978
length = int .from_bytes (content [4 :8 ], "big" )
979
979
self .assertEqual (length , len (expected_logged_error .encode ("utf8" )))
@@ -1016,7 +1016,7 @@ def test_log_error_empty_stacktrace_line_framed_log_sink(self):
1016
1016
content = f .read ()
1017
1017
1018
1018
frame_type = int .from_bytes (content [:4 ], "big" )
1019
- self .assertEqual (frame_type , 0xA55A0003 )
1019
+ self .assertEqual (frame_type , 0xA55A0017 )
1020
1020
1021
1021
length = int .from_bytes (content [4 :8 ], "big" )
1022
1022
self .assertEqual (length , len (expected_logged_error ))
@@ -1053,7 +1053,7 @@ def test_log_error_invokeId_line_framed_log_sink(self):
1053
1053
content = f .read ()
1054
1054
1055
1055
frame_type = int .from_bytes (content [:4 ], "big" )
1056
- self .assertEqual (frame_type , 0xA55A0003 )
1056
+ self .assertEqual (frame_type , 0xA55A0017 )
1057
1057
1058
1058
length = int .from_bytes (content [4 :8 ], "big" )
1059
1059
self .assertEqual (length , len (expected_logged_error ))
@@ -1179,14 +1179,13 @@ def test_log_level(self) -> None:
1179
1179
(LogFormat .JSON , "WARN" , logging .WARNING ),
1180
1180
(LogFormat .JSON , "ERROR" , logging .ERROR ),
1181
1181
(LogFormat .JSON , "FATAL" , logging .CRITICAL ),
1182
- # Log level is set only for Json format
1183
- (LogFormat .TEXT , "TRACE" , logging .NOTSET ),
1184
- (LogFormat .TEXT , "DEBUG" , logging .NOTSET ),
1185
- (LogFormat .TEXT , "INFO" , logging .NOTSET ),
1186
- (LogFormat .TEXT , "WARN" , logging .NOTSET ),
1187
- (LogFormat .TEXT , "ERROR" , logging .NOTSET ),
1188
- (LogFormat .TEXT , "FATAL" , logging .NOTSET ),
1189
- ("Unknown format" , "INFO" , logging .NOTSET ),
1182
+ (LogFormat .TEXT , "TRACE" , logging .DEBUG ),
1183
+ (LogFormat .TEXT , "DEBUG" , logging .DEBUG ),
1184
+ (LogFormat .TEXT , "INFO" , logging .INFO ),
1185
+ (LogFormat .TEXT , "WARN" , logging .WARN ),
1186
+ (LogFormat .TEXT , "ERROR" , logging .ERROR ),
1187
+ (LogFormat .TEXT , "FATAL" , logging .CRITICAL ),
1188
+ ("Unknown format" , "INFO" , logging .INFO ),
1190
1189
# if level is unknown fall back to default
1191
1190
(LogFormat .JSON , "Unknown level" , logging .NOTSET ),
1192
1191
]
@@ -1196,11 +1195,67 @@ def test_log_level(self) -> None:
1196
1195
logging .getLogger ().handlers .clear ()
1197
1196
logging .getLogger ().level = logging .NOTSET
1198
1197
1199
- bootstrap ._setup_logging (fmt , log_level , bootstrap .StandardLogSink ())
1198
+ bootstrap ._setup_logging (
1199
+ fmt ,
1200
+ _get_log_level_from_env_var (log_level ),
1201
+ bootstrap .StandardLogSink (),
1202
+ )
1200
1203
1201
1204
self .assertEqual (expected_level , logging .getLogger ().level )
1202
1205
1203
1206
1207
+ class TestLambdaLoggerHandlerSetup (unittest .TestCase ):
1208
+ @classmethod
1209
+ def tearDownClass (cls ):
1210
+ importlib .reload (bootstrap )
1211
+ logging .getLogger ().handlers .clear ()
1212
+ logging .getLogger ().level = logging .NOTSET
1213
+
1214
+ def test_handler_setup (self , * _ ):
1215
+ test_cases = [
1216
+ (62 , 0xA55A0003 , 46 , {}),
1217
+ (133 , 0xA55A001A , 117 , {"AWS_LAMBDA_LOG_FORMAT" : "JSON" }),
1218
+ (62 , 0xA55A001B , 46 , {"AWS_LAMBDA_LOG_LEVEL" : "INFO" }),
1219
+ ]
1220
+
1221
+ for total_length , header , message_length , env_vars in test_cases :
1222
+ with patch .dict (
1223
+ os .environ , env_vars , clear = True
1224
+ ), NamedTemporaryFile () as temp_file :
1225
+ importlib .reload (bootstrap )
1226
+ logging .getLogger ().handlers .clear ()
1227
+ logging .getLogger ().level = logging .NOTSET
1228
+
1229
+ before = int (time .time_ns () / 1000 )
1230
+ with bootstrap .FramedTelemetryLogSink (
1231
+ os .open (temp_file .name , os .O_CREAT | os .O_RDWR )
1232
+ ) as ls :
1233
+ bootstrap ._setup_logging (
1234
+ bootstrap ._AWS_LAMBDA_LOG_FORMAT ,
1235
+ bootstrap ._AWS_LAMBDA_LOG_LEVEL ,
1236
+ ls ,
1237
+ )
1238
+ logger = logging .getLogger ()
1239
+ logger .critical ("critical" )
1240
+ after = int (time .time_ns () / 1000 )
1241
+
1242
+ content = open (temp_file .name , "rb" ).read ()
1243
+ self .assertEqual (len (content ), total_length )
1244
+
1245
+ pos = 0
1246
+ frame_type = int .from_bytes (content [pos : pos + 4 ], "big" )
1247
+ self .assertEqual (frame_type , header )
1248
+ pos += 4
1249
+
1250
+ length = int .from_bytes (content [pos : pos + 4 ], "big" )
1251
+ self .assertEqual (length , message_length )
1252
+ pos += 4
1253
+
1254
+ timestamp = int .from_bytes (content [pos : pos + 8 ], "big" )
1255
+ self .assertTrue (before <= timestamp )
1256
+ self .assertTrue (timestamp <= after )
1257
+
1258
+
1204
1259
class TestLogging (unittest .TestCase ):
1205
1260
@classmethod
1206
1261
def setUpClass (cls ) -> None :
0 commit comments