diff --git a/rclpy/rclpy/logging.py b/rclpy/rclpy/logging.py index dc0fa97ff..9f2c86022 100644 --- a/rclpy/rclpy/logging.py +++ b/rclpy/rclpy/logging.py @@ -65,3 +65,8 @@ def set_logger_level(name, level): def get_logger_effective_level(name): logger_level = _rclpy_logging.rclpy_logging_get_logger_effective_level(name) return LoggingSeverity(logger_level) + + +def get_logging_severity_from_string(log_severity): + return LoggingSeverity( + _rclpy_logging.rclpy_logging_severity_level_from_string(log_severity)) diff --git a/rclpy/src/rclpy/_rclpy_logging.c b/rclpy/src/rclpy/_rclpy_logging.c index c339de9d2..7860f4550 100644 --- a/rclpy/src/rclpy/_rclpy_logging.c +++ b/rclpy/src/rclpy/_rclpy_logging.c @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -169,6 +170,35 @@ rclpy_logging_rcutils_log(PyObject * Py_UNUSED(self), PyObject * args) Py_RETURN_NONE; } +/// Get the log severity based on the log level string representation +/** + * Raises RuntimeError if an invalid log level name is given. + * Raises ValueError if log level is not a string. + * + * \param[in] log_level Name of the log level. + * \return NULL on failure + Log level associated with the string representation + */ +static PyObject * +rclpy_logging_severity_level_from_string(PyObject * Py_UNUSED(self), PyObject * args) +{ + int severity; + const char * log_level = NULL; + if (!PyArg_ParseTuple(args, "s", &log_level)) { + return NULL; + } + rcutils_allocator_t allocator = rcutils_get_default_allocator(); + rcutils_ret_t ret = rcutils_logging_severity_level_from_string(log_level, allocator, &severity); + if (ret != RCUTILS_RET_OK) { + PyErr_Format(PyExc_RuntimeError, + "Failed to get log severity from name \"%s\", return code: %d\n", + log_level, ret); + rcutils_reset_error(); + return NULL; + } + return PyLong_FromLongLong(severity); +} + /// Define the public methods of this module static PyMethodDef rclpy_logging_methods[] = { { @@ -196,6 +226,10 @@ static PyMethodDef rclpy_logging_methods[] = { "rclpy_logging_rcutils_log", rclpy_logging_rcutils_log, METH_VARARGS, "Log a message with the specified severity" }, + { + "rclpy_logging_severity_level_from_string", rclpy_logging_severity_level_from_string, + METH_VARARGS, "Determine log level from string" + }, {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/rclpy/test/test_logging.py b/rclpy/test/test_logging.py index 6843e0ae5..6e03fc159 100644 --- a/rclpy/test/test_logging.py +++ b/rclpy/test/test_logging.py @@ -359,6 +359,15 @@ def test_clear_config(self): rclpy.logging._root_logger.get_effective_level(), my_logger.get_effective_level()) + def test_logging_severity_from_string(self): + for severity in rclpy.logging.LoggingSeverity: + self.assertEqual( + rclpy.logging.get_logging_severity_from_string(severity.name), severity) + + def test_nonexistent_logging_severity_from_string(self): + with self.assertRaises(RuntimeError): + rclpy.logging.get_logging_severity_from_string('non_existent_severity') + if __name__ == '__main__': unittest.main()