Skip to content

Commit

Permalink
support basic colcon test. (#19)
Browse files Browse the repository at this point in the history
* support basic colcon test.

Signed-off-by: Tomoya Fujita <[email protected]>

* add logging file and contents check via rsyslog test conf.

Signed-off-by: Tomoya Fujita <[email protected]>

* add test section in README.

Signed-off-by: Tomoya Fujita <[email protected]>

---------

Signed-off-by: Tomoya Fujita <[email protected]>
  • Loading branch information
fujitatomoya authored Sep 25, 2024
1 parent 2c3ed2f commit ae29c87
Show file tree
Hide file tree
Showing 5 changed files with 503 additions and 34 deletions.
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# cppcheck 1.90 doesn't understand some of the syntax in spdlog's bundled fmt
# code. Since we already have cppcheck disabled on Linux, just disable it
# completely for this package.
list(APPEND AMENT_LINT_AUTO_EXCLUDE
ament_cmake_cppcheck
)
ament_lint_auto_find_test_dependencies()

find_package(ament_cmake_gtest REQUIRED)
ament_add_gmock(test_logging_interface test/test_logging_interface.cpp)
if(TARGET test_logging_interface)
target_link_libraries(test_logging_interface ${PROJECT_NAME} rcpputils::rcpputils)
target_compile_definitions(test_logging_interface PUBLIC RCUTILS_ENABLE_FAULT_INJECTION)
endif()
endif()

ament_export_libraries(${PROJECT_NAME})
ament_export_targets(${PROJECT_NAME})
ament_package()
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ export RCL_LOGGING_IMPLEMENTATION=rcl_logging_syslog
colcon build --symlink-install --cmake-clean-cache --packages-select rcl_logging_syslog rcl
```

### Test

Following to the previous build procedure, we need to copy [ros2-test.conf](./config/ros2-test.conf) to `/etc/rsyslog.d/`, and restart the `rsyslog`.

```bash
sudo cp ./config/ros2-test.conf /etc/rsyslog.d/
```

Then we can start the `colcon test`:

This test creates and uses `/var/log/rcl_logging_syslog` directory in temporary for the test, and it checks the file existence and contents using `rcl_logging_syslog`.

```bash
colcon test --event-handlers console_direct+ --packages-select rcl_logging_syslog
```

### Configuration

[SYSLOG(3)](https://man7.org/linux/man-pages/man3/syslog.3.html) is really simple that does not have much interfaces to control on application side, it just writes the log data on `rsyslog` Unix Domain Socket.
Expand All @@ -128,7 +144,7 @@ See more details for https://www.rsyslog.com/doc/index.html.

#### `rsyslog`

Copy [ros-logging.conf](./config/ros2-logging.conf) to `/etc/rsyslog.d/`, and replace `<FLUENTBIT_IP>` with your own IP address where `fluent-bit` listens on.
Copy [ros2-logging.conf](./config/ros2-logging.conf) to `/etc/rsyslog.d/`, and replace `<FLUENTBIT_IP>` with your own IP address where `fluent-bit` listens on.

```bash
sudo cp ./config/ros2-logging.conf /etc/rsyslog.d/
Expand Down
23 changes: 23 additions & 0 deletions config/ros2-test.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# ROS Test Setting
#
# This is an test configuration file for for rcl_logging_syslog.
#
# For more information install rsyslog-doc and see
# /usr/share/doc/rsyslog-doc/html/configuration/index.html
#

# Test Message Format Template
# See more details for https://www.rsyslog.com/doc/configuration/properties.html
#$template TestFormat,"%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$template TestFormat,"%msg:2:$%\n"

# Directory and File Name Test Template
# See more details for https://www.rsyslog.com/doc/configuration/properties.html
### e.g) /var/log/rcl_logging_syslog/test_logging_interface_1405655_1727291103.log
$template TestFileName,"/var/log/rcl_logging_syslog/%programname%_%procid%_%$now-unixtimestamp%.log"

# Log locally with specified templated file name.
local1.* ?TestFileName;TestFormat
local2.* ?TestFileName;TestFormat
local3.* ?TestFileName;TestFormat
69 changes: 36 additions & 33 deletions src/rcl_logging_syslog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <syslog.h>

#include <memory>
#include <system_error>

#include <rcl_logging_interface/rcl_logging_interface.h>

#include <rcpputils/env.hpp>
#include <rcpputils/scope_exit.hpp>
#include "rcpputils/env.hpp"
#include "rcpputils/scope_exit.hpp"

#include <rcutils/allocator.h>
#include <rcutils/logging.h>
#include "rcutils/allocator.h"
#include "rcutils/logging.h"
#include "rcutils/logging_macros.h"
#include "rcutils/process.h"
#include <rcutils/snprintf.h>
#include <rcutils/strdup.h>
#include <rcutils/time.h>
#include "rcutils/snprintf.h"
#include "rcutils/strdup.h"
#include "rcutils/time.h"

#include "rcl_logging_interface/rcl_logging_interface.h"

static const char * facility_env_name = "RCL_LOGGING_SYSLOG_FACILITY";

Expand All @@ -41,33 +41,35 @@ static std::shared_ptr<std::string> syslog_identity;

static const char *logger_name = "rcl_logging_syslog";

typedef struct facility_index {
typedef struct facility_index
{
const char *c_name;
const int c_value;
} FACILITY_INDEX;

const FACILITY_INDEX facility_table[] =
{
{ "LOG_CRON", LOG_CRON },
{ "LOG_DAEMON", LOG_DAEMON },
{ "LOG_SYSLOG", LOG_SYSLOG },
{ "LOG_USER", LOG_USER },
{ "LOG_LOCAL0", LOG_LOCAL0 },
{ "LOG_LOCAL1", LOG_LOCAL1 },
{ "LOG_LOCAL2", LOG_LOCAL2 },
{ "LOG_LOCAL3", LOG_LOCAL3 },
{ "LOG_LOCAL4", LOG_LOCAL4 },
{ "LOG_LOCAL5", LOG_LOCAL5 },
{ "LOG_LOCAL6", LOG_LOCAL6 },
{ "LOG_LOCAL7", LOG_LOCAL7 },
{ NULL, -1 }
};

static const char *get_facility_name(int facility) {
{
{"LOG_CRON", LOG_CRON},
{"LOG_DAEMON", LOG_DAEMON},
{"LOG_SYSLOG", LOG_SYSLOG},
{"LOG_USER", LOG_USER},
{"LOG_LOCAL0", LOG_LOCAL0},
{"LOG_LOCAL1", LOG_LOCAL1},
{"LOG_LOCAL2", LOG_LOCAL2},
{"LOG_LOCAL3", LOG_LOCAL3},
{"LOG_LOCAL4", LOG_LOCAL4},
{"LOG_LOCAL5", LOG_LOCAL5},
{"LOG_LOCAL6", LOG_LOCAL6},
{"LOG_LOCAL7", LOG_LOCAL7},
{NULL, -1}
};

static const char * get_facility_name(int facility)
{
for (auto f = facility_table; f->c_name != NULL; f++) {
if (f->c_value == facility) {
return f->c_name;
}
if (f->c_value == facility) {
return f->c_name;
}
}
return "Unknown facility";
}
Expand Down Expand Up @@ -137,7 +139,8 @@ static int rcutil_to_syslog_level(int rcutil_level)
return syslog_level;
}

[[maybe_unused]] static void vlog_msg(int level, const char *format, ...) {
[[maybe_unused]] static void vlog_msg(int level, const char *format, ...)
{
va_list args;
va_start(args, format);
vsyslog(level, format, args);
Expand Down Expand Up @@ -170,7 +173,7 @@ rcl_logging_ret_t rcl_logging_external_initialize(
char * logdir = nullptr;
rcl_logging_ret_t dir_ret = rcl_logging_get_logging_directory(allocator, &logdir);
if (RCL_LOGGING_RET_OK != dir_ret) {
RCUTILS_SET_ERROR_MSG("Failed to get logging directory");
RCUTILS_SET_ERROR_MSG_AND_APPEND_PREV_ERROR("Failed to get logging directory");
return dir_ret;
} else {
// rsyslog does not allow user to create or specify logging directory via API.
Expand Down
Loading

0 comments on commit ae29c87

Please sign in to comment.