diff --git a/rclpy/CMakeLists.txt b/rclpy/CMakeLists.txt
index c9339adb7..2c93c8e3e 100644
--- a/rclpy/CMakeLists.txt
+++ b/rclpy/CMakeLists.txt
@@ -17,6 +17,7 @@ endif()
find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED)
find_package(rcl REQUIRED)
+find_package(rcl_logging_interface REQUIRED)
find_package(rcl_action REQUIRED)
find_package(rcl_yaml_param_parser REQUIRED)
find_package(rcutils REQUIRED)
@@ -142,6 +143,7 @@ add_library(
configure_python_c_extension_library(rclpy_logging)
ament_target_dependencies(rclpy_logging
"rcutils"
+ "rcl_logging_interface"
)
# Signal handling library
diff --git a/rclpy/package.xml b/rclpy/package.xml
index 8fda0974b..d06bba679 100644
--- a/rclpy/package.xml
+++ b/rclpy/package.xml
@@ -22,6 +22,7 @@
rmw_implementation
rcl
+ rcl_logging_interface
rcl_action
rcl_yaml_param_parser
unique_identifier_msgs
diff --git a/rclpy/rclpy/logging.py b/rclpy/rclpy/logging.py
index b3d98de0e..224127a8e 100644
--- a/rclpy/rclpy/logging.py
+++ b/rclpy/rclpy/logging.py
@@ -14,6 +14,7 @@
from enum import IntEnum
+from pathlib import Path
from rclpy.impl.implementation_singleton import rclpy_logging_implementation as _rclpy_logging
import rclpy.impl.rcutils_logger
@@ -70,3 +71,13 @@ def get_logger_effective_level(name):
def get_logging_severity_from_string(log_severity):
return LoggingSeverity(
_rclpy_logging.rclpy_logging_severity_level_from_string(log_severity))
+
+
+def get_logging_directory() -> Path:
+ """
+ Return the current logging directory being used.
+
+ For more details, see .. c:function::
+ rcl_logging_ret_t rcl_logging_get_logging_directory(rcutils_allocator_t, char **)
+ """
+ return Path(_rclpy_logging.rclpy_logging_get_logging_directory())
diff --git a/rclpy/src/rclpy/_rclpy_logging.c b/rclpy/src/rclpy/_rclpy_logging.c
index b76cbe2ae..0e98c2a49 100644
--- a/rclpy/src/rclpy/_rclpy_logging.c
+++ b/rclpy/src/rclpy/_rclpy_logging.c
@@ -19,6 +19,8 @@
#include
#include
+#include
+
/// Initialize the logging system.
/**
* \return None or
@@ -254,6 +256,27 @@ rclpy_get_fatal_logging_severity(PyObject * Py_UNUSED(self), PyObject * Py_UNUSE
return PyLong_FromLongLong(RCUTILS_LOG_SEVERITY_FATAL);
}
+/// Get the current logging directory from rcutils.
+/// \return Unicode UTF8 object containing the current logging directory.
+static PyObject *
+rclpy_logging_get_logging_directory(PyObject * Py_UNUSED(self), PyObject * Py_UNUSED(args))
+{
+ char * log_dir = NULL;
+ rcutils_allocator_t allocator = rcutils_get_default_allocator();
+ rcl_logging_ret_t ret = rcl_logging_get_logging_directory(allocator, &log_dir);
+ if (RCL_LOGGING_RET_OK != ret) {
+ PyErr_Format(
+ PyExc_RuntimeError,
+ "Failed to get current logging directory, error: \"%s\", return code: \"%d\"\n",
+ rcutils_get_error_string().str, ret);
+ rcutils_reset_error();
+ return NULL;
+ }
+ PyObject * py_log_dir = PyUnicode_DecodeFSDefault(log_dir);
+ allocator.deallocate(log_dir, allocator.state);
+ return py_log_dir;
+}
+
/// Define the public methods of this module
static PyMethodDef rclpy_logging_methods[] = {
{
@@ -309,6 +332,10 @@ static PyMethodDef rclpy_logging_methods[] = {
"rclpy_get_fatal_logging_severity", rclpy_get_fatal_logging_severity,
METH_VARARGS, "Get log fatal severity level as int from rcutils"
},
+ {
+ "rclpy_logging_get_logging_directory", rclpy_logging_get_logging_directory,
+ METH_VARARGS, "Get the current logging directory from rcutils"
+ },
{NULL, NULL, 0, NULL} /* sentinel */
};
diff --git a/rclpy/test/test_logging.py b/rclpy/test/test_logging.py
index 6e03fc159..6f097fca7 100644
--- a/rclpy/test/test_logging.py
+++ b/rclpy/test/test_logging.py
@@ -13,6 +13,8 @@
# limitations under the License.
import inspect
+import os
+from pathlib import Path
import time
import unittest
@@ -368,6 +370,15 @@ def test_nonexistent_logging_severity_from_string(self):
with self.assertRaises(RuntimeError):
rclpy.logging.get_logging_severity_from_string('non_existent_severity')
+ def test_get_logging_directory(self):
+ os.environ['HOME'] = '/fake_home_dir'
+ os.environ.pop('USERPROFILE', None)
+ os.environ.pop('ROS_LOG_DIR', None)
+ os.environ.pop('ROS_HOME', None)
+ log_dir = rclpy.logging.get_logging_directory()
+ assert isinstance(log_dir, Path)
+ assert log_dir == Path('/fake_home_dir') / '.ros' / 'log'
+
if __name__ == '__main__':
unittest.main()