Add Logger class and give one to nodes (#411)
* Add Logger class and give one to nodes * Try to improve compiler errors when non-Logger is passed to macros * Add define for 'disabling' loggers * Add/update tests * Linter fix * Documentation * Windows fix * Move free functions to source file (windows was upset) * Fix windows by changing prototype ordering * Store node logger in NodeBase * Windows is not happy with this EXPECT_ANY_THROW * Move get_logger to a NodeLogger interface * Move Logger into 'logger' namespace * Move helper function for macro errors into macro header * Remove 'logger' namespace * Return type on separate line * Update copyright year * Give lifecycle nodes a logger * Add test for lifecycle node logger Move the default_state_machine tests to another file because having different test fixtures was causing init to be called twice. * Switch to static_assert for logger check * global ns scope in macro calls just in case * Revert "Add test for lifecycle node logger" (make diff smaller) demos use the loggers and we don't test other node stuff in lifecycle_node * Update for rcutils function name change * Add reference to Node::get_logger() in doxygen * Rename NodeLoggerInterface to NodeLoggingInterface
This commit is contained in:
parent
d989bd15c1
commit
2e4e85f141
15 changed files with 424 additions and 39 deletions
|
@ -45,12 +45,14 @@ set(${PROJECT_NAME}_SRCS
|
|||
src/rclcpp/graph_listener.cpp
|
||||
src/rclcpp/intra_process_manager.cpp
|
||||
src/rclcpp/intra_process_manager_impl.cpp
|
||||
src/rclcpp/logger.cpp
|
||||
src/rclcpp/memory_strategies.cpp
|
||||
src/rclcpp/memory_strategy.cpp
|
||||
src/rclcpp/node.cpp
|
||||
src/rclcpp/node_interfaces/node_base.cpp
|
||||
src/rclcpp/node_interfaces/node_clock.cpp
|
||||
src/rclcpp/node_interfaces/node_graph.cpp
|
||||
src/rclcpp/node_interfaces/node_logging.cpp
|
||||
src/rclcpp/node_interfaces/node_parameters.cpp
|
||||
src/rclcpp/node_interfaces/node_services.cpp
|
||||
src/rclcpp/node_interfaces/node_timers.cpp
|
||||
|
@ -297,6 +299,9 @@ if(BUILD_TESTING)
|
|||
target_link_libraries(test_executor ${PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
ament_add_gtest(test_logger test/test_logger.cpp)
|
||||
target_link_libraries(test_logger ${PROJECT_NAME})
|
||||
|
||||
ament_add_gmock(test_logging test/test_logging.cpp)
|
||||
target_link_libraries(test_logging ${PROJECT_NAME})
|
||||
|
||||
|
|
131
rclcpp/include/rclcpp/logger.hpp
Normal file
131
rclcpp/include/rclcpp/logger.hpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2017 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef RCLCPP__LOGGER_HPP_
|
||||
#define RCLCPP__LOGGER_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "rclcpp/visibility_control.hpp"
|
||||
|
||||
/**
|
||||
* \def RCLCPP_LOGGING_ENABLED
|
||||
* When this define evaluates to true (default), logger factory functions will
|
||||
* behave normally.
|
||||
* When false, logger factory functions will create dummy loggers to avoid
|
||||
* computational expense in manipulating objects.
|
||||
* This should be used in combination with `RCLCPP_LOG_MIN_SEVERITY` to compile
|
||||
* out logging macros.
|
||||
*/
|
||||
// TODO(dhood): determine this automatically from `RCLCPP_LOG_MIN_SEVERITY`
|
||||
#ifndef RCLCPP_LOGGING_ENABLED
|
||||
#define RCLCPP_LOGGING_ENABLED 1
|
||||
#endif
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
|
||||
// Forward declaration is used for friend statement.
|
||||
namespace node_interfaces
|
||||
{
|
||||
class NodeLogging;
|
||||
}
|
||||
|
||||
class Logger;
|
||||
|
||||
/// Return a named logger.
|
||||
/**
|
||||
* The returned logger's name will include any naming conventions, such as a
|
||||
* name prefix.
|
||||
* Currently there are no such naming conventions but they may be introduced in
|
||||
* the future.
|
||||
*
|
||||
* \param[in] name the name of the logger
|
||||
* \return a logger with the fully-qualified name including naming conventions, or
|
||||
* \return a dummy logger if logging is disabled.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
Logger
|
||||
get_logger(const std::string & name);
|
||||
|
||||
class Logger
|
||||
{
|
||||
private:
|
||||
friend Logger rclcpp::get_logger(const std::string & name);
|
||||
friend ::rclcpp::node_interfaces::NodeLogging;
|
||||
|
||||
/// Constructor of a dummy logger.
|
||||
/**
|
||||
* This is used when logging is disabled: see `RCLCPP_LOGGING_ENABLED`.
|
||||
* This cannot be called directly, see `rclcpp::get_logger` instead.
|
||||
*/
|
||||
Logger()
|
||||
: name_(nullptr) {}
|
||||
|
||||
/// Constructor of a named logger.
|
||||
/**
|
||||
* This cannot be called directly, see `rclcpp::get_logger` instead.
|
||||
*/
|
||||
explicit Logger(const std::string & name)
|
||||
: name_(new std::string(name)) {}
|
||||
|
||||
std::shared_ptr<const std::string> name_;
|
||||
|
||||
public:
|
||||
RCLCPP_PUBLIC
|
||||
Logger(const Logger &) = default;
|
||||
|
||||
/// Get the name of this logger.
|
||||
/**
|
||||
* \return the full name of the logger including any prefixes, or
|
||||
* \return `nullptr` if this logger is invalid (e.g. because logging is
|
||||
* disabled).
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
const char *
|
||||
get_name() const
|
||||
{
|
||||
if (!name_) {
|
||||
return nullptr;
|
||||
}
|
||||
return name_->c_str();
|
||||
}
|
||||
|
||||
/// Return a logger that is a descendant of this logger.
|
||||
/**
|
||||
* The child logger's full name will include any hierarchy conventions that
|
||||
* indicate it is a descendant of this logger.
|
||||
* For example, ```get_logger('abc').get_child('def')``` will return a logger
|
||||
* with name `abc.def`.
|
||||
*
|
||||
* \param[in] suffix the child logger's suffix
|
||||
* \return a logger with the fully-qualified name including the suffix, or
|
||||
* \return a dummy logger if this logger is invalid (e.g. because logging is
|
||||
* disabled).
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
Logger
|
||||
get_child(const std::string & suffix)
|
||||
{
|
||||
if (!name_) {
|
||||
return Logger();
|
||||
}
|
||||
return Logger(*name_ + "." + suffix);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rclcpp
|
||||
|
||||
#endif // RCLCPP__LOGGER_HPP_
|
|
@ -37,11 +37,13 @@
|
|||
#include "rclcpp/client.hpp"
|
||||
#include "rclcpp/context.hpp"
|
||||
#include "rclcpp/event.hpp"
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rclcpp/macros.hpp"
|
||||
#include "rclcpp/message_memory_strategy.hpp"
|
||||
#include "rclcpp/node_interfaces/node_base_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_clock_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_graph_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_logging_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_parameters_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_services_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_timers_interface.hpp"
|
||||
|
@ -108,6 +110,12 @@ public:
|
|||
const char *
|
||||
get_namespace() const;
|
||||
|
||||
/// Get the logger of the node.
|
||||
/** \return The logger of the node. */
|
||||
RCLCPP_PUBLIC
|
||||
rclcpp::Logger
|
||||
get_logger() const;
|
||||
|
||||
/// Create and return a callback group.
|
||||
RCLCPP_PUBLIC
|
||||
rclcpp::callback_group::CallbackGroup::SharedPtr
|
||||
|
@ -412,6 +420,7 @@ private:
|
|||
|
||||
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_;
|
||||
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_;
|
||||
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_;
|
||||
rclcpp::node_interfaces::NodeTimersInterface::SharedPtr node_timers_;
|
||||
rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_;
|
||||
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_;
|
||||
|
|
61
rclcpp/include/rclcpp/node_interfaces/node_logging.hpp
Normal file
61
rclcpp/include/rclcpp/node_interfaces/node_logging.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2017 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef RCLCPP__NODE_INTERFACES__NODE_LOGGING_HPP_
|
||||
#define RCLCPP__NODE_INTERFACES__NODE_LOGGING_HPP_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rclcpp/macros.hpp"
|
||||
#include "rclcpp/node_interfaces/node_base_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_logging_interface.hpp"
|
||||
#include "rclcpp/visibility_control.hpp"
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
namespace node_interfaces
|
||||
{
|
||||
|
||||
/// Implementation of the NodeLogging part of the Node API.
|
||||
class NodeLogging : public NodeLoggingInterface
|
||||
{
|
||||
public:
|
||||
RCLCPP_SMART_PTR_ALIASES_ONLY(NodeLoggingInterface)
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
explicit NodeLogging(rclcpp::node_interfaces::NodeBaseInterface * node_base);
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
~NodeLogging();
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
rclcpp::Logger
|
||||
get_logger() const;
|
||||
|
||||
private:
|
||||
RCLCPP_DISABLE_COPY(NodeLogging)
|
||||
|
||||
/// Handle to the NodeBaseInterface given in the constructor.
|
||||
rclcpp::node_interfaces::NodeBaseInterface * node_base_;
|
||||
|
||||
rclcpp::Logger logger_;
|
||||
};
|
||||
|
||||
} // namespace node_interfaces
|
||||
} // namespace rclcpp
|
||||
|
||||
#endif // RCLCPP__NODE_INTERFACES__NODE_LOGGING_HPP_
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2017 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef RCLCPP__NODE_INTERFACES__NODE_LOGGING_INTERFACE_HPP_
|
||||
#define RCLCPP__NODE_INTERFACES__NODE_LOGGING_INTERFACE_HPP_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rclcpp/macros.hpp"
|
||||
#include "rclcpp/node_interfaces/node_base_interface.hpp"
|
||||
#include "rclcpp/visibility_control.hpp"
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
namespace node_interfaces
|
||||
{
|
||||
|
||||
/// Pure virtual interface class for the NodeLogging part of the Node API.
|
||||
class NodeLoggingInterface
|
||||
{
|
||||
public:
|
||||
RCLCPP_SMART_PTR_ALIASES_ONLY(NodeLoggingInterface)
|
||||
|
||||
/// Return the logger of the node.
|
||||
/** \return The logger of the node. */
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
rclcpp::Logger
|
||||
get_logger() const = 0;
|
||||
};
|
||||
|
||||
} // namespace node_interfaces
|
||||
} // namespace rclcpp
|
||||
|
||||
#endif // RCLCPP__NODE_INTERFACES__NODE_LOGGING_INTERFACE_HPP_
|
|
@ -17,7 +17,7 @@
|
|||
* `rclcpp` provides the canonical C++ API for interacting with ROS.
|
||||
* It consists of these main components:
|
||||
*
|
||||
* - Nodes
|
||||
* - Node
|
||||
* - rclcpp::node::Node
|
||||
* - rclcpp/node.hpp
|
||||
* - Publisher
|
||||
|
@ -93,6 +93,20 @@
|
|||
* - rclcpp::node::Node::count_publishers()
|
||||
* - rclcpp::node::Node::count_subscribers()
|
||||
*
|
||||
* And components related to logging:
|
||||
*
|
||||
* - Logging macros:
|
||||
* - Some examples (not exhaustive):
|
||||
* - RCLCPP_DEBUG()
|
||||
* - RCLCPP_INFO()
|
||||
* - RCLCPP_WARN_ONCE()
|
||||
* - RCLCPP_ERROR_SKIPFIRST()
|
||||
* - rclcpp/logging.hpp
|
||||
* - Logger:
|
||||
* - rclcpp::Logger
|
||||
* - rclcpp/logger.hpp
|
||||
* - rclcpp::node::Node::get_logger()
|
||||
*
|
||||
* Finally, there are many internal API's and utilities:
|
||||
*
|
||||
* - Exceptions:
|
||||
|
@ -110,13 +124,6 @@
|
|||
* - rclcpp::context::Context
|
||||
* - rclcpp/context.hpp
|
||||
* - rclcpp/contexts/default_context.hpp
|
||||
* - Logging macros:
|
||||
* - Some examples (not exhaustive):
|
||||
* - RCLCPP_DEBUG()
|
||||
* - RCLCPP_INFO()
|
||||
* - RCLCPP_WARN_ONCE()
|
||||
* - RCLCPP_ERROR_SKIPFIRST()
|
||||
* - rclcpp/logging.hpp
|
||||
* - Various utilities:
|
||||
* - rclcpp/function_traits.hpp
|
||||
* - rclcpp/macros.hpp
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#ifndef RCLCPP__LOGGING_HPP_
|
||||
#define RCLCPP__LOGGING_HPP_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rcutils/logging_macros.h"
|
||||
|
||||
// These are used for compiling out logging macros lower than a minimum severity.
|
||||
|
@ -31,13 +34,12 @@
|
|||
* \def RCLCPP_LOG_MIN_SEVERITY
|
||||
* Define RCLCPP_LOG_MIN_SEVERITY=RCLCPP_LOG_MIN_SEVERITY_[DEBUG|INFO|WARN|ERROR|FATAL]
|
||||
* in your build options to compile out anything below that severity.
|
||||
* Use RCUTILS_LOG_MIN_SEVERITY_NONE to compile out all macros.
|
||||
* Use RCLCPP_LOG_MIN_SEVERITY_NONE to compile out all macros.
|
||||
*/
|
||||
#ifndef RCLCPP_LOG_MIN_SEVERITY
|
||||
#define RCLCPP_LOG_MIN_SEVERITY RCLCPP_LOG_MIN_SEVERITY_DEBUG
|
||||
#endif
|
||||
|
||||
|
||||
@{
|
||||
from rcutils.logging import feature_combinations
|
||||
from rcutils.logging import get_macro_parameters
|
||||
|
@ -76,20 +78,20 @@ def is_supported_feature_combination(feature_combination):
|
|||
@[ for doc_line in feature_combinations[feature_combination].doc_lines]@
|
||||
* @(doc_line)
|
||||
@[ end for]@
|
||||
* \param name The name of the logger
|
||||
* \param logger The `rclcpp::Logger` to use
|
||||
@[ for param_name, doc_line in feature_combinations[feature_combination].params.items()]@
|
||||
* \param @(param_name) @(doc_line)
|
||||
@[ end for]@
|
||||
* \param ... The format string, followed by the variable arguments for the format string
|
||||
*/
|
||||
// TODO(dhood): Replace the name argument with a logger object.
|
||||
#define RCLCPP_@(severity)@(suffix)(name, @(''.join([p + ', ' for p in get_macro_parameters(feature_combination).keys()]))...) \
|
||||
#define RCLCPP_@(severity)@(suffix)(logger, @(''.join([p + ', ' for p in get_macro_parameters(feature_combination).keys()]))...) \
|
||||
static_assert(::std::is_same<decltype(logger), ::rclcpp::Logger>::value, "First argument to logging macros must be an rclcpp::Logger"); \
|
||||
RCUTILS_LOG_@(severity)@(suffix)_NAMED( \
|
||||
@{params = get_macro_parameters(feature_combination).keys()}@
|
||||
@[ if params]@
|
||||
@(''.join([' ' + p + ', \\\n' for p in params]))@
|
||||
@[ end if]@
|
||||
std::string(name).c_str(), \
|
||||
logger.get_name(), \
|
||||
__VA_ARGS__)
|
||||
|
||||
@[ end for]@
|
||||
|
|
33
rclcpp/src/rclcpp/logger.cpp
Normal file
33
rclcpp/src/rclcpp/logger.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2017 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "rclcpp/logger.hpp"
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
|
||||
rclcpp::Logger
|
||||
get_logger(const std::string & name)
|
||||
{
|
||||
#if RCLCPP_LOGGING_ENABLED
|
||||
return rclcpp::Logger(name);
|
||||
#else
|
||||
(void)name;
|
||||
return rclcpp::Logger();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace rclcpp
|
|
@ -26,6 +26,7 @@
|
|||
#include "rclcpp/node_interfaces/node_base.hpp"
|
||||
#include "rclcpp/node_interfaces/node_clock.hpp"
|
||||
#include "rclcpp/node_interfaces/node_graph.hpp"
|
||||
#include "rclcpp/node_interfaces/node_logging.hpp"
|
||||
#include "rclcpp/node_interfaces/node_parameters.hpp"
|
||||
#include "rclcpp/node_interfaces/node_services.hpp"
|
||||
#include "rclcpp/node_interfaces/node_timers.hpp"
|
||||
|
@ -52,6 +53,7 @@ Node::Node(
|
|||
bool use_intra_process_comms)
|
||||
: node_base_(new rclcpp::node_interfaces::NodeBase(node_name, namespace_, context)),
|
||||
node_graph_(new rclcpp::node_interfaces::NodeGraph(node_base_.get())),
|
||||
node_logging_(new rclcpp::node_interfaces::NodeLogging(node_base_.get())),
|
||||
node_timers_(new rclcpp::node_interfaces::NodeTimers(node_base_.get())),
|
||||
node_topics_(new rclcpp::node_interfaces::NodeTopics(node_base_.get())),
|
||||
node_services_(new rclcpp::node_interfaces::NodeServices(node_base_.get())),
|
||||
|
@ -84,6 +86,12 @@ Node::get_namespace() const
|
|||
return node_base_->get_namespace();
|
||||
}
|
||||
|
||||
rclcpp::Logger
|
||||
Node::get_logger() const
|
||||
{
|
||||
return node_logging_->get_logger();
|
||||
}
|
||||
|
||||
rclcpp::callback_group::CallbackGroup::SharedPtr
|
||||
Node::create_callback_group(
|
||||
rclcpp::callback_group::CallbackGroupType group_type)
|
||||
|
|
34
rclcpp/src/rclcpp/node_interfaces/node_logging.cpp
Normal file
34
rclcpp/src/rclcpp/node_interfaces/node_logging.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2017 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "rclcpp/node_interfaces/node_logging.hpp"
|
||||
|
||||
using rclcpp::node_interfaces::NodeLogging;
|
||||
|
||||
NodeLogging::NodeLogging(rclcpp::node_interfaces::NodeBaseInterface * node_base)
|
||||
: node_base_(node_base)
|
||||
{
|
||||
// TODO(dhood): use the namespace (slashes converted to dots)
|
||||
logger_ = rclcpp::get_logger(node_base_->get_name());
|
||||
}
|
||||
|
||||
NodeLogging::~NodeLogging()
|
||||
{
|
||||
}
|
||||
|
||||
rclcpp::Logger
|
||||
NodeLogging::get_logger() const
|
||||
{
|
||||
return logger_;
|
||||
}
|
35
rclcpp/test/test_logger.cpp
Normal file
35
rclcpp/test/test_logger.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2017 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rclcpp/logging.hpp"
|
||||
|
||||
TEST(TestLogger, factory_functions) {
|
||||
rclcpp::Logger logger = rclcpp::get_logger("test_logger");
|
||||
EXPECT_STREQ("test_logger", logger.get_name());
|
||||
rclcpp::Logger logger_copy = rclcpp::Logger(logger);
|
||||
EXPECT_STREQ("test_logger", logger_copy.get_name());
|
||||
}
|
||||
|
||||
TEST(TestLogger, hierarchy) {
|
||||
rclcpp::Logger logger = rclcpp::get_logger("test_logger");
|
||||
rclcpp::Logger sublogger = logger.get_child("child");
|
||||
EXPECT_STREQ("test_logger.child", sublogger.get_name());
|
||||
rclcpp::Logger subsublogger = sublogger.get_child("grandchild");
|
||||
EXPECT_STREQ("test_logger.child.grandchild", subsublogger.get_name());
|
||||
}
|
|
@ -19,15 +19,15 @@
|
|||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rclcpp/logging.hpp"
|
||||
#include "rcutils/logging.h"
|
||||
#include "rcutils/time.h"
|
||||
|
||||
#define RCLCPP_TEST_LOGGING_MACRO_NAME "name" // Used in testing below
|
||||
|
||||
using ::testing::EndsWith;
|
||||
|
||||
size_t g_log_calls = 0;
|
||||
rclcpp::Logger g_logger = rclcpp::get_logger("name");
|
||||
|
||||
struct LogEvent
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
|
||||
TEST_F(TestLoggingMacros, test_logging_named) {
|
||||
for (int i : {1, 2, 3}) {
|
||||
RCLCPP_DEBUG("name", "message %d", i);
|
||||
RCLCPP_DEBUG(g_logger, "message %d", i);
|
||||
}
|
||||
EXPECT_EQ(3u, g_log_calls);
|
||||
EXPECT_TRUE(g_last_log_event.location != NULL);
|
||||
|
@ -87,28 +87,11 @@ TEST_F(TestLoggingMacros, test_logging_named) {
|
|||
EXPECT_EQ(RCUTILS_LOG_SEVERITY_DEBUG, g_last_log_event.level);
|
||||
EXPECT_EQ("name", g_last_log_event.name);
|
||||
EXPECT_EQ("message 3", g_last_log_event.message);
|
||||
|
||||
// Test different name inputs
|
||||
std::string std_string_name = "name";
|
||||
RCLCPP_DEBUG(std_string_name, "message");
|
||||
EXPECT_EQ("name", g_last_log_event.name);
|
||||
|
||||
const char * c_string_name = "name";
|
||||
RCLCPP_DEBUG(c_string_name, "message");
|
||||
EXPECT_EQ("name", g_last_log_event.name);
|
||||
|
||||
RCLCPP_DEBUG(std_string_name + c_string_name, "message");
|
||||
EXPECT_EQ("namename", g_last_log_event.name);
|
||||
|
||||
RCLCPP_DEBUG(RCLCPP_TEST_LOGGING_MACRO_NAME, "message");
|
||||
EXPECT_EQ(RCLCPP_TEST_LOGGING_MACRO_NAME, g_last_log_event.name);
|
||||
RCLCPP_DEBUG(std::string(RCLCPP_TEST_LOGGING_MACRO_NAME) + std_string_name, "message");
|
||||
EXPECT_EQ("namename", g_last_log_event.name);
|
||||
}
|
||||
|
||||
TEST_F(TestLoggingMacros, test_logging_once) {
|
||||
for (int i : {1, 2, 3}) {
|
||||
RCLCPP_INFO_ONCE("name", "message %d", i);
|
||||
RCLCPP_INFO_ONCE(g_logger, "message %d", i);
|
||||
}
|
||||
EXPECT_EQ(1u, g_log_calls);
|
||||
EXPECT_EQ(RCUTILS_LOG_SEVERITY_INFO, g_last_log_event.level);
|
||||
|
@ -118,7 +101,7 @@ TEST_F(TestLoggingMacros, test_logging_once) {
|
|||
// Check that another instance has a context that's independent to the call above's
|
||||
g_log_calls = 0;
|
||||
for (int i : {1, 2, 3}) {
|
||||
RCLCPP_INFO_ONCE("name", "second message %d", i);
|
||||
RCLCPP_INFO_ONCE(g_logger, "second message %d", i);
|
||||
}
|
||||
EXPECT_EQ(1u, g_log_calls);
|
||||
EXPECT_EQ(RCUTILS_LOG_SEVERITY_INFO, g_last_log_event.level);
|
||||
|
@ -128,7 +111,7 @@ TEST_F(TestLoggingMacros, test_logging_once) {
|
|||
|
||||
TEST_F(TestLoggingMacros, test_logging_expression) {
|
||||
for (int i : {1, 2, 3, 4, 5, 6}) {
|
||||
RCLCPP_INFO_EXPRESSION("name", i % 3, "message %d", i);
|
||||
RCLCPP_INFO_EXPRESSION(g_logger, i % 3, "message %d", i);
|
||||
}
|
||||
EXPECT_EQ(4u, g_log_calls);
|
||||
EXPECT_EQ("message 5", g_last_log_event.message);
|
||||
|
@ -144,7 +127,7 @@ bool mod3()
|
|||
TEST_F(TestLoggingMacros, test_logging_function) {
|
||||
for (int i : {1, 2, 3, 4, 5, 6}) {
|
||||
g_counter = i;
|
||||
RCLCPP_INFO_FUNCTION("name", &mod3, "message %d", i);
|
||||
RCLCPP_INFO_FUNCTION(g_logger, &mod3, "message %d", i);
|
||||
}
|
||||
EXPECT_EQ(4u, g_log_calls);
|
||||
EXPECT_EQ("message 5", g_last_log_event.message);
|
||||
|
@ -152,7 +135,7 @@ TEST_F(TestLoggingMacros, test_logging_function) {
|
|||
|
||||
TEST_F(TestLoggingMacros, test_logging_skipfirst) {
|
||||
for (uint32_t i : {1, 2, 3, 4, 5}) {
|
||||
RCLCPP_WARN_SKIPFIRST("name", "message %u", i);
|
||||
RCLCPP_WARN_SKIPFIRST(g_logger, "message %u", i);
|
||||
EXPECT_EQ(i - 1, g_log_calls);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,18 @@ TEST_F(TestNode, get_name_and_namespace) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(TestNode, get_logger) {
|
||||
// Currently the namespace is not taken into account with the node logger name
|
||||
{
|
||||
auto node = std::make_shared<rclcpp::node::Node>("my_node");
|
||||
EXPECT_STREQ("my_node", node->get_logger().get_name());
|
||||
}
|
||||
{
|
||||
auto node = std::make_shared<rclcpp::node::Node>("my_node", "/ns");
|
||||
EXPECT_STREQ("my_node", node->get_logger().get_name());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestNode, get_clock) {
|
||||
auto node = std::make_shared<rclcpp::node::Node>("my_node", "/ns");
|
||||
auto ros_clock = node->get_clock();
|
||||
|
|
|
@ -32,10 +32,12 @@
|
|||
#include "rclcpp/client.hpp"
|
||||
#include "rclcpp/context.hpp"
|
||||
#include "rclcpp/event.hpp"
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rclcpp/macros.hpp"
|
||||
#include "rclcpp/message_memory_strategy.hpp"
|
||||
#include "rclcpp/node_interfaces/node_base_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_graph_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_logging_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_parameters_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_services_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_timers_interface.hpp"
|
||||
|
@ -108,6 +110,12 @@ public:
|
|||
const char *
|
||||
get_namespace() const;
|
||||
|
||||
/// Get the logger of the node.
|
||||
/** \return The logger of the node. */
|
||||
RCLCPP_LIFECYCLE_PUBLIC
|
||||
rclcpp::Logger
|
||||
get_logger() const;
|
||||
|
||||
/// Create and return a callback group.
|
||||
RCLCPP_LIFECYCLE_PUBLIC
|
||||
rclcpp::callback_group::CallbackGroup::SharedPtr
|
||||
|
@ -467,6 +475,7 @@ private:
|
|||
|
||||
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_;
|
||||
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_;
|
||||
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_;
|
||||
rclcpp::node_interfaces::NodeTimersInterface::SharedPtr node_timers_;
|
||||
rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_;
|
||||
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_;
|
||||
|
|
|
@ -25,9 +25,11 @@
|
|||
|
||||
#include "rclcpp/exceptions.hpp"
|
||||
#include "rclcpp/graph_listener.hpp"
|
||||
#include "rclcpp/logger.hpp"
|
||||
#include "rclcpp/node.hpp"
|
||||
#include "rclcpp/node_interfaces/node_base.hpp"
|
||||
#include "rclcpp/node_interfaces/node_graph.hpp"
|
||||
#include "rclcpp/node_interfaces/node_logging.hpp"
|
||||
#include "rclcpp/node_interfaces/node_parameters.hpp"
|
||||
#include "rclcpp/node_interfaces/node_services.hpp"
|
||||
#include "rclcpp/node_interfaces/node_timers.hpp"
|
||||
|
@ -56,6 +58,7 @@ LifecycleNode::LifecycleNode(
|
|||
bool use_intra_process_comms)
|
||||
: node_base_(new rclcpp::node_interfaces::NodeBase(node_name, namespace_, context)),
|
||||
node_graph_(new rclcpp::node_interfaces::NodeGraph(node_base_.get())),
|
||||
node_logging_(new rclcpp::node_interfaces::NodeLogging(node_base_.get())),
|
||||
node_timers_(new rclcpp::node_interfaces::NodeTimers(node_base_.get())),
|
||||
node_topics_(new rclcpp::node_interfaces::NodeTopics(node_base_.get())),
|
||||
node_services_(new rclcpp::node_interfaces::NodeServices(node_base_.get())),
|
||||
|
@ -95,6 +98,12 @@ LifecycleNode::get_namespace() const
|
|||
return node_base_->get_namespace();
|
||||
}
|
||||
|
||||
rclcpp::Logger
|
||||
LifecycleNode::get_logger() const
|
||||
{
|
||||
return node_logging_->get_logger();
|
||||
}
|
||||
|
||||
rclcpp::callback_group::CallbackGroup::SharedPtr
|
||||
LifecycleNode::create_callback_group(
|
||||
rclcpp::callback_group::CallbackGroupType group_type)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue