diff --git a/ddsrouter_core/test/blackbox/ddsrouter_core/dds/WAN/CMakeLists.txt b/ddsrouter_core/test/blackbox/ddsrouter_core/dds/WAN/CMakeLists.txt index 6920bbb40..3c70390c2 100644 --- a/ddsrouter_core/test/blackbox/ddsrouter_core/dds/WAN/CMakeLists.txt +++ b/ddsrouter_core/test/blackbox/ddsrouter_core/dds/WAN/CMakeLists.txt @@ -71,3 +71,10 @@ add_blackbox_executable( # Set flaky tests as xfail add_xfail_label(${CMAKE_CURRENT_SOURCE_DIR}/TEST_XFAIL.list) + +# Set as TSAN errors due to Fast DDS +# TODO: use a cmake_utils macro +file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/TEST_XTSAN.list TEST_LIST) +foreach(XTSAN_TEST ${TEST_LIST}) + set_property(TEST ${XTSAN_TEST} PROPERTY LABELS xtsan) +endforeach() diff --git a/ddsrouter_core/test/blackbox/ddsrouter_core/dds/WAN/TEST_XTSAN.list b/ddsrouter_core/test/blackbox/ddsrouter_core/dds/WAN/TEST_XTSAN.list new file mode 100644 index 000000000..0640790ee --- /dev/null +++ b/ddsrouter_core/test/blackbox/ddsrouter_core/dds/WAN/TEST_XTSAN.list @@ -0,0 +1,4 @@ +DDSTestWAN.end_to_end_discovery_server_WAN_communication_UDPv4 +DDSTestWAN.end_to_end_discovery_server_WAN_communication_UDPv6 +DDSTestWAN.end_to_end_initial_peers_WAN_communication_UDPv6 +DDSTestWAN.end_to_end_discovery_server_WAN_communication_high_throughput diff --git a/docs/rst/notes/forthcoming_version.rst b/docs/rst/notes/forthcoming_version.rst index 5cd65f076..38179b3e5 100644 --- a/docs/rst/notes/forthcoming_version.rst +++ b/docs/rst/notes/forthcoming_version.rst @@ -1,8 +1,12 @@ - .. add orphan tag when new info added to this file -:orphan: +.. :orphan: ################### Forthcoming Version ################### + +Next release will include the following **features**: + +* New :ref:`user_manual_user_interface_log_verbosity_argument` and :ref:`user_manual_user_interface_log_filter_argument` + arguments to configure *DDS Router* and *Fast DDS* logs shown in application. diff --git a/docs/rst/notes/notes.rst b/docs/rst/notes/notes.rst index ec79d5b93..e4e38b449 100644 --- a/docs/rst/notes/notes.rst +++ b/docs/rst/notes/notes.rst @@ -3,8 +3,8 @@ .. _release_notes: .. comment the include of forthcoming when new info is added -.. - .. include:: forthcoming_version.rst + +.. include:: forthcoming_version.rst ############## Version v1.0.0 diff --git a/docs/rst/user_manual/user_interface.rst b/docs/rst/user_manual/user_interface.rst index c8bf59675..5ee4ca886 100644 --- a/docs/rst/user_manual/user_interface.rst +++ b/docs/rst/user_manual/user_interface.rst @@ -50,6 +50,12 @@ The |ddsrouter| application supports several input arguments: - - + * - :ref:`user_manual_user_interface_version_argument` + - ``-v`` + - ``--version`` + - + - + * - :ref:`user_manual_user_interface_configuration_file_argument` - ``-c`` - ``--config-path`` @@ -60,7 +66,7 @@ The |ddsrouter| application supports several input arguments: - ``-r`` - ``--reload-time`` - Unsigned Integer - - 0 + - ``0`` * - :ref:`user_manual_user_interface_debug_argument` - ``-d`` @@ -68,6 +74,17 @@ The |ddsrouter| application supports several input arguments: - - + * - :ref:`user_manual_user_interface_log_verbosity_argument` + - + - ``--log-verbosity`` + - ``info`` ``warning`` ``error`` + - ``warning`` + + * - :ref:`user_manual_user_interface_log_filter_argument` + - + - ``--log-filter`` + - String + - ``"DDSROUTER"`` .. _user_manual_user_interface_help_argument: @@ -83,14 +100,27 @@ It shows the usage information of the application. It will build a communication bridge between the different Participants included in the provided configuration file. To stop the execution gracefully use SIGINT (C^) or SIGTERM (kill) signals. General options: - -h --help Print this help message. - -c --config-path Path to the Configuration File (yaml format) [Default: ./DDS_ROUTER_CONFIGURATION.yaml]. - -r --reload-time Time period in seconds to reload configuration file. This is needed when File Watcher - functionality is not available (e.g. config file is a symbolic link). - Value 0 does not reload file. [Default: 0]. - -d --debug Activate debug Logs (be aware that some logs may require specific CMAKE compilation options). - -v --version Print version, branch and commit hash. - -t --timeout Set a maximum time in seconds for the Router to run. Value 0 does not set maximum. [Default: 0]. + + Application help and information. + -h --help Print this help message. + -v --version Print version, branch and commit hash. + + Application parameters + -c --config-path Path to the Configuration File (yaml format) [Default: ./DDS_ROUTER_CONFIGURATION.yaml]. + -r --reload-time Time period in seconds to reload configuration file. This is needed when FileWatcher functionality is not available (e.g. config file is a symbolic link). Value 0 does not reload file. [Default: 0]. + -t --timeout Set a maximum time in seconds for the Router to run. Value 0 does not set maximum. [Default: 0]. + + Debug options + -d --debug Set log verbosity to Info (Using this option with --log-filter and/or --log-verbosity will head to undefined behaviour). + --log-filter Set a Regex Filter to filter by category the info and warning log entries. [Default = "DDSROUTER"]. + --log-verbosity Set a Log Verbosity Level higher or equal the one given. (Values accepted: "info","warning","error" no Case Sensitive) [Default = "warning"]. + +.. _user_manual_user_interface_version_argument: + +Version Argument +^^^^^^^^^^^^^^^^ + +It shows the current version of the DDS Router and the hash of the last commit of the compiled code. .. _user_manual_user_interface_configuration_file_argument: @@ -108,41 +138,47 @@ Reload Time Argument Set the :ref:`user_manual_user_interface_reload_timer` in **seconds**. +.. _user_manual_user_interface_timeout_argument: + +Timeout Argument +^^^^^^^^^^^^^^^^ + +This argument allow to set a maximum time while the application will be running. +Setting this argument will set the number of seconds the application will run until it is killed. +While the application is waiting for timeout, it is still possible to kill it via signal. +Default value ``0`` means that the application will run forever (until kill via signal). .. _user_manual_user_interface_debug_argument: Debug Argument ^^^^^^^^^^^^^^ -Activate ``INFO`` and ``DEBUG`` logs for the |ddsrouter| execution. -For this argument to work, the |ddsrouter| must have been compiled with CMake option ``CMAKE_BUILD_TYPE=Debug``, -or compiled with CMake option ``LOG_INFO=ON``. +This argument enables the |ddsrouter| logs so the execution can be followed by internal debugging information. +This argument sets :ref:`user_manual_user_interface_log_verbosity_argument` to ``info`` and +:ref:`user_manual_user_interface_log_filter_argument` to ``DDSROUTER``. +For more information about debugging options, refer to :ref:`user_manual_user_interface_log`. .. note:: - If this option is enabled and Fast DDS has been compiled in debug mode, it will print the logs of the DDS Router - and Fast DDS mixed. - In order to skip Fast DDS logs, compile ``fastrtps`` library with CMake option ``-DLOG_NO_INFO=ON`` - or ``CMAKE_BUILD_TYPE`` different to ``Debug``. + If this argument is used with any of the other arguments of debugging, the behavior depends on the order + of parser of the arguments. +.. _user_manual_user_interface_log_verbosity_argument: -.. _user_manual_user_interface_version_argument: +Log Verbosity Argument +^^^^^^^^^^^^^^^^^^^^^^ -Version Argument -^^^^^^^^^^^^^^^^ +Set the verbosity level so only log messages with equal or higher importance level are shown. -It shows the current version of the DDS Router and the hash of the last commit of the compiled code. +.. _user_manual_user_interface_log_filter_argument: +Log Filter Argument +^^^^^^^^^^^^^^^^^^^ -.. _user_manual_user_interface_timeout_argument: - -Timeout Argument -^^^^^^^^^^^^^^^^ - -This argument allow to set a maximum time while the application will be running. -Setting this argument will set the number of seconds the application will run until it is killed. -While the application is waiting for timeout, it is still possible to kill it via signal. -Default value ``0`` means that the application will run forever (until kill via signal). +Set a regex string as filter. +Only log messages with a category that matches this regex will be printed +(``ERROR`` messages will be always shown unless :ref:`user_manual_user_interface_log_verbosity_argument` is +set to ``ERROR``). .. _user_manual_user_interface_configuration_file: @@ -200,6 +236,41 @@ A timer could be set in order to periodically reload the configuration file. The configuration file will be automatically reloaded according to the specified time period. +.. _user_manual_user_interface_log: + +Log +--- + +Log module of |ddsrouter| uses the |fastdds| logging module. +This log has 3 severity levels: ``INFO``, ``WARNING`` and ``ERROR``. +Every log has also a category associated. +This is how a log looks like: + +.. code:: + + Date Category Severity Log message Function + 2022-11-16 14:58:13.375 [MODULE_SUBMODULE Error] It has happen ... because of ... -> Function main + +Every log entry has several parts: + +- **Date**: format: ``year-month-day hour::minute::second::millisecond`` with millisecond accuracy. + This is the time when the log was added to the log queue, not when it is printed. +- **Category**: Reference to the module where the log was raised. It is used to filter logs. +- **Severity**: Could be ``Info``, ``Warning`` or ``Error``. +- **Log message**: The actual log message. +- **Function**: Name of the function or method that has produced this log entry. + + +.. note:: + + For ``INFO`` logs to be compiled, the |ddsrouter| must have been compiled with CMake option ``CMAKE_BUILD_TYPE=Debug``, + or compiled with CMake option ``LOG_INFO=ON``. + + If Fast DDS has been compiled in debug mode, it will print the logs of the DDS Router and Fast DDS mixed. + In order to skip Fast DDS logs, compile ``fastrtps`` library with CMake option ``-DLOG_NO_INFO=ON`` + or ``CMAKE_BUILD_TYPE`` different to ``Debug``, or use the argument `` + + .. _user_manual_user_interface_close_application: Close Application diff --git a/tools/ddsrouter_tool/src/cpp/main.cpp b/tools/ddsrouter_tool/src/cpp/main.cpp index 37ddadd9b..a1f3b766e 100644 --- a/tools/ddsrouter_tool/src/cpp/main.cpp +++ b/tools/ddsrouter_tool/src/cpp/main.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -50,12 +51,13 @@ int main( // Maximum timeout eprosima::utils::Duration_ms timeout = 0; - // Debug option active - bool activate_debug = false; + // Debug options + std::string log_filter = "DDSROUTER"; + eprosima::fastdds::dds::Log::Kind log_verbosity = eprosima::fastdds::dds::Log::Kind::Warning; // Parse arguments ui::ProcessReturnCode arg_parse_result = - ui::parse_arguments(argc, argv, file_path, reload_time, activate_debug, timeout); + ui::parse_arguments(argc, argv, file_path, reload_time, timeout, log_filter, log_verbosity); if (arg_parse_result == ui::ProcessReturnCode::help_argument) { @@ -92,11 +94,16 @@ int main( logUser(DDSROUTER_EXECUTION, "Starting DDS Router Tool execution."); - // Activate Debug - if (activate_debug) + // Debug { - // Activate log - eprosima::utils::Log::SetVerbosity(eprosima::utils::Log::Kind::Info); + // Remove every consumer + eprosima::utils::Log::ClearConsumers(); + + // Activate log with verbosity, as this will avoid running log thread with not desired kind + eprosima::utils::Log::SetVerbosity(log_verbosity); + + eprosima::utils::Log::RegisterConsumer( + std::make_unique(log_filter, log_verbosity)); // NOTE: // It will not filter any log, so Fast DDS logs will be visible unless Fast DDS is compiled @@ -105,6 +112,7 @@ int main( // Change it when Log Module is independent and with more extensive API. // eprosima::utils::Log::SetCategoryFilter(std::regex("(DDSROUTER)")); } + // Encapsulating execution in block to erase all memory correctly before closing process try { diff --git a/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.cpp b/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.cpp index dcb1b649c..012ca3638 100644 --- a/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.cpp +++ b/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.cpp @@ -46,6 +46,13 @@ const option::Descriptor usage[] = { "General options:" }, + //////////////////// + // Help options + { + optionIndex::UNKNOWN_OPT, 0, "", "", Arg::None, + "\nApplication help and information." + }, + { optionIndex::HELP, 0, @@ -56,6 +63,23 @@ const option::Descriptor usage[] = { "Print this help message." }, + { + optionIndex::VERSION, + 0, + "v", + "version", + Arg::None, + " -v \t--version\t \t" \ + "Print version, branch and commit hash." \ + }, + + //////////////////// + // Application options + { + optionIndex::UNKNOWN_OPT, 0, "", "", Arg::None, + "\nApplication parameters" + }, + { optionIndex::CONFIGURATION_FILE, 0, @@ -76,6 +100,24 @@ const option::Descriptor usage[] = { "Time period in seconds to reload configuration file. " \ "This is needed when FileWatcher functionality is not available (e.g. config file is a symbolic link). " \ "Value 0 does not reload file. [Default: 0]." + + }, + { + optionIndex::TIMEOUT, + 0, + "t", + "timeout", + Arg::Numeric, + " -t \t--timeout\t \t" \ + "Set a maximum time in seconds for the Router to run. " \ + "Value 0 does not set maximum. [Default: 0]." + }, + + //////////////////// + // Debug options + { + optionIndex::UNKNOWN_OPT, 0, "", "", Arg::None, + "\nDebug parameters" }, { @@ -85,26 +127,36 @@ const option::Descriptor usage[] = { "debug", Arg::None, " -d \t--debug\t \t" \ - "Activate debug Logs (be aware that some logs may require specific CMAKE compilation options)." \ + "Set log verbosity to Info \t" \ + "(Using this option with --log-filter and/or --log-verbosity will head to undefined behaviour)." }, + { - optionIndex::VERSION, + optionIndex::LOG_FILTER, 0, - "v", - "version", - Arg::None, - " -v \t--version\t \t" \ - "Print version, branch and commit hash." \ + "", + "log-filter", + Arg::String, + " \t--log-filter\t \t" \ + "Set a Regex Filter to filter by category the info and warning log entries. " \ + "[Default = \"DDSROUTER\"]. " }, + { - optionIndex::TIMEOUT, + optionIndex::LOG_VERBOSITY, 0, - "t", - "timeout", - Arg::Numeric, - " -t \t--timeout\t \t" \ - "Set a maximum time in seconds for the Router to run. " \ - "Value 0 does not set maximum. [Default: 0]." + "", + "log-verbosity", + Arg::Log_Kind_Correct_Argument, + " \t--log-verbosity\t \t" \ + "Set a Log Verbosity Level higher or equal the one given. " \ + "(Values accepted: \"info\",\"warning\",\"error\" no Case Sensitive) " \ + "[Default = \"warning\"]. " + }, + + { + optionIndex::UNKNOWN_OPT, 0, "", "", Arg::None, + "\n" }, { 0, 0, 0, 0, 0, 0 } @@ -121,8 +173,9 @@ ProcessReturnCode parse_arguments( char** argv, std::string& file_path, utils::Duration_ms& reload_time, - bool& activate_debug, - utils::Duration_ms& timeout) + utils::Duration_ms& timeout, + std::string& log_filter, + eprosima::fastdds::dds::Log::Kind& log_verbosity) { // Variable to pretty print usage help int columns; @@ -196,13 +249,22 @@ ProcessReturnCode parse_arguments( break; case optionIndex::ACTIVATE_DEBUG: - activate_debug = true; + log_filter = "DDSROUTER"; + log_verbosity = eprosima::fastdds::dds::Log::Kind::Info; break; case optionIndex::TIMEOUT: timeout = std::stol(opt.arg) * 1000; // pass to milliseconds break; + case optionIndex::LOG_FILTER: + log_filter = opt.arg; + break; + + case optionIndex::LOG_VERBOSITY: + log_verbosity = eprosima::fastdds::dds::Log::Kind(static_cast(from_string_LogKind(opt.arg))); + break; + case optionIndex::UNKNOWN_OPT: logError(DDSROUTER_ARGS, opt << " is not a valid argument."); option::printUsage(fwrite, stdout, usage, columns); @@ -326,6 +388,47 @@ option::ArgStatus Arg::Readable_File( return option::ARG_ILLEGAL; } +option::ArgStatus Arg::Log_Kind_Correct_Argument( + const option::Option& option, + bool msg) +{ + return Arg::Valid_Options(string_vector_LogKind(), option, msg); +} + +option::ArgStatus Arg::Valid_Options( + const std::vector& valid_options, + const option::Option& option, + bool msg) +{ + if (nullptr == option.arg) + { + if (msg) + { + logError(DDSROUTER_ARGS, "Option '" << option.name << "' requires a text argument."); + } + return option::ARG_ILLEGAL; + } + + if (std::find(valid_options.begin(), valid_options.end(), std::string(option.arg)) != valid_options.end()) + { + return option::ARG_OK; + } + else if (msg) + { + utils::Formatter error_msg; + error_msg << "Option '" << option.name << "' requires a one of this values: {"; + for (const auto& valid_option : valid_options) + { + error_msg << "\"" << valid_option << "\";"; + } + error_msg << "}."; + + logError(DDSROUTER_ARGS, error_msg); + } + + return option::ARG_ILLEGAL; +} + std::ostream& operator <<( std::ostream& output, const option::Option& option) diff --git a/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.hpp b/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.hpp index 7b3d9b03f..f1468110d 100644 --- a/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.hpp +++ b/tools/ddsrouter_tool/src/cpp/user_interface/arguments_configuration.hpp @@ -24,6 +24,7 @@ #include +#include #include #include "ProcessReturnCode.hpp" @@ -72,12 +73,22 @@ struct Arg : public option::Arg static option::ArgStatus Readable_File( const option::Option& option, bool msg); + + //! Check that the argument is an option of kind + static option::ArgStatus Log_Kind_Correct_Argument( + const option::Option& option, + bool msg); + + static option::ArgStatus Valid_Options( + const std::vector& valid_options, + const option::Option& option, + bool msg); }; /* * Option arguments available */ -enum optionIndex +enum optionIndex { UNKNOWN_OPT, HELP, @@ -86,6 +97,8 @@ enum optionIndex ACTIVATE_DEBUG, VERSION, TIMEOUT, + LOG_FILTER, + LOG_VERBOSITY, }; /** @@ -117,8 +130,9 @@ ProcessReturnCode parse_arguments( char** argv, std::string& file_path, utils::Duration_ms& reload_time, - bool& activate_debug, - utils::Duration_ms& timeout); + utils::Duration_ms& timeout, + std::string& log_filter, + eprosima::fastdds::dds::Log::Kind& log_verbosity); //! \c Option to stream serializator std::ostream& operator <<( @@ -130,6 +144,13 @@ std::ostream& operator <<( */ void print_version(); +ENUMERATION_BUILDER( + LogKind, + error, + warning, + info + ); + } /* namespace ui */ } /* namespace ddsrouter */ } /* namespace eprosima */