feat: add trace log level

This commit is contained in:
Xuwznln
2025-08-04 20:27:02 +08:00
parent 5cd0f72fbd
commit 98ce360088
8 changed files with 81 additions and 36 deletions

View File

@@ -51,7 +51,7 @@ from unilabos.ros.nodes.resource_tracker import DeviceNodeResourceTracker
from unilabos.ros.x.rclpyx import get_event_loop
from unilabos.ros.utils.driver_creator import ProtocolNodeCreator, PyLabRobotCreator, DeviceClassCreator
from unilabos.utils.async_util import run_async_func
from unilabos.utils.log import info, debug, warning, error, critical, logger
from unilabos.utils.log import info, debug, warning, error, critical, logger, trace
from unilabos.utils.type_check import get_type_class, TypeEncoder, serialize_result_info
T = TypeVar("T")
@@ -82,6 +82,7 @@ class ROSLoggerAdapter:
self.level_2_logger_func = {
"info": info,
"debug": debug,
"trace": trace,
"warning": warning,
"error": error,
"critical": critical,
@@ -96,6 +97,10 @@ class ROSLoggerAdapter:
ros_log_func(msg)
self.level_2_logger_func[level](msg, *args, stack_level=1, **kwargs)
def trace(self, msg, *args, **kwargs):
"""记录TRACE级别日志"""
self._log("trace", msg, *args, **kwargs)
def debug(self, msg, *args, **kwargs):
"""记录DEBUG级别日志"""
self._log("debug", msg, *args, **kwargs)
@@ -175,12 +180,12 @@ class PropertyPublisher:
self.timer = node.create_timer(self.timer_period, self.publish_property)
self.__loop = get_event_loop()
str_msg_type = str(msg_type)[8:-2]
self.node.lab_logger().debug(f"发布属性: {name}, 类型: {str_msg_type}, 周期: {initial_period}")
self.node.lab_logger().trace(f"发布属性: {name}, 类型: {str_msg_type}, 周期: {initial_period}")
def get_property(self):
if asyncio.iscoroutinefunction(self.get_method):
# 如果是异步函数,运行事件循环并等待结果
self.node.lab_logger().debug(f"【PropertyPublisher.get_property】获取异步属性: {self.name}")
self.node.lab_logger().trace(f"【PropertyPublisher.get_property】获取异步属性: {self.name}")
loop = self.__loop
if loop:
future = asyncio.run_coroutine_threadsafe(self.get_method(), loop)
@@ -191,28 +196,28 @@ class PropertyPublisher:
return None
else:
# 如果是同步函数,直接调用并返回结果
self.node.lab_logger().debug(f"【PropertyPublisher.get_property】获取同步属性: {self.name}")
self.node.lab_logger().trace(f"【PropertyPublisher.get_property】获取同步属性: {self.name}")
self._value = self.get_method()
return self._value
async def get_property_async(self):
try:
# 获取异步属性值
self.node.lab_logger().debug(f"【PropertyPublisher.get_property_async】异步获取属性: {self.name}")
self.node.lab_logger().trace(f"【PropertyPublisher.get_property_async】异步获取属性: {self.name}")
self._value = await self.get_method()
except Exception as e:
self.node.lab_logger().error(f"【PropertyPublisher.get_property_async】获取异步属性出错: {str(e)}")
def publish_property(self):
try:
self.node.lab_logger().debug(f"【PropertyPublisher.publish_property】开始发布属性: {self.name}")
self.node.lab_logger().trace(f"【PropertyPublisher.publish_property】开始发布属性: {self.name}")
value = self.get_property()
if self.print_publish:
self.node.lab_logger().info(f"【PropertyPublisher.publish_property】发布 {self.msg_type}: {value}")
self.node.lab_logger().trace(f"【PropertyPublisher.publish_property】发布 {self.msg_type}: {value}")
if value is not None:
msg = convert_to_ros_msg(self.msg_type, value)
self.publisher_.publish(msg)
self.node.lab_logger().debug(f"【PropertyPublisher.publish_property】属性 {self.name} 发布成功")
self.node.lab_logger().trace(f"【PropertyPublisher.publish_property】属性 {self.name} 发布成功")
except Exception as e:
self.node.lab_logger().error(f"【PropertyPublisher.publish_property】发布属性 {self.publisher_.topic} 出错: {str(e)}\n{traceback.format_exc()}")
@@ -606,7 +611,7 @@ class BaseROS2DeviceNode(Node, Generic[T]):
callback_group=ReentrantCallbackGroup(),
)
self.lab_logger().debug(f"发布动作: {action_name}, 类型: {str_action_type}")
self.lab_logger().trace(f"发布动作: {action_name}, 类型: {str_action_type}")
def get_real_function(self, instance, attr_name):
if hasattr(instance.__class__, attr_name):

View File

