From ab04b27ad2c9e581e5a74d09ba144b4e02d6355f Mon Sep 17 00:00:00 2001 From: Stephen Roderick Date: Fri, 4 Apr 2014 14:45:00 -0400 Subject: [PATCH] logger: Support logging using log4cpp framework Supports logging using the log4cpp framework, which replaces logging both to file and via printf. The log4cpp option defaults off. This fix also ensures that application code is informed of the build option. --- config/FindLog4cpp.cmake | 36 ++++++++++++++++++++++++ rtt/CMakeLists.txt | 15 +++++++++- rtt/Logger.cpp | 46 +++++++++++++++++++++++++++++-- rtt/Logger.hpp | 7 +++++ rtt/os/targets/target-config.h.in | 1 + 5 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 config/FindLog4cpp.cmake diff --git a/config/FindLog4cpp.cmake b/config/FindLog4cpp.cmake new file mode 100644 index 000000000..04f4bcedb --- /dev/null +++ b/config/FindLog4cpp.cmake @@ -0,0 +1,36 @@ +################################################################################ +# +# CMake script for finding Log4cpp. +# The default CMake search process is used to locate files. +# +# This script creates the following variables: +# LOG4CPP_FOUND: Boolean that indicates if the package was found +# LOG4CPP_INCLUDE_DIRS: Paths to the necessary header files +# LOG4CPP_LIBRARIES: Package libraries +# LOG4CPP_LIBRARY_DIRS: Path to package libraries +# +################################################################################ + +include(FindPackageHandleStandardArgs) + +# Find headers and libraries +find_path(LOG4CPP_INCLUDE_DIR NAMES log4cpp/Category.hh) +find_library(LOG4CPP_LIBRARY NAMES log4cpp) + +# Set LOG4CPP_FOUND honoring the QUIET and REQUIRED arguments +find_package_handle_standard_args(LOG4CPP DEFAULT_MSG LOG4CPP_LIBRARY LOG4CPP_INCLUDE_DIR) + +# Output variables +if(LOG4CPP_FOUND) + # Include dirs + set(LOG4CPP_INCLUDE_DIRS ${LOG4CPP_INCLUDE_DIR}) + + # Libraries + set(LOG4CPP_LIBRARIES ${LOG4CPP_LIBRARY}) + + # Link dirs + get_filename_component(LOG4CPP_LIBRARY_DIRS ${LOG4CPP_LIBRARY} PATH) +endif() + +# Advanced options for not cluttering the cmake UIs +mark_as_advanced(LOG4CPP_INCLUDE_DIR LOG4CPP_LIBRARY) diff --git a/rtt/CMakeLists.txt b/rtt/CMakeLists.txt index 91fc3190d..02a710b08 100644 --- a/rtt/CMakeLists.txt +++ b/rtt/CMakeLists.txt @@ -58,6 +58,7 @@ OPTION(OROBLD_DISABLE_LOGGING "Disable Logging Infrastructure" OFF) CMAKE_DEPENDENT_OPTION(OROSEM_PRINTF_LOGGING "Logger uses printf()/fprintf() instead of std::iostream." OFF "NOT OROBLD_DISABLE_LOGGING" OFF) CMAKE_DEPENDENT_OPTION(OROSEM_FILE_LOGGING "Logger logs to orocos.log file." ON "NOT OROBLD_DISABLE_LOGGING" OFF) CMAKE_DEPENDENT_OPTION(OROSEM_REMOTE_LOGGING "Logger allows remote log retrieval." ON "NOT OROBLD_DISABLE_LOGGING" OFF) +CMAKE_DEPENDENT_OPTION(OROSEM_LOG4CPP_LOGGING "Logger logs to log4cpp infrastructure (replaces file and printf logging) ." OFF "NOT OROBLD_DISABLE_LOGGING;OROSEM_FILE_LOGGING" OFF) IF (OROSEM_REMOTE_LOGGING AND NOT OROBLD_DISABLE_LOGGING) SET(ORONUM_LOGGING_BUFSIZE 1000 CACHE STRING "Maximum number of lines kept for remote log retrieval.") @@ -65,6 +66,18 @@ ELSE (OROSEM_REMOTE_LOGGING AND NOT OROBLD_DISABLE_LOGGING) SET(ORONUM_LOGGING_BUFSIZE CACHE INTERNAL "") ENDIF (OROSEM_REMOTE_LOGGING AND NOT OROBLD_DISABLE_LOGGING) +IF (OROSEM_LOG4CPP_LOGGING) + FIND_PACKAGE(Log4cpp REQUIRED) + + INCLUDE_DIRECTORIES(${LOG4CPP_INCLUDE_DIRS}) + list(APPEND OROCOS-RTT_INCLUDE_DIRS ${LOG4CPP_INCLUDE_DIRS} ) + # add to list of libraries in pkgconfig file + LIST(APPEND OROCOS-RTT_USER_LINK_LIBS ${LOG4CPP_LIBRARIES}) + # add to list of dependent link libraries + LIST(APPEND EXTRA_LIBRARIES ${LOG4CPP_LIBRARIES}) + +ENDIF (OROSEM_LOG4CPP_LOGGING) + ### Execution Engine OPTION(OROPKG_EXECUTION_ADVANCED "Advanced Execution Engine configuration" OFF) CMAKE_DEPENDENT_OPTION(OROPKG_EXECUTION_ENGINE_EVENTS "Enable Event Processing." ON "OROPKG_EXECUTION_ADVANCED" ON) @@ -205,7 +218,7 @@ ENDIF ( BUILD_STATIC ) ENDIF () - target_link_libraries(orocos-rtt-${OROCOS_TARGET}_dynamic ${OROCOS-RTT_LIBRARIES}) + target_link_libraries(orocos-rtt-${OROCOS_TARGET}_dynamic ${OROCOS-RTT_LIBRARIES} ${EXTRA_LIBRARIES}) IF (BUILD_ENABLE_COVERAGE) target_link_libraries(orocos-rtt-${OROCOS_TARGET}_dynamic gcov) ENDIF (BUILD_ENABLE_COVERAGE) diff --git a/rtt/Logger.cpp b/rtt/Logger.cpp index 8af882d91..8b867deb8 100644 --- a/rtt/Logger.cpp +++ b/rtt/Logger.cpp @@ -52,6 +52,9 @@ # include # ifdef OROSEM_FILE_LOGGING # include +# ifdef OROSEM_LOG4CPP_LOGGING +# include +# endif # endif # ifdef OROSEM_REMOTE_LOGGING # include @@ -86,6 +89,31 @@ namespace RTT #ifndef OROBLD_DISABLE_LOGGING +#ifdef OROSEM_LOG4CPP_LOGGING + + const std::string Logger::log4cppCategoryName = "org.orocos.rtt"; + + log4cpp::Priority::Value level2Priority(const int logLevel) + { + log4cpp::Priority::Value value = log4cpp::Priority::NOTSET; + switch (logLevel) + { + case Never: value = log4cpp::Priority::NOTSET; break; + case Fatal: value = log4cpp::Priority::FATAL; break; + case Critical: value = log4cpp::Priority::CRIT; break; + case Error: value = log4cpp::Priority::ERROR; break; + case Warning: value = log4cpp::Priority::WARN; break; + case Info: value = log4cpp::Priority::INFO; break; + case Debug: value = log4cpp::Priority::DEBUG; break; + // best we can do!? + case RealTime: value = log4cpp::Priority::DEBUG; break; + default: value = log4cpp::Priority::NOTSET; break; + } + return value; + } + +#endif + Logger& Logger::log() { return *Instance(); } @@ -107,8 +135,12 @@ namespace RTT #ifdef OROSEM_REMOTE_LOGGING messagecnt(0), #endif -#if defined(OROSEM_FILE_LOGGING) && !defined(OROSEM_PRINTF_LOGGING) +#if defined(OROSEM_FILE_LOGGING) +#if defined(OROSEM_LOG4CPP_LOGGING) + category(log4cpp::Category::getInstance(RTT::Logger::log4cppCategoryName)), +#elif !defined(OROSEM_PRINTF_LOGGING) logfile(logfile_name ? logfile_name : "orocos.log"), +#endif #endif inloglevel(Info), outloglevel(Warning), @@ -117,7 +149,7 @@ namespace RTT mlogStdOut(true), mlogFile(true), moduleptr("Logger") { -#if defined(OROSEM_FILE_LOGGING) && defined(OROSEM_PRINTF_LOGGING) +#if defined(OROSEM_FILE_LOGGING) && !defined(OROSEM_LOG4CPP_LOGGING) && defined(OROSEM_PRINTF_LOGGING) logfile = fopen(logfile_name ? logfile_name : "orocos.log","w"); #endif } @@ -163,7 +195,9 @@ namespace RTT if ( maylogFile() ) { #ifdef OROSEM_FILE_LOGGING -#ifndef OROSEM_PRINTF_LOGGING +#if defined(OROSEM_LOG4CPP_LOGGING) + category.log(level2Priority(inloglevel), fileline.str()); +#elif !defined(OROSEM_PRINTF_LOGGING) logfile << res << fileline.str() << pf; #else fprintf( logfile, "%s%s\n", res.c_str(), fileline.str().c_str() ); @@ -197,6 +231,9 @@ namespace RTT unsigned int messagecnt; #endif #if defined(OROSEM_FILE_LOGGING) +#if defined(OROSEM_LOG4CPP_LOGGING) + log4cpp::Category& category; +#endif # ifndef OROSEM_PRINTF_LOGGING std::ofstream logfile; # else @@ -575,6 +612,9 @@ namespace RTT void Logger::setLogLevel( LogLevel ll ) { d->outloglevel = ll; +#if defined(OROSEM_LOG4CPP_LOGGING) + d->category.setPriority(level2Priority(ll)); +#endif } Logger::LogLevel Logger::getLogLevel() const { diff --git a/rtt/Logger.hpp b/rtt/Logger.hpp index 833d916cd..8d0ceb2e6 100644 --- a/rtt/Logger.hpp +++ b/rtt/Logger.hpp @@ -311,6 +311,13 @@ namespace RTT */ void lognl(); +#ifdef OROSEM_LOG4CPP_LOGGING + /** + * Name of the log4cpp category that RTT logs to + */ + static const std::string log4cppCategoryName; +#endif + private: /** * Returns true if the next message will be logged. diff --git a/rtt/os/targets/target-config.h.in b/rtt/os/targets/target-config.h.in index 67dc4b569..f6b32e20f 100644 --- a/rtt/os/targets/target-config.h.in +++ b/rtt/os/targets/target-config.h.in @@ -63,6 +63,7 @@ #cmakedefine OROSEM_PRINTF_LOGGING #cmakedefine OROSEM_FILE_LOGGING #cmakedefine OROSEM_REMOTE_LOGGING +#cmakedefine OROSEM_LOG4CPP_LOGGING #define ORONUM_LOGGING_BUFSIZE @ORONUM_LOGGING_BUFSIZE@ #define OROPKG_OS