|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | rolling |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged rcl_logging_journal at Robotics Stack Exchange
|
rcl_logging_journal package from rcl_logging_journal reporcl_logging_journal |
ROS Distro
|
Package Summary
| Version | 0.1.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/fujitatomoya/rcl_logging_journal.git |
| VCS Type | git |
| VCS Version | lyrical |
| Last Updated | 2026-09-14 |
| Dev Status | MAINTAINED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Tomoya Fujita
Authors
- Tomoya Fujita
rcl_logging_journal 📓🔍🐧
rcl_logging_journal is an alternative logging backend implementation that can be used for ROS 2 applications via rcl_logging_interface.
rcl_logging_journal uses the journald native protocol (sd_journal_sendv(3)) to write structured, indexed log records straight into systemd-journald, the system journal that is already running on every systemd based Linux host.
The main objective is Enabling ROS 2 logging with the native Linux system journal: per-node filtering with journalctl, built-in rotation and retention, structured binary storage, zero additional daemons or configuration.
See the overview slide deck and the design document for more information.
Motivation
ROS 2 ships no tool to consume its logs. The default rcl_logging_spdlog backend writes one text file per process under ~/.ros/log, and from there it is grep, less and a home grown logrotate job. Correlating several nodes, filtering by severity over a time window, or looking at what happened right before a robot rebooted is manual work every time.
Linux already has that tool: journalctl. rcl_logging_journal makes ROS 2 log records first class journal entries:
- every record carries indexed fields (
ROS2_NODE_NAME,PRIORITY,SYSLOG_IDENTIFIER,ROS2_DISTRO, your own fleet fields), sojournalctl ROS2_NODE_NAME=talkeris an index lookup, not a text scan; - journald adds trusted metadata (
_PID,_UID,_COMM,_EXE,_BOOT_ID,_HOSTNAME) from kernel credentials, nothing the client can spoof; - rotation, size and time based retention, vacuuming, compression and field deduplication are built in and configured once in
journald.conf(5); -
journalctl -b -1shows the previous boot, JSON export is one flag away, and the same files can be shipped to a fleet collector withsystemd-journal-remote; - containers log into the host journal by binding one socket, no daemon inside the image.
The major difference from rcl_logging_syslog is on the consumption side: log records live in the system storage managed by journald, and developers can use standard utilities such as journalctl to see, filter and export them right away. There is no log directory to manage, no rotation to configure, nothing to clean up.
The log pipeline capability of rcl_logging_syslog (rsyslog to FluentBit / Fluentd / Loki / remote collectors) is not lost with journald. Both FluentBit (systemd input) and Fluentd (fluent-plugin-systemd) read the journal directly, so the same architecture can be built on top of rcl_logging_journal, with the ROS 2 fields already structured instead of parsed from text. Forwarding is not covered in this version yet, that is a temporary limitation and it is planned to be supported just like in rcl_logging_syslog. See design.md for a feature by feature comparison.
Demonstration
See how it works 🔥
https://github.com/user-attachments/assets/df6aa765-af66-480f-aa2f-e06c7c232e02
export RCL_LOGGING_IMPLEMENTATION=rcl_logging_journal
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener &
journalctl -f ROS2_NODE_NAME=talker
Sep 07 10:15:01 robot-07 talker[3141]: [INFO] [1757236501.620827927] [talker]: Publishing: 'Hello World: 1'
Sep 07 10:15:02 robot-07 talker[3141]: [INFO] [1757236502.620758249] [talker]: Publishing: 'Hello World: 2'
Sep 07 10:15:03 robot-07 talker[3141]: [INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
journalctl ROS2_NODE_NAME=talker -o verbose -n 1
Sun 2026-09-07 10:15:03.620812 JST [s=8a9b5ca9...;i=1a3;b=376ab38e...;m=f37f7688;t=65addc52cde52;x=4332bb0b]
_TRANSPORT=journal
_PID=3141
_UID=1000
_GID=1000
_COMM=talker
_EXE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_CMDLINE=/opt/ros/rolling/lib/demo_nodes_cpp/talker
_BOOT_ID=376ab38eebb14eedb2304ad5aa7f5f0e
_MACHINE_ID=5e01c53d9dd64ba6b52d4a50543ef4e8
_HOSTNAME=robot-07
PRIORITY=6
ROS2_NODE_NAME=talker
SYSLOG_IDENTIFIER=talker
ROS2_DISTRO=rolling
MESSAGE=[INFO] [1757236503.620777277] [talker]: Publishing: 'Hello World: 3'
Tutorials
- journalctl basics for ROS 2 logs: per-node filtering, severities, time windows and boots, JSON export, vacuum.
-
ROS 2 in a container, logs in the host journal: bind
/run/systemd/journal/socket. -
Rate limits and retention for robots:
journald.conftuning and the shipped drop-in.
Supported ROS Distribution
| Distribution | Supported | Branch | Dynamic Loading |
|---|---|---|---|
| Rolling Ridley | ✅ |
rolling (Development) |
✅ |
| Lyrical Luth | ✅ | lyrical |
✅ |
| Kilted Kaiju | ✅ | kilted |
❌ |
| Jazzy Jalisco | ✅ | jazzy |
❌ |
| Humble Hawksbill | ✅ | humble |
❌ |
Linux with systemd is required at runtime (Ubuntu, Debian, Fedora, …). The package does not build on Windows or macOS.
rcl_logging_implementation
Starting with Lyrical Luth, ROS 2 introduces rcl_logging_implementation, a package that enables runtime dynamic loading of logging backends, similar to how rmw_implementation works for middleware selection.
This abstraction layer allows users to switch between different logging implementations (such as rcl_logging_spdlog, rcl_logging_noop, rcl_logging_syslog or rcl_logging_journal) without rebuilding RCL or application code.
See the ROS 2 Logging Documentation for more details.
Runtime Dynamic Loading vs Static Linking
File truncated at 100 lines see the full file
Changelog for package rcl_logging_journal
0.1.0 (unreleased)
- Initial implementation of the rcl_logging_interface on top of the systemd-journald native protocol (sd_journal_sendv).
- Structured record schema: MESSAGE, PRIORITY, SYSLOG_IDENTIFIER, ROS2_NODE_NAME, ROS2_DISTRO and user defined extra fields.
- Asynchronous hot path: records are copied into a preallocated ring buffer and sent to journald by one sender thread; FATAL stays synchronous; no severity filtering in the backend (rcl and journald MaxLevelStore= do that).
- Environment configuration: RCL_LOGGING_JOURNAL_IDENTIFIER, RCL_LOGGING_JOURNAL_EXTRA_FIELDS, RCL_LOGGING_JOURNAL_STRICT, RCL_LOGGING_JOURNAL_SOCKET_PATH, RCL_LOGGING_JOURNAL_BUFFER_SIZE (ring buffer capacity, 1 MiB by default).
- gtest suite reading records back through the sd_journal API and journalctl.
- GitHub workflows per distribution with a standalone journald in the container, Mergify backports, codespell, stale and ABI checks.
- Design document, journalctl / container / retention tutorials, overview deck.
- Benchmark harness comparing the spdlog and journald backends.
- Contributors: Tomoya Fujita
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake_ros | |
| ament_cmake_gtest | |
| ament_lint_auto | |
| ament_lint_common | |
| performance_test_fixture | |
| rcl_logging_interface | |
| rcpputils | |
| rcutils |