Skip to content

Commit

Permalink
Merge pull request #18 from ethz-asl/feature/nolog
Browse files Browse the repository at this point in the history
Added MODE_NOLOG
  • Loading branch information
michaelpantic committed Sep 20, 2023
2 parents dfbacd1 + 2eacac0 commit 3dc97f4
Show file tree
Hide file tree
Showing 15 changed files with 1,003 additions and 45 deletions.
4 changes: 3 additions & 1 deletion .github/scripts/run_build_ubuntu20_04.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ cmake --build . --target test_default -- -j 6
cmake --build . --target test_glog -- -j 6
cmake --build . --target test_lpp -- -j 6
cmake --build . --target test_lpp_custom -- -j 6
cmake --build . --target test_nolog -- -j 6
cmake --build . --target test_roslog -- -j 6
cd devel/lib/lpp
./test_default
./test_roslog
./test_glog
./test_lpp
./test_lpp_custom
./test_nolog
./test_roslog
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,22 @@ if (GLOG_FOUND AND catkin_FOUND AND LPP_BUILD_TESTS)
target_link_libraries(${DEFAULT_TESTS} glog gtest ${catkin_LIBRARIES})
target_compile_definitions(${DEFAULT_TESTS} PRIVATE MODE_DEFAULT)
target_compile_options(${DEFAULT_TESTS} PRIVATE "-fcompare-debug-second")

##### Nolog Tests #####
set(NOLOG_TESTS "test_nolog")
add_executable(${NOLOG_TESTS} test/test_entry_point.cpp
test/nolog/test_nolog_basic.cc
test/nolog/test_nolog_every_n.cc
test/nolog/test_nolog_first_n.cc
test/nolog/test_nolog_if_every_n.cc
test/nolog/test_nolog_log_string.cc
test/nolog/test_nolog_rosprintf.cc
test/nolog/test_nolog_timed.cc
test/nolog/test_nolog_vlog.cc
)

target_include_directories(${NOLOG_TESTS} PRIVATE ${LPP_INCLUDE_DIRECTORIES} test/nolog)
target_link_libraries(${NOLOG_TESTS} glog gtest ${catkin_LIBRARIES})
target_compile_definitions(${NOLOG_TESTS} PRIVATE MODE_NOLOG)
target_compile_options(${NOLOG_TESTS} PRIVATE "-fcompare-debug-second")
endif ()
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ $ catkin build lpp
- **MODE_GLOG:** Google Logging output. Calls abort() if it logs a fatal error.
- **MODE_ROSLOG:** ROS Logging output.
- **MODE_DEFAULT:** Disables Logging standardization. Messages are logged according to their framework.
- **MODE_NOLOG:** Disables Logging completely. Useful for unittests or in some cases for release builds.

## How severity levels should be used

Expand Down
111 changes: 98 additions & 13 deletions include/log++.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#include <functional>
#include <memory>

#if !defined MODE_LPP && !defined MODE_GLOG && !defined MODE_ROSLOG && !defined MODE_DEFAULT
#if !defined MODE_LPP && !defined MODE_GLOG && !defined MODE_ROSLOG && !defined MODE_DEFAULT && !defined MODE_NOLOG
#define MODE_DEFAULT
#warning "No mode defined. Selected MODE_DEFAULT";
#endif
Expand All @@ -56,10 +56,11 @@
*
* Defining MODE_DEFAULT will prevent errors from being generated for each logging function that is called.
*/
#if defined(MODE_LPP) + defined(MODE_GLOG) + defined(MODE_ROSLOG) + defined(MODE_DEFAULT) > 1
#if defined(MODE_LPP) + defined(MODE_GLOG) + defined(MODE_ROSLOG) + defined(MODE_DEFAULT) + defined(MODE_NOLOG) > 1
#undef MODE_LPP
#undef MODE_GLOG
#undef MODE_ROSLOG
#undef MODE_NOLOG
#define MODE_DEFAULT
#error "More than one mode is defined"
#endif
Expand Down Expand Up @@ -196,6 +197,17 @@ inline static Init lppInit;
#undef ROS_WARN_ONCE
#undef ROS_ERROR_ONCE
#undef ROS_FATAL_ONCE

