1818
1919import awslambdaric .bootstrap as bootstrap
2020from 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
2222from awslambdaric .lambda_runtime_marshaller import LambdaMarshaller
2323
2424
@@ -927,7 +927,7 @@ def test_log_error_framed_log_sink(self):
927927 content = f .read ()
928928
929929 frame_type = int .from_bytes (content [:4 ], "big" )
930- self .assertEqual (frame_type , 0xA55A0003 )
930+ self .assertEqual (frame_type , 0xA55A0017 )
931931
932932 length = int .from_bytes (content [4 :8 ], "big" )
933933 self .assertEqual (length , len (expected_logged_error .encode ("utf8" )))
@@ -973,7 +973,7 @@ def test_log_error_indentation_framed_log_sink(self):
973973 content = f .read ()
974974
975975 frame_type = int .from_bytes (content [:4 ], "big" )
976- self .assertEqual (frame_type , 0xA55A0003 )
976+ self .assertEqual (frame_type , 0xA55A0017 )
977977
978978 length = int .from_bytes (content [4 :8 ], "big" )
979979 self .assertEqual (length , len (expected_logged_error .encode ("utf8" )))
@@ -1016,7 +1016,7 @@ def test_log_error_empty_stacktrace_line_framed_log_sink(self):
10161016 content = f .read ()
10171017
10181018 frame_type = int .from_bytes (content [:4 ], "big" )
1019- self .assertEqual (frame_type , 0xA55A0003 )
1019+ self .assertEqual (frame_type , 0xA55A0017 )
10201020
10211021 length = int .from_bytes (content [4 :8 ], "big" )
10221022 self .assertEqual (length , len (expected_logged_error ))
@@ -1053,7 +1053,7 @@ def test_log_error_invokeId_line_framed_log_sink(self):
10531053 content = f .read ()
10541054
10551055 frame_type = int .from_bytes (content [:4 ], "big" )
1056- self .assertEqual (frame_type , 0xA55A0003 )
1056+ self .assertEqual (frame_type , 0xA55A0017 )
10571057
10581058 length = int .from_bytes (content [4 :8 ], "big" )
10591059 self .assertEqual (length , len (expected_logged_error ))
@@ -1179,14 +1179,13 @@ def test_log_level(self) -> None:
11791179 (LogFormat .JSON , "WARN" , logging .WARNING ),
11801180 (LogFormat .JSON , "ERROR" , logging .ERROR ),
11811181 (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 ),
11901189 # if level is unknown fall back to default
11911190 (LogFormat .JSON , "Unknown level" , logging .NOTSET ),
11921191 ]
@@ -1196,11 +1195,67 @@ def test_log_level(self) -> None:
11961195 logging .getLogger ().handlers .clear ()
11971196 logging .getLogger ().level = logging .NOTSET
11981197
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+ )
12001203
12011204 self .assertEqual (expected_level , logging .getLogger ().level )
12021205
12031206
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+
12041259class TestLogging (unittest .TestCase ):
12051260 @classmethod
12061261 def setUpClass (cls ) -> None :
0 commit comments