intermediate - Logging and logger configuration

ROS 2 로깅은 메시지를 콘솔(연결된 경우), 디스크 로그 파일(저장 공간이 있는 경우), /rosout 토픽(ROS 2 네트워크) 등 여러 대상으로 보낸다. 기본적으로 노드의 로그는 콘솔(stderr), 디스크 로그 파일, /rosout 세 곳 모두로 나가며, 노드 단위로 각 대상을 켜거나 끌 수 있다.

공식 개념 문서: Logging and logger configuration (Jazzy)

심각도 레벨(Severity level)

로그 메시지에는 심각도가 붙는다: DEBUG, INFO, WARN, ERROR, FATAL(낮은 순).

로거는 그 로거에 설정된 레벨 이상의 심각도 메시지만 처리한다. 각 노드에는 노드 이름·네임스페이스를 포함한 로거가 붙고, 노드 이름이 리매핑되면 로거 이름에도 반영된다. 노드가 아닌 독립 로거도 이름을 지정해 만들 수 있다.

로거 이름은 계층을 이룬다. 예: abc.def의 레벨이 없으면 부모 abc를 보고, abc도 없으면 기본 로거 레벨을 쓴다. abc의 레벨을 바꾸면 자손(abc.def, abc.ghi.jkl 등)도 영향받되, 명시적으로 레벨이 설정된 자손은 그대로다.

API (클라이언트 라이브러리별)

C++ (rclcpp)

  • RCLCPP_{DEBUG,INFO,WARN,ERROR,FATAL}: printf 스타일, 매번 출력
  • _ONCE, _THROTTLE(ms), _EXPRESSION, _FUNCTION, _SKIPFIRST 등 변형
  • _STREAM 계열: C++ 스트림 스타일
  • 첫 인자로 rclcpp::Logger를 받으며, node->get_logger()로 얻는 것을 권장

Python (rclpy)

  • logger.debug, logger.info, logger.warning, logger.error, logger.fatal
  • 키워드 인자: throttle_duration_sec, skip_first, once
  • rclpy.logging.set_logger_level, rclpy.logging.get_logger_effective_level

C++·Python 모두 동일한 하부 로깅 인프라를 쓰므로 설정은 공통이다.

설정(Configuration)

환경 변수

프로세스 전체에 적용된다(한 프로세스 안의 모든 노드에 동일).

변수역할
ROS_LOG_DIR디스크 로그 디렉터리. 비어 있으면 ROS_HOME으로 $ROS_HOME/.log 경로 구성
ROS_HOME로그·설정 등 ROS 관련 파일의 홈. ~는 사용자 HOME으로 확장
RCUTILS_LOGGING_USE_STDOUT0 또는 미설정이면 stderr, 1이면 stdout
RCUTILS_LOGGING_BUFFERED_STREAM0=unbuffered, 1=line buffered
RCUTILS_COLORIZED_OUTPUT0=색 비활성, 1=색 활성. 미설정 시 TTY 등에 따라 자동
RCUTILS_CONSOLE_OUTPUT_FORMAT출력 형식. {severity}, {name}, {message}, {function_name}, {file_name}, {time}, {date_time_with_ms}, {line_number} 등 사용. 미설정 시 기본: [{severity}] [{time}] [{name}]: {message}

노드 생성 시 옵션

노드별로 다르게 줄 수 있다(한 프로세스에 여러 노드가 있어도 노드마다 설정 가능).

  • 로거 레벨: ros2 run demo_nodes_cpp talker --ros-args --log-level talker:=DEBUG
  • 외부 로그 설정 파일: --log-config-file log-config.txt (백엔드별 형식, 기본 spdlog 백엔드는 미구현)
  • 콘솔 출력 끄기: --disable-stdout-logs
  • /rosout 끄기: --disable-rosout-logs (대역폭 절약, 외부에서 로그 구독 불가)
  • 외부 로거(디스크 기록) 끄기: --disable-external-lib-logs (일부 경우 더 빠르지만 디스크에 안 씀)

로깅 서브시스템 구조

  • rcutils: 메시지 포맷·콘솔 출력. 프로세스 단위 로깅. 상위 레이어가 주입되는 구조.
  • rcl_logging_spdlog: rcl_logging_interface 구현. 포맷된 로그를 디스크 파일에 기록(spdlog 사용, 기본 ~/.ros/log 부근, 설정 가능).
  • rcl: rcutils·rcl_logging_spdlog를 사용해 로그를 콘솔 / 디스크 / /rosout(RMW 경유) 중 설정된 곳으로 전달. 노드마다 조합 다르게 가능.
  • rclcpp / rclpy: 사용자 API(매크로·logger 메서드). 메시지 심각도가 노드 로거 레벨 이상일 때만 포맷·출력. rclcpp는 로그 호출에 전역 뮤텍스를 써서 한 프로세스 내 로깅은 직렬화된다.

사용 예시