Skip to content

Commit b629190

Browse files
author
Ramisa Alam
committed
feat: add tenant id to structed log messages
1 parent 6c2257d commit b629190

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

awslambdaric/bootstrap.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ def emit(self, record):
341341
class LambdaLoggerFilter(logging.Filter):
342342
def filter(self, record):
343343
record.aws_request_id = _GLOBAL_AWS_REQUEST_ID or ""
344+
record.tenant_id = _GLOBAL_TENANT_ID
344345
return True
345346

346347

@@ -449,6 +450,7 @@ def create_log_sink():
449450

450451

451452
_GLOBAL_AWS_REQUEST_ID = None
453+
_GLOBAL_TENANT_ID = None
452454

453455

454456
def _setup_logging(log_format, log_level, log_sink):
@@ -494,7 +496,7 @@ def run(app_root, handler, lambda_runtime_api_addr):
494496

495497
try:
496498
_setup_logging(_AWS_LAMBDA_LOG_FORMAT, _AWS_LAMBDA_LOG_LEVEL, log_sink)
497-
global _GLOBAL_AWS_REQUEST_ID
499+
global _GLOBAL_AWS_REQUEST_ID, _GLOBAL_TENANT_ID
498500

499501
request_handler = _get_handler(handler)
500502
except FaultException as e:
@@ -519,6 +521,7 @@ def run(app_root, handler, lambda_runtime_api_addr):
519521
event_request = lambda_runtime_client.wait_next_invocation()
520522

521523
_GLOBAL_AWS_REQUEST_ID = event_request.invoke_id
524+
_GLOBAL_TENANT_ID = event_request.tenant_id
522525

523526
update_xray_env_variable(event_request.x_amzn_trace_id)
524527

awslambdaric/lambda_runtime_log_utils.py

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"processName",
3131
"process",
3232
"aws_request_id",
33+
"tenant_id",
3334
"_frame_type",
3435
}
3536

@@ -124,6 +125,9 @@ def format(self, record: logging.LogRecord) -> str:
124125
"requestId": getattr(record, "aws_request_id", None),
125126
"location": self.__format_location(record),
126127
}
128+
if hasattr(record, "tenant_id") and record.tenant_id is not None:
129+
result["tenantId"] = record.tenant_id
130+
127131
result.update(
128132
(key, value)
129133
for key, value in record.__dict__.items()

tests/test_bootstrap.py

+53
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,59 @@ def test_json_formatter(self, mock_stderr):
13761376
)
13771377
self.assertEqual(mock_stderr.getvalue(), "")
13781378

1379+
@patch("awslambdaric.bootstrap._GLOBAL_TENANT_ID", "test-tenant-id")
1380+
@patch("sys.stderr", new_callable=StringIO)
1381+
def test_json_formatter_with_tenant_id(self, mock_stderr):
1382+
logger = logging.getLogger("a.b")
1383+
1384+
test_cases = [
1385+
(
1386+
logging.ERROR,
1387+
"TEST 1",
1388+
{
1389+
"level": "ERROR",
1390+
"logger": "a.b",
1391+
"message": "TEST 1",
1392+
"requestId": "",
1393+
"tenantId": "test-tenant-id",
1394+
},
1395+
),
1396+
(
1397+
logging.ERROR,
1398+
"test \nwith \nnew \nlines",
1399+
{
1400+
"level": "ERROR",
1401+
"logger": "a.b",
1402+
"message": "test \nwith \nnew \nlines",
1403+
"requestId": "",
1404+
"tenantId": "test-tenant-id",
1405+
},
1406+
),
1407+
(
1408+
logging.CRITICAL,
1409+
"TEST CRITICAL",
1410+
{
1411+
"level": "CRITICAL",
1412+
"logger": "a.b",
1413+
"message": "TEST CRITICAL",
1414+
"requestId": "",
1415+
"tenantId": "test-tenant-id",
1416+
},
1417+
),
1418+
]
1419+
for level, msg, expected in test_cases:
1420+
with self.subTest(msg):
1421+
with patch("sys.stdout", new_callable=StringIO) as mock_stdout:
1422+
logger.log(level, msg)
1423+
1424+
data = json.loads(mock_stdout.getvalue())
1425+
data.pop("timestamp")
1426+
self.assertEqual(
1427+
data,
1428+
expected,
1429+
)
1430+
self.assertEqual(mock_stderr.getvalue(), "")
1431+
13791432
@patch("sys.stdout", new_callable=StringIO)
13801433
@patch("sys.stderr", new_callable=StringIO)
13811434
def test_exception(self, mock_stderr, mock_stdout):

0 commit comments

Comments
 (0)