@@ -1,3 +1,4 @@
import collections
import copy
import json
import threading
@@ -254,7 +255,7 @@ class HostNode(BaseROS2DeviceNode):
检测ROS2网络中的所有设备节点并为它们创建ActionClient
同时检测设备离线情况
"""
self.lab_logger().debug("[Host Node] Discovering devices in the network...")
self.lab_logger().trace("[Host Node] Discovering devices in the network...")
# 获取当前所有设备
nodes_and_names = self.get_node_names_and_namespaces()
@@ -303,7 +304,7 @@ class HostNode(BaseROS2DeviceNode):
# 更新在线设备列表
self._online_devices = current_devices
self.lab_logger().debug(f"[Host Node] Total online devices: {len(self._online_devices)}")
self.lab_logger().trace(f"[Host Node] Total online devices: {len(self._online_devices)}")
def _discovery_devices_callback(self) -> None:
"""
@@ -335,7 +336,7 @@ class HostNode(BaseROS2DeviceNode):
self._action_clients[action_id] = ActionClient(
self, action_type, action_id, callback_group=self.callback_group
)
self.lab_logger().debug(f"[Host Node] Created ActionClient (Discovery): {action_id}")
self.lab_logger().trace(f"[Host Node] Created ActionClient (Discovery): {action_id}")
action_name = action_id[len(namespace) + 1 :]
edge_device_id = namespace[9:]
# from unilabos.app.mq import mqtt_client
@@ -476,7 +477,7 @@ class HostNode(BaseROS2DeviceNode):
if action_id not in self._action_clients:
action_type = action_value_mapping["type"]
self._action_clients[action_id] = ActionClient(self, action_type, action_id)
self.lab_logger().debug(
self.lab_logger().trace(
f"[Host Node] Created ActionClient (Local): {action_id}"
) # 子设备再创建用的是Discover发现的
# from unilabos.app.mq import mqtt_client
@@ -521,7 +522,7 @@ class HostNode(BaseROS2DeviceNode):
self.device_status_timestamps[device_id] = {}
# 默认初始化属性值为 None
self.device_status[device_id][property_name] = None
self.device_status[device_id] = collections.defaultdict()
self.device_status_timestamps[device_id][property_name] = 0 # 初始化时间戳
# 动态创建订阅
@@ -539,7 +540,7 @@ class HostNode(BaseROS2DeviceNode):
)
# 标记为已订阅
self._subscribed_topics.add(topic)
self.lab_logger().debug(f"[Host Node] Subscribed to new topic: {topic}")
self.lab_logger().trace(f"[Host Node] Subscribed to new topic: {topic}")
except (NameError, SyntaxError) as e:
self.lab_logger().error(f"[Host Node] Failed to create subscription for topic {topic}: {e}")
@@ -557,10 +558,15 @@ class HostNode(BaseROS2DeviceNode):
# 更新设备状态字典
if hasattr(msg, "data"):
bChange = False
bCreate = False
if isinstance(msg.data, (float, int, str)):
if self.device_status[device_id][property_name] != msg.data:
if property_name not in self.device_status[device_id]:
bCreate = True
bChange = True
self.device_status[device_id][property_name] = msg.data
self.device_status[device_id][property_name] = msg.data
elif self.device_status[device_id][property_name] != msg.data:
bChange = True
self.device_status[device_id][property_name] = msg.data
# 更新时间戳
self.device_status_timestamps[device_id][property_name] = time.time()
else:
@@ -573,9 +579,14 @@ class HostNode(BaseROS2DeviceNode):
for bridge in self.bridges:
if hasattr(bridge, "publish_device_status"):
bridge.publish_device_status(self.device_status, device_id, property_name)
self.lab_logger().debug(
f"[Host Node] Status updated: {device_id}.{property_name} = {msg.data}"
)
if bCreate:
self.lab_logger().trace(
f"Status created: {device_id}.{property_name} = {msg.data}"
)
else:
self.lab_logger().debug(
f"Status updated: {device_id}.{property_name} = {msg.data}"
)
def send_goal(
self,

View File

@@ -151,7 +151,7 @@ class ROS2ProtocolNode(BaseROS2DeviceNode):
except Exception as ex:
self.lab_logger().error(f"创建动作客户端失败: {action_id}, 错误: {ex}")
continue
self.lab_logger().debug(f"为子设备 {device_id} 创建动作客户端: {action_name}")
self.lab_logger().trace(f"为子设备 {device_id} 创建动作客户端: {action_name}")
return d
def create_ros_action_server(self, action_name, action_value_mapping):
@@ -171,7 +171,7 @@ class ROS2ProtocolNode(BaseROS2DeviceNode):
callback_group=ReentrantCallbackGroup(),
)
self.lab_logger().debug(f"发布动作: {action_name}, 类型: {str_action_type}")
self.lab_logger().trace(f"发布动作: {action_name}, 类型: {str_action_type}")
def _create_protocol_execute_callback(self, protocol_name, protocol_steps_generator):
async def execute_protocol(goal_handle: ServerGoalHandle):