feat: replace stdlib logging with hivecore_logger SDK

- Import hivecore_logger alongside stdlib logging
- Replace _setup_file_logging() with hivecore_logger.init() using
  node_name='ctrlgui', log_dir from ROS2 param log_base_dir,
  enable_signal_handlers=False and enable_auto_shutdown_hook=False
  to avoid conflicts with NiceGUI/ROS2 lifecycle
- Obtain logger instance via hivecore_logger.get_logger(); all
  existing self.file_logger call sites (info/warning/error) unchanged
- Add hivecore_logger.stop() in shutdown() to flush async log queue
- Update default log_base_dir parameter to /var/log/robot
- Log output format: [timestamp] [LEVEL] [ctrlgui] [thread] [file:line] msg
  written to <log_dir>/<YYYYMMDD>/ctrlgui.log with console echo
This commit is contained in:
2026-03-04 18:40:10 +08:00
parent 1968580877
commit 597ab48699
2 changed files with 20 additions and 50 deletions

View File

@@ -2,7 +2,7 @@ ctrlgui_node:
ros__parameters:
collection_enabled: false
data_base_dir: "/home/demo/hivecore_robot_os1/data"
log_base_dir: "/home/demo/hivecore_robot_os1/logs"
log_base_dir: "/var/log/robot"
queue_size: 10
action_server_wait_timeout_sec: 1.0
work_info_log_throttle_sec: 1.0

View File

@@ -12,6 +12,7 @@ import time
import asyncio
import datetime
import logging
import hivecore_logger
import rclpy
from rclpy.node import Node
from rclpy.action.client import ActionClient
@@ -39,7 +40,7 @@ class CtrlGuiNode(Node):
def _declare_parameters(self) -> None:
self.declare_parameter('collection_enabled', False)
self.declare_parameter('data_base_dir', '/home/demo/hivecore_robot_os1/data')
self.declare_parameter('log_base_dir', '/home/demo/hivecore_robot_os1/logs')
self.declare_parameter('log_base_dir', '/var/log/robot')
self.declare_parameter('queue_size', 10)
self.declare_parameter('action_server_wait_timeout_sec', 1.0)
self.declare_parameter('work_info_log_throttle_sec', 1.0)
@@ -441,54 +442,19 @@ class CtrlGuiNode(Node):
ui.notify(f'Error: {str(e)}', color='negative')
def _setup_file_logging(self):
"""Setup logging to a file with timestamp in filename."""
# Base logs directory
base_log_dir = self.log_base_dir
now = datetime.datetime.now()
today_str = now.strftime("%Y%m%d")
today_dir = os.path.join(base_log_dir, today_str)
log_dir = None
try:
# 1. 检查当天的目录是否存在
if os.path.exists(today_dir):
# 2. 查找当天目录中最新的 "robot_logs_..." 文件夹
dirs = [os.path.join(today_dir, d) for d in os.listdir(today_dir)
if os.path.isdir(os.path.join(today_dir, d)) and d.startswith("robot_logs_")]
if dirs:
log_dir = max(dirs, key=os.path.getmtime)
# 3. 如果当天目录不存在,或者里面没有 robot_logs 文件夹,则创建新的
if not log_dir:
time_str = now.strftime("%H%M%S")
log_dir = os.path.join(today_dir, f"robot_logs_{today_str}_{time_str}")
except Exception:
# 兜底方案
log_dir = os.path.join(today_dir, f"robot_logs_{today_str}_{now.strftime('%H%M%S')}")
os.makedirs(log_dir, exist_ok=True)
# Generate filename with timestamp
timestamp = now.strftime("%Y%m%d_%H%M%S")
log_filename = os.path.join(log_dir, f"ctrlgui_{timestamp}.log")
print(f"Logging to file: {log_filename}")
# Create file handler
file_handler = logging.FileHandler(log_filename)
file_handler.setLevel(logging.INFO)
# Create formatter
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
# Create a dedicated logger for file output
self.file_logger = logging.getLogger(f"ctrlgui_file_{timestamp}")
self.file_logger.setLevel(logging.INFO)
self.file_logger.addHandler(file_handler)
self.log_filename = log_filename
self.file_logger.info('File logging setup complete.')
"""Initialize hivecore logger for this node."""
hivecore_logger.init(
node_name='ctrlgui',
log_dir=self.log_base_dir,
level=logging.INFO,
enable_console=True,
# Disable built-in signal handlers to avoid conflicts with NiceGUI/ROS2 lifecycle
enable_signal_handlers=False,
# Disable auto atexit hook; we register our own shutdown() below
enable_auto_shutdown_hook=False,
)
self.file_logger = hivecore_logger.get_logger()
self.file_logger.info('Hivecore logger initialized (log_dir=%s).', self.log_base_dir)
def _on_work_info(self, msg: RobotWorkInfo) -> None:
"""Callback for /robot_work_info subscription: store latest text."""
@@ -1457,6 +1423,10 @@ def main() -> None:
node.file_logger.info(f'Final statistics: {str(stats)}')
except Exception as e:
pass
try:
hivecore_logger.stop()
except Exception:
pass
try:
node.destroy_node()
except Exception: