11
11
import asyncio
12
12
from collections import deque
13
13
from datetime import datetime
14
- from functools import cached_property
14
+ from functools import cached_property , lru_cache
15
15
import logging
16
16
import secrets
17
17
import time
@@ -230,6 +230,13 @@ def _loop(self) -> asyncio.AbstractEventLoop:
230
230
assert self .server .loop
231
231
return self .server .loop
232
232
233
+ @lru_cache (maxsize = 1024 ) # noqa: B019
234
+ def get_node_logger (
235
+ self , logger : logging .Logger , node_id : int
236
+ ) -> logging .LoggerAdapter :
237
+ """Return a logger for a specific node."""
238
+ return logging .LoggerAdapter (logger , {"node" : node_id })
239
+
233
240
@api_command (APICommand .GET_NODES )
234
241
def get_nodes (self , only_available : bool = False ) -> list [MatterNodeData ]:
235
242
"""Return all Nodes known to the server."""
@@ -757,7 +764,7 @@ async def ping_node(self, node_id: int, attempts: int = 1) -> NodePingResult:
757
764
raise NodeNotExists (
758
765
f"Node { node_id } does not exist or is not yet interviewed"
759
766
)
760
- node_logger = LOGGER . getChild ( f"node_ { node_id } " )
767
+ node_logger = self . get_node_logger ( LOGGER , node_id )
761
768
762
769
battery_powered = (
763
770
node .attributes .get (ROUTING_ROLE_ATTRIBUTE_PATH , 0 )
@@ -813,7 +820,7 @@ async def _get_node_ip_addresses(
813
820
raise NodeNotExists (
814
821
f"Node { node_id } does not exist or is not yet interviewed"
815
822
)
816
- node_logger = LOGGER . getChild ( f"node_ { node_id } " )
823
+ node_logger = self . get_node_logger ( LOGGER , node_id )
817
824
# query mdns for all IP's
818
825
# ensure both fabric id and node id have 16 characters (prefix with zero's)
819
826
mdns_name = f"{ self .compressed_fabric_id :0{16 }X} -{ node_id :0{16 }X} .{ MDNS_TYPE_OPERATIONAL_NODE } "
@@ -882,7 +889,7 @@ async def _subscribe_node(self, node_id: int) -> None:
882
889
f"Node { node_id } does not exist or has not been interviewed."
883
890
)
884
891
885
- node_logger = LOGGER . getChild ( f"node_ { node_id } " )
892
+ node_logger = self . get_node_logger ( LOGGER , node_id )
886
893
887
894
# Shutdown existing subscriptions for this node first
888
895
await self ._chip_device_controller .shutdown_subscription (node_id )
@@ -1104,7 +1111,8 @@ async def _setup_node(self, node_id: int) -> None:
1104
1111
# prevent duplicate setup actions
1105
1112
return
1106
1113
self ._nodes_in_setup .add (node_id )
1107
- node_logger = LOGGER .getChild (f"node_{ node_id } " )
1114
+
1115
+ node_logger = self .get_node_logger (LOGGER , node_id )
1108
1116
node_data = self ._nodes [node_id ]
1109
1117
log_timers : dict [int , asyncio .TimerHandle ] = {}
1110
1118
is_thread_node = (
@@ -1297,6 +1305,7 @@ def _on_mdns_operational_node_state(
1297
1305
# the mdns name is constructed as [fabricid]-[nodeid]._matter._tcp.local.
1298
1306
# extract the node id from the name
1299
1307
node_id = int (name .split ("-" )[1 ].split ("." )[0 ], 16 )
1308
+ node_logger = self .get_node_logger (logger , node_id )
1300
1309
1301
1310
if not (node := self ._nodes .get (node_id )):
1302
1311
return # this should not happen, but guard just in case
@@ -1315,13 +1324,13 @@ def _on_mdns_operational_node_state(
1315
1324
return
1316
1325
1317
1326
if not self ._chip_device_controller .node_has_subscription (node_id ):
1318
- logger .info ("Node %s discovered on MDNS" , node_id )
1327
+ node_logger .info ("Discovered on mDNS" )
1319
1328
elif (now - last_seen ) > NODE_MDNS_BACKOFF :
1320
1329
# node came back online after being offline for a while or restarted
1321
- logger .info ("Node %s re -discovered on MDNS" , node_id )
1330
+ node_logger .info ("Re -discovered on mDNS" )
1322
1331
elif state_change == ServiceStateChange .Added :
1323
1332
# Trigger node re-subscriptions when mDNS entry got added
1324
- logger .info ("Node %s activity on MDNS , trigger resubscribe" , node_id )
1333
+ node_logger .info ("Activity on mDNS , trigger resubscribe" )
1325
1334
asyncio .create_task (
1326
1335
self ._chip_device_controller .trigger_resubscribe_if_scheduled (
1327
1336
node_id , "mDNS state change detected"
@@ -1383,7 +1392,7 @@ def _node_unavailable(
1383
1392
return
1384
1393
node .available = False
1385
1394
self .server .signal_event (EventType .NODE_UPDATED , node )
1386
- node_logger = LOGGER . getChild ( f"node_ { node_id } " )
1395
+ node_logger = self . get_node_logger ( LOGGER , node_id )
1387
1396
node_logger .info ("Marked node as unavailable" )
1388
1397
if force_resubscription :
1389
1398
# Make sure the subscriptions are expiring very soon to trigger subscription
@@ -1419,7 +1428,7 @@ async def _node_offline(self, node_id: int) -> None:
1419
1428
return # nothing to do to
1420
1429
node .available = False
1421
1430
self .server .signal_event (EventType .NODE_UPDATED , node )
1422
- node_logger = LOGGER . getChild ( f"node_ { node_id } " )
1431
+ node_logger = self . get_node_logger ( LOGGER , node_id )
1423
1432
node_logger .info ("Marked node as offline" )
1424
1433
1425
1434
async def _fallback_node_scanner (self ) -> None :
0 commit comments