#undef ROS_DEBUG_THROTTLE
#undef ROS_DEBUG_STREAM_THROTTLE
#undef ROS_INFO_THROTTLE
#undef ROS_INFO_STREAM_THROTTLE
#undef ROS_WARN_THROTTLE
#undef ROS_WARN_STREAM_THROTTLE
#undef ROS_ERROR_THROTTLE
#undef ROS_ERROR_STREAM_THROTTLE
#undef ROS_FATAL_THROTTLE
#undef ROS_FATAL_STREAM_THROTTLE
#endif

using namespace lpp::internal;
Expand Down Expand Up @@ -357,6 +369,18 @@ true
#define LOG_TIMED(severity, n, x) LPP_INTL::InternalLogCount::getInstance().update(LPP_GET_KEY(), n, LPP_INTL::InternalLog() << x, toBase(LPP_INTL::LppSeverity::severity), LPP_INTL::PolicyType::TIMED) // NOLINT(bugprone-macro-parentheses)
#endif

#if defined MODE_ROSLOG || defined MODE_LPP || MODE_NOLOG
/**
* Replace glog's FLAGS_v and VLOG_IS_ON to avoid linker errors
* if glog is installed but not linked to lpp.
*/
[[maybe_unused]] inline static int32_t LPP_FLAGS_v;

#ifdef GLOG_SUPPORTED
#define FLAGS_v LPP_FLAGS_v
#endif //GLOG_SUPPORTED
#endif //defined MODE_ROSLOG || defined MODE_LPP || MODE_NOLOG

#if defined MODE_ROSLOG || defined MODE_LPP
#define LOG_EVERY_N(severity, n) LPP_INTL::InternalPolicyLog(LPP_GET_KEY(), n, LPP_INTL::toBase(LPP_INTL::GlogSeverity::severity), LPP_INTL::PolicyType::EVERY_N)
#define LOG_IF_EVERY_N(severity, condition, n) if (condition) LOG_EVERY_N(severity, n)
Expand All @@ -369,17 +393,6 @@ LPP_INTL::InternalPolicyLog(LPP_GET_KEY(), n, LPP_INTL::BaseSeverity::DEBUG, LPP
#define DLOG_IF_EVERY_N(severity, condition, n) LPP_ASSERT_GLOG(LPP_INTL::GlogSeverity::severity); if (condition) LPP_INTL::InternalPolicyLog(LPP_GET_KEY(), n, LPP_INTL::BaseSeverity::DEBUG, LPP_INTL::PolicyType::EVERY_N)
#define LOG_STRING(severity, ptr) LPP_ASSERT_GLOG(LPP_INTL::GlogSeverity::severity); LPP_INTL::InternalGlogLogStringLog(toBase(LPP_INTL::GlogSeverity::severity), ptr)

/**
* Replace glog's FLAGS_v and VLOG_IS_ON to avoid linker errors
* if glog is installed but not linked to lpp.
*/
[[maybe_unused]] inline static int32_t LPP_FLAGS_v;

#ifdef GLOG_SUPPORTED
#define FLAGS_v LPP_FLAGS_v
#endif


#undef VLOG_IS_ON
#define VLOG_IS_ON(verboselevel) LPP_FLAGS_v >= (verboselevel) ? true : false
#define VLOG(verboselevel) LPP_INTL::InternalCondLog(LPP_INTL::BaseSeverity::DEBUG, VLOG_IS_ON(verboselevel))
Expand Down Expand Up @@ -427,9 +440,81 @@ LPP_INTL::InternalPolicyLog(LPP_GET_KEY(), n, LPP_INTL::BaseSeverity::DEBUG, LPP
#define LOG_3(severity, cond, x) if (cond) LPP_INTL::InternalLog(LPP_INTL::LppSeverity::severity) << x // NOLINT(bugprone-macro-parentheses)
#endif


//! MODE_NOLOG

#ifdef MODE_NOLOG
//lpp
#define LOG_2(severity, x) (void) LPP_INTL::LppSeverity::severity; InternalLog() << x
#define LOG_EVERY(severity, n, x) (void) LPP_INTL::LppSeverity::severity; static_assert(std::is_integral_v<decltype(n)>); InternalLog()
#define LOG_FIRST(severity, n, x) (void) LPP_INTL::LppSeverity::severity; static_assert(std::is_integral_v<decltype(n)>); InternalLog()
#define LOG_TIMED(severity, t, x) (void) LPP_INTL::LppSeverity::severity; static_assert(std::is_integral_v<decltype(t)>); InternalLog()

//glog
#define LOG_1(severity) (void) LPP_INTL::GlogSeverity::severity; InternalLog()
#define DLOG(severity) (void) LPP_INTL::GlogSeverity::severity; InternalLog()
#define DLOG_EVERY_N(severity, n) (void) LPP_INTL::GlogSeverity::severity; InternalLog()
#define LOG_EVERY_N(severity, n) (void) LPP_INTL::GlogSeverity::severity; InternalLog()
#define DLOG_FIRST_N(severity, n) (void) LPP_INTL::GlogSeverity::severity; static_assert(std::is_integral_v<decltype(n)>); InternalLog()
#define LOG_FIRST_N(severity, n) (void) LPP_INTL::GlogSeverity::severity; static_assert(std::is_integral_v<decltype(n)>); InternalLog()
#define DLOG_IF_EVERY_N(severity, cond, n) (void) LPP_INTL::GlogSeverity::severity; static_assert(std::is_same<decltype(cond), bool>::value && std::is_integral_v<decltype(n)>); InternalLog()
#define LOG_IF_EVERY_N(severity, cond, n) DLOG_IF_EVERY_N(severity, cond, n)
#define LOG_STRING(severity, ptr) (void) LPP_INTL::GlogSeverity::severity; static_assert(std::is_same<decltype(ptr), std::vector<std::string>*>::value || std::is_same<decltype(ptr), std::nullptr_t>::value); InternalLog()
#define VLOG(verboselevel) static_assert(std::is_integral_v<decltype(verboselevel)>); InternalLog()
#define VLOG_IF(verboselevel, condition) static_assert(std::is_integral_v<decltype(verboselevel)> && std::is_same<decltype(condition), bool>::value); InternalLog()
#define VLOG_EVERY_N(verboselevel, n) static_assert(std::is_integral_v<decltype(verboselevel)> && std::is_integral_v<decltype(n)>); InternalLog()
#define VLOG_IF_EVERY_N(verboselevel, condition, n) static_assert(std::is_integral_v<decltype(verboselevel)> && std::is_same<decltype(condition), bool>::value && std::is_integral_v<decltype(n)>); InternalLog()
#define DLOG_EVERY_T(severity, t) (void) LPP_INTL::GlogSeverity::severity; static_assert(std::is_integral_v<decltype(t)>); InternalLog()
#define LOG_EVERY_T(severity, t) DLOG_EVERY_T(severity, t)

//ros
#define ROS_DEBUG(...) LOG_2(D, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_INFO(...) LOG_2(I, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_WARN(...) LOG_2(W, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_ERROR(...) LOG_2(E, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_FATAL(...) LOG_2(F, LPP_INTL::emptyString(__VA_ARGS__))

#define ROS_DEBUG_STREAM(x) LPP_INTL::emptyString(x)
#define ROS_INFO_STREAM(x) LPP_INTL::emptyString(x)
#define ROS_WARN_STREAM(x) LPP_INTL::emptyString(x)
#define ROS_ERROR_STREAM(x) LPP_INTL::emptyString(x)
#define ROS_FATAL_STREAM(x) LPP_INTL::emptyString(x)

#define ROS_DEBUG_ONCE(...) LOG_2(D, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_INFO_ONCE(...) LOG_2(I, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_WARN_ONCE(...) LOG_2(W, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_ERROR_ONCE(...) LOG_2(E, LPP_INTL::emptyString(__VA_ARGS__))
#define ROS_FATAL_ONCE(...) LOG_2(F, LPP_INTL::emptyString(__VA_ARGS__))

#define ROS_DEBUG_THROTTLE(t, x) static_assert(std::is_integral_v<decltype(t)>); LPP_INTL::emptyString(x)
#define ROS_DEBUG_STREAM_THROTTLE(t, x) static_assert(std::is_integral_v<decltype(t)>); InternalLog()
#define ROS_INFO_THROTTLE(t, x) ROS_DEBUG_THROTTLE(t, x)
#define ROS_INFO_STREAM_THROTTLE(t, x) ROS_DEBUG_STREAM_THROTTLE(t, x)
#define ROS_WARN_THROTTLE(t, x) ROS_DEBUG_THROTTLE(t, x)
#define ROS_WARN_STREAM_THROTTLE(t, x) ROS_DEBUG_STREAM_THROTTLE(t, x)
#define ROS_ERROR_THROTTLE(t, x) ROS_DEBUG_THROTTLE(t, x)
#define ROS_ERROR_STREAM_THROTTLE(t, x) ROS_DEBUG_STREAM_THROTTLE(t, x)
#define ROS_FATAL_THROTTLE(t, x) ROS_DEBUG_THROTTLE(t, x)
#define ROS_FATAL_STREAM_THROTTLE(t, x) ROS_DEBUG_STREAM_THROTTLE(t, x)
#endif

namespace lpp {
namespace internal {
#ifdef MODE_NOLOG
//! Used to disable logging for printf(3) like syntax
template<typename... Args>
constexpr inline std::string_view emptyString([[maybe_unused]] const char *f, [[maybe_unused]] Args... args) {
return "";
}

[[maybe_unused]] constexpr std::string_view emptyString([[maybe_unused]] const char *str) {
return "";
}

[[maybe_unused]] constexpr std::string_view emptyString([[maybe_unused]] const std::string& str) {
return "";
}
#endif
//! Composes a string with the same text that would be printed if format was used on printf(3)
template<typename... Args>
inline std::string formatToString(const char *f, Args... args) {
Expand Down
3 changes: 1 addition & 2 deletions test/common/async_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class TestResult {
* @return true on success otherwise false
*/
inline bool get(const std::string &test_name) {
test_result_mutex_.lock();
std::scoped_lock<std::mutex> lock(test_result_mutex_);
LOG_INIT(*test_argv);
if (!started_) {
started_ = true;
Expand All @@ -56,7 +56,6 @@ class TestResult {
}

bool res = test_results.at(test_name);
test_result_mutex_.unlock();
return res;
}

Expand Down
68 changes: 39 additions & 29 deletions test/lpp/test_lpp_rosprintf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,62 +8,72 @@

using namespace lpp::testing;

TEST(lpp_rosprintf, ros_info) {
TEST(lpp_rosprintf, ros_debug) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDOUT(ROS_DEBUG(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "DEBUG " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_debug_once) {
LOG_INIT(*test_argv);

testing::internal::CaptureStdout();
ROS_INFO(ERROR_MESSAGE, 3.3, 5.5);
std::string c = testing::internal::GetCapturedStdout();
std::string output = LPP_CAPTURE_STDOUT(ROS_DEBUG_ONCE(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "DEBUG " + EXPECTED_ERROR_MESSAGE);
}

ASSERT_EQ(c, "INFO " + EXPECTED_ERROR_MESSAGE);
TEST(lpp_rosprintf, ros_info) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDOUT(ROS_INFO(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "INFO " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_info_once) {
LOG_INIT(*test_argv);

testing::internal::CaptureStdout();
ROS_INFO_ONCE(ERROR_MESSAGE, 3.3, 5.5);
std::string c = testing::internal::GetCapturedStdout();

ASSERT_EQ(c, "INFO " + EXPECTED_ERROR_MESSAGE);
std::string output = LPP_CAPTURE_STDOUT(ROS_INFO_ONCE(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "INFO " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_warn) {
LOG_INIT(*test_argv);

testing::internal::CaptureStdout();
ROS_WARN(ERROR_MESSAGE, 3.3, 5.5);
std::string c = testing::internal::GetCapturedStdout();

ASSERT_EQ(c, "WARN " + EXPECTED_ERROR_MESSAGE);
std::string output = LPP_CAPTURE_STDOUT(ROS_WARN(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "WARN " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_warn_once) {
LOG_INIT(*test_argv);

testing::internal::CaptureStdout();
ROS_WARN_ONCE(ERROR_MESSAGE, 3.3, 5.5);
std::string c = testing::internal::GetCapturedStdout();

ASSERT_EQ(c, "WARN " + EXPECTED_ERROR_MESSAGE);
std::string output = LPP_CAPTURE_STDOUT(ROS_WARN_ONCE(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "WARN " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_error) {
LOG_INIT(*test_argv);

testing::internal::CaptureStdout();
ROS_ERROR(ERROR_MESSAGE, 3.3, 5.5);
std::string c = testing::internal::GetCapturedStdout();

ASSERT_EQ(c, "ERROR " + EXPECTED_ERROR_MESSAGE);
std::string output = LPP_CAPTURE_STDOUT(ROS_ERROR(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "ERROR " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_error_once) {
LOG_INIT(*test_argv);

testing::internal::CaptureStdout();
ROS_ERROR_ONCE(ERROR_MESSAGE, 3.3, 5.5);
std::string c = testing::internal::GetCapturedStdout();
std::string output = LPP_CAPTURE_STDOUT(ROS_ERROR_ONCE(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "ERROR " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_fatal) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDOUT(ROS_FATAL(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "FATAL " + EXPECTED_ERROR_MESSAGE);
}

TEST(lpp_rosprintf, ros_fatal_once) {
LOG_INIT(*test_argv);

ASSERT_EQ(c, "ERROR " + EXPECTED_ERROR_MESSAGE);
std::string output = LPP_CAPTURE_STDOUT(ROS_FATAL_ONCE(ERROR_MESSAGE, 3.3, 5.5));
ASSERT_EQ(output, "FATAL " + EXPECTED_ERROR_MESSAGE);
}
6 changes: 6 additions & 0 deletions test/lpp/test_lpp_vlog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ TEST(lpp_vlog, glog_syntax_every_n_severity_v5) {
}

TEST(lpp_vlog, glog_syntax_if_every_n_severity_v1) {
LOG_INIT(*test_argv);
FLAGS_v = 3;

for (int i = 0; i < 5; i++) {
testing::internal::CaptureStdout();
VLOG_IF_EVERY_N(1, i <= 3, 3) << "Test" << 123;
Expand All @@ -134,6 +137,9 @@ TEST(lpp_vlog, glog_syntax_if_every_n_severity_v1) {
}

TEST(lpp_vlog, glog_syntax_if_every_n_severity_v3) {
LOG_INIT(*test_argv);
FLAGS_v = 3;

for (int i = 0; i < 5; i++) {
testing::internal::CaptureStdout();
VLOG_IF_EVERY_N(3, i <= 3, 3) << "Test" << 123;
Expand Down
Loading

0 comments on commit 3dc97f4

Please sign in to comment.