LayerManagerUtils: Introducing DLT binding for Logging Framework
authorMichael Schuldt <michael.schuldt@bmw.de>
Tue, 28 Feb 2012 14:34:20 +0000 (15:34 +0100)
committerMichael Schuldt <michael.schuldt@bmw.de>
Tue, 28 Feb 2012 14:34:20 +0000 (15:34 +0100)
- Due to the fact that in Genivi the automotive dlt should
  be used as standard logging component the Logging Class was
  extended by this functionality.

- To use that component please recompile with the option WITH_DLT=ON

CMakeLists.txt
LayerManagerPlugins/Communicators/DBUSCommunicator/test/CMakeLists.txt
LayerManagerService/CMakeLists.txt
LayerManagerService/include/config.h.cmake
LayerManagerService/src/main.cpp
LayerManagerUtils/CMakeLists.txt
LayerManagerUtils/include/Log.h
LayerManagerUtils/src/Log.cpp
LayerManagerUtils/tests/LogTest.cpp
cmake/modules/FindAutomotiveDlt.cmake [new file with mode: 0644]

index 89e4abf..0b42ba3 100644 (file)
@@ -45,6 +45,7 @@ option (WITH_FORCE_COPY     "Force Software Copy of Pixmaps"
 option (WITH_XTHREADS       "Build with usage of X11 Threading"                   ON )
 option (WITH_CLIENTEXAMPLES "Build client examples "                              ON )
 option (WITH_TESTS          "Build Available Tests "                              OFF)
+option (WITH_DLT            "Build with DLT support "                             OFF)
 
 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
 
index bc40185..a45e32f 100644 (file)
@@ -7,7 +7,7 @@
 # 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 
+#       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, 
@@ -31,7 +31,7 @@ include_directories(${DBUS_INCLUDE_DIR})
 include_directories(${DBUS_ARCH_INCLUDE_DIR})
 
 find_package (Threads)
-set(LIBS ${LIBS} ${DBUS_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} LayerManagerUtils)
+set(LIBS ${LIBS} ${DBUS_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} LayerManagerUtils ${DLT_LIBRARY})
 
 file(GLOB LM_SOURCES "${PROJECT_SOURCE_DIR}/LayerManagerService/src/Scene.cpp"
                      "${PROJECT_SOURCE_DIR}/LayerManagerService/src/Layermanager.cpp"
index 39c04f8..525d1ea 100644 (file)
@@ -7,7 +7,7 @@
 # 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 
+#       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, 
@@ -50,7 +50,8 @@ set(LIBS ${LIBS}
          LayerManagerUtils 
          LayerManagerCommands
          dl
-         ${CMAKE_THREAD_LIBS_INIT}) 
+         ${CMAKE_THREAD_LIBS_INIT}
+         ${DLT_LIBRARY}) 
 target_link_libraries(LayerManagerService ${LIBS})
 
 install (TARGETS LayerManagerService DESTINATION bin)
@@ -87,4 +88,4 @@ target_link_libraries(LayerManagerService_Test ${LIBS} gtest gmock)
 
 add_test(LayerManagerService LayerManagerService_Test )
 
-endif(WITH_TESTS) 
\ No newline at end of file
+endif(WITH_TESTS) 
index 74cb883..ab223d0 100644 (file)
 // build unit tests for all projects
 #cmakedefine WITH_TESTS
 
-// build OpenGL ES 2.0/X11 renderer
+// build OpenGL ES 2.0 / X11 renderer
 #cmakedefine WITH_X11_GLES
 
 // use xthreads library
 #cmakedefine WITH_XTHREADS
 
+// use automotive dlt for logging
+#cmakedefine WITH_DLT
 
 //-----------------------------------------------------------------------------
 // human readable report
@@ -92,5 +94,5 @@
     LOG_DEBUG("Config", "WITH_INPUT_EVENTS   = ${WITH_INPUT_EVENTS}"); \
     LOG_DEBUG("Config", "WITH_TESTS          = ${WITH_TESTS}"); \
     LOG_DEBUG("Config", "WITH_X11_GLES       = ${WITH_X11_GLES}"); \
-    LOG_DEBUG("Config", "WITH_XTHREADS       = ${WITH_XTHREADS}")
-
+    LOG_DEBUG("Config", "WITH_XTHREADS       = ${WITH_XTHREADS}"); \
+    LOG_DEBUG("Config", "WITH_DLT            = ${WITH_DLT}");
index 79bae55..87b50d9 100644 (file)
@@ -537,7 +537,7 @@ int main(int argc, char **argv)
     signal(SIGTERM, SIG_DFL);
     signal(SIGINT, SIG_DFL);
 
-    LOG_INFO("LayerManagerService", "Shutdown complete.")
-
+    LOG_INFO("LayerManagerService", "Shutdown complete.")    
+    Log::closeInstance();
     return (int)started - 1;
 }
index 037eac1..8d55eec 100644 (file)
@@ -7,7 +7,7 @@
 # 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 
+#       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, 
 cmake_minimum_required (VERSION 2.6)
 
 include_directories ("include")
+include_directories ("${PROJECT_SOURCE_DIR}/LayerManagerService/include")
+if (WITH_DLT)
+find_package(AutomotiveDlt REQUIRED)
+include_directories(${DLT_INCLUDE_DIR})
+endif (WITH_DLT)
+
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
 add_library(LayerManagerUtils STATIC src/Bitmap.cpp src/IlmMatrix.cpp src/Log.cpp src/LogMessageBuffer.cpp)
 
@@ -30,8 +36,8 @@ install (TARGETS LayerManagerUtils ARCHIVE DESTINATION lib/layermanager/static)
 if (WITH_TESTS)
 
 add_executable(UtilsTest tests/BitmapTest.cpp tests/LogTest.cpp)
-target_link_libraries(UtilsTest LayerManagerUtils gtest pthread)
+target_link_libraries(UtilsTest LayerManagerUtils gtest pthread ${DLT_LIBRARY})
 enable_testing()
 add_test(Utilities UtilsTest)
 
-endif(WITH_TESTS) 
\ No newline at end of file
+endif(WITH_TESTS) 
index 0558d42..d6945df 100644 (file)
 */
 #ifndef _LOG_H_
 #define _LOG_H_
-
+#include "config.h"
 #include "LogMessageBuffer.h"
 #include <iostream>
 #include <fstream>
 #include <pthread.h>
 
+#ifdef WITH_DLT
+#include <dlt/dlt.h>
+#endif
+
 typedef enum {
     LOG_DISABLED = 0,
     LOG_ERROR = 1,
@@ -51,51 +55,62 @@ typedef enum {
     LOG_MAX_LEVEL
 } LOG_MODES;
 
+#ifdef WITH_DLT
+typedef DltContext LogContext;
+#else 
+typedef std::string LogContext;
+#endif
+
 class Log
 {
 public:
     virtual ~Log();
-    static Log* instance;
     static LOG_MODES fileLogLevel;
     static LOG_MODES consoleLogLevel;
-    void warning (const std::string& moduleName, const std::basic_string<char>& output);
-    void info (const std::string& moduleName, const std::basic_string<char>& output);
-    void error (const std::string& moduleName, const std::basic_string<char>& output);
-    void debug (const std::string& moduleName, const std::basic_string<char>& output);
-    void log(LOG_MODES logMode, const std::string& moduleName, const std::basic_string<char>& output);
-
+    static LOG_MODES dltLogLevel;
+    static Log* getInstance();
+    void warning (LogContext *logContext, const std::string& moduleName, const std::basic_string<char>& output);
+    void info (LogContext *logContext, const std::string& moduleName, const std::basic_string<char>& output);
+    void error (LogContext *logContext, const std::string& moduleName, const std::basic_string<char>& output);
+    void debug (LogContext *logContext, const std::string& moduleName, const std::basic_string<char>& output);
+    void log(LogContext *logContext, LOG_MODES logMode, const std::string& moduleName, const std::basic_string<char>& output);
+    LogContext* getLogContext();
+    static void closeInstance();
 private:
     Log();
     void LogToFile(std::string logMode, const std::string& moduleName, const std::basic_string<char>& output);
-    void LogToConsole(std::string logMode,const std::string& moduleName,const std::basic_string<char>& output);
-
+    void LogToConsole(std::string logMode, const std::string& moduleName,const std::basic_string<char>& output);
+#ifdef WITH_DLT
+    void LogToDltDaemon(LogContext *logContext, LOG_MODES logMode,const std::string& moduleName,const std::basic_string<char>& output);
+#endif    
 private:
     std::ofstream* m_fileStream;
     pthread_mutex_t m_LogBufferMutex;
+    LogContext m_logContext;
+    static Log* m_instance;
 };
 
-//#define LOG_ERROR(module, message)
+//#define LOG_ERROR(logcontext,module, message)
 
 #define LOG_ERROR(module, message) { \
            LogMessageBuffer oss_; \
-           Log::instance->error(module, oss_.str(oss_<< message)); }
+           Log::getInstance()->error(Log::getInstance()->getLogContext(), module, oss_.str(oss_<< message)); }
 
-//#define LOG_INFO(module, message)
+//#define LOG_INFO(logcontext,module, message)
 
 #define LOG_INFO(module, message) { \
            LogMessageBuffer oss_; \
-           Log::instance->info(module, oss_.str(oss_<< message)); }
+           Log::getInstance()->info(Log::getInstance()->getLogContext(), module, oss_.str(oss_<< message)); }
 
-//#define LOG_DEBUG(module, message)
+//#define LOG_DEBUG(logcontext,module, message)
 
 #define LOG_DEBUG(module, message) { \
            LogMessageBuffer oss_; \
-           Log::instance->debug(module, oss_.str(oss_<< message)); }
+           Log::getInstance()->debug(Log::getInstance()->getLogContext(), module, oss_.str(oss_<< message)); }
 
-//#define LOG_WARNING(module, message)
+//#define LOG_WARNING(logcontext,module, message)
 
 #define LOG_WARNING(module, message) { \
            LogMessageBuffer oss_; \
-           Log::instance->warning(module, oss_.str(oss_<< message)); }
-
+           Log::getInstance()->warning(Log::getInstance()->getLogContext(), module, oss_.str(oss_<< message)); }
 #endif /* _LOG_H_ */
index fc8aa4c..ee3234e 100644 (file)
 #include "Log.h"
 #include <iomanip>
 
-Log* Log::instance = new Log();
+Log* Log::m_instance = NULL;
 LOG_MODES Log::fileLogLevel = LOG_DISABLED;
 LOG_MODES Log::consoleLogLevel = LOG_INFO;
+LOG_MODES Log::dltLogLevel = LOG_DEBUG;
 
 Log::Log()
 {
     // TODO Auto-generated constructor stub
     m_fileStream = new std::ofstream("/tmp/LayerManagerService.log");
     pthread_mutex_init(&m_LogBufferMutex, NULL);
+#ifdef WITH_DLT
+    DLT_REGISTER_APP("LMSA","LayerManagerService");
+    DLT_REGISTER_CONTEXT(m_logContext,"LMSC","LayerManagerService");
+#else 
+    m_logContext = "LMSC";
+#endif     
+}
+
+Log* Log::getInstance()
+{
+    if ( m_instance == NULL ) 
+    {
+        m_instance = new Log();
+    }
+    return m_instance;
+}
 
+void Log::closeInstance()
+{
+    delete m_instance;
+    m_instance = NULL;
 }
 
 Log::~Log()
@@ -55,30 +76,33 @@ Log::~Log()
     // TODO Auto-generated destructor stub
     m_fileStream->close();
     pthread_mutex_destroy(&m_LogBufferMutex);
-    Log::instance = NULL;
+    Log::m_instance = NULL;
+#ifdef WITH_DLT
+    DLT_UNREGISTER_CONTEXT(m_logContext);
+#endif    
 }
 
-void Log::warning (const std::string& moduleName, const std::basic_string<char>& output)
+void Log::warning (LogContext* logContext, const std::string& moduleName, const std::basic_string<char>& output)
 {
-    log(LOG_WARNING, moduleName, output);
+    log(logContext,LOG_WARNING, moduleName, output);
 }
 
-void Log::info (const std::string& moduleName, const std::basic_string<char>& output)
+void Log::info (LogContext* logContext,const std::string& moduleName, const std::basic_string<char>& output)
 {
-    log(LOG_INFO, moduleName, output);
+    log(logContext, LOG_INFO, moduleName, output);
 }
 
-void Log::error (const std::string& moduleName, const std::basic_string<char>& output)
+void Log::error (LogContext* logContext,const std::string& moduleName, const std::basic_string<char>& output)
 {
-    log(LOG_ERROR, moduleName, output);
+    log(logContext, LOG_ERROR, moduleName, output);
 }
 
-void Log::debug (const std::string& moduleName, const std::basic_string<char>& output)
+void Log::debug (LogContext* logContext, const std::string& moduleName, const std::basic_string<char>& output)
 {
-    log(LOG_DEBUG, moduleName, output);
+    log(logContext,  LOG_DEBUG, moduleName, output);
 }
 
-void Log::log(LOG_MODES logMode, const std::string& moduleName, const std::basic_string<char>& output)
+void Log::log(LogContext* logContext, LOG_MODES logMode, const std::string& moduleName, const std::basic_string<char>& output)
 {
     std::string logString[LOG_MAX_LEVEL] = {"","ERROR","INFO","WARNING","DEBUG"};
     std::string logOutLevelString = logString[LOG_INFO];
@@ -95,6 +119,12 @@ void Log::log(LOG_MODES logMode, const std::string& moduleName, const std::basic
     {
         LogToFile(logOutLevelString, moduleName, output);
     }   
+#ifdef WITH_DLT
+    if ( dltLogLevel >= logMode ) 
+    {
+        LogToDltDaemon(logContext, logMode, moduleName, output);
+    }   
+#endif    
     pthread_mutex_unlock(&m_LogBufferMutex);
 }
 
@@ -138,3 +168,35 @@ void Log::LogToConsole(std::string logMode, const std::string& moduleName, const
               << output << std::endl;
 }
 
+LogContext* Log::getLogContext()
+{
+    return &m_logContext;
+}
+
+#ifdef WITH_DLT    
+void Log::LogToDltDaemon(LogContext *logContext, LOG_MODES logMode, const std::string& moduleName, const std::basic_string<char>& output)
+{
+    
+    std::stringstream oss;
+    std::string dltString;
+    static unsigned int maxLengthModuleName = 0;
+
+    if (moduleName.length() > maxLengthModuleName)
+    {
+        maxLengthModuleName = moduleName.length();
+    }
+    oss << std::setw(maxLengthModuleName)  << std::left << moduleName << " | "
+     << output << std::endl;
+    dltString = oss.str();                         
+    switch ( logMode ) 
+    {
+        case LOG_INFO : DLT_LOG(*logContext,DLT_LOG_INFO,DLT_STRING(dltString.c_str())); break;
+        case LOG_ERROR : DLT_LOG(*logContext,DLT_LOG_ERROR,DLT_STRING(dltString.c_str())); break;
+        case LOG_DEBUG : DLT_LOG(*logContext,DLT_LOG_DEBUG,DLT_STRING(dltString.c_str())); break;
+        case LOG_WARNING : DLT_LOG(*logContext,DLT_LOG_WARN,DLT_STRING(dltString.c_str())); break;
+        default:
+            DLT_LOG(*logContext,DLT_LOG_INFO,DLT_STRING(dltString.c_str()));
+    }
+}
+#endif              
+
index 67e26f7..13061da 100644 (file)
@@ -52,21 +52,21 @@ bool checkLogFileForMessage(std::string message)
 
 
 TEST(LogTest, writeAWarning) {
-    Log::instance->fileLogLevel = LOG_MAX_LEVEL;
+    Log::getInstance()->fileLogLevel = LOG_MAX_LEVEL;
     LOG_WARNING(moduleName, "writeAWarning");
 
     ASSERT_TRUE(checkLogFileForMessage("writeAWarning"));
 }
 
 TEST(LogTest, writeAnError) {
-    Log::instance->fileLogLevel = LOG_INFO;
+    Log::getInstance()->fileLogLevel = LOG_INFO;
     LOG_ERROR(moduleName, "writeAnError");
 
     ASSERT_TRUE(checkLogFileForMessage("writeAnError"));
 }
 
 TEST(LogTest, writeAnInformation) {
-    Log::instance->fileLogLevel = LOG_INFO;
+    Log::getInstance()->fileLogLevel = LOG_INFO;
     LOG_INFO(moduleName, "writeAnInformation");
 
     ASSERT_TRUE(checkLogFileForMessage("writeAnInformation"));
@@ -76,7 +76,7 @@ TEST(LogTest, writeAnInformation) {
 TEST(LogTest, logSomethingWithLowerLogLevel) {
 
     // when disabled, nothing should ever be logged
-    Log::instance->fileLogLevel = LOG_DISABLED;
+    Log::getInstance()->fileLogLevel = LOG_DISABLED;
     LOG_ERROR(moduleName, "err1");
     ASSERT_FALSE(checkLogFileForMessage("err1"));
 
@@ -90,7 +90,7 @@ TEST(LogTest, logSomethingWithLowerLogLevel) {
     ASSERT_FALSE(checkLogFileForMessage("info1"));
 
     // when error is set, only higher levels may be logged
-    Log::instance->fileLogLevel = LOG_ERROR;
+    Log::getInstance()->fileLogLevel = LOG_ERROR;
     LOG_ERROR(moduleName, "err2");
     ASSERT_TRUE(checkLogFileForMessage("err2"));
 
@@ -104,7 +104,7 @@ TEST(LogTest, logSomethingWithLowerLogLevel) {
     ASSERT_FALSE(checkLogFileForMessage("info2"));
 
     // when debug is set, only higher levels may be logged
-    Log::instance->fileLogLevel = LOG_DEBUG;
+    Log::getInstance()->fileLogLevel = LOG_DEBUG;
     LOG_ERROR(moduleName, "err3");
     ASSERT_TRUE(checkLogFileForMessage("err3"));
 
@@ -118,7 +118,7 @@ TEST(LogTest, logSomethingWithLowerLogLevel) {
     ASSERT_TRUE(checkLogFileForMessage("info3"));
 
     // when info is set, only higher levels may be logged
-    Log::instance->fileLogLevel = LOG_INFO;
+    Log::getInstance()->fileLogLevel = LOG_INFO;
     LOG_ERROR(moduleName, "err4");
     ASSERT_TRUE(checkLogFileForMessage("err4"));
 
diff --git a/cmake/modules/FindAutomotiveDlt.cmake b/cmake/modules/FindAutomotiveDlt.cmake
new file mode 100644 (file)
index 0000000..8808373
--- /dev/null
@@ -0,0 +1,48 @@
+############################################################################
+# 
+# Copyright 2012, BMW AG
+# 
+# 
+# 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.
+#
+############################################################################
+
+FIND_PACKAGE(PkgConfig)
+IF (PKG_CONFIG_FOUND)
+# added aditional pkg config check to find dbus dependend includes
+    pkg_check_modules(DLT_PKG_PATHS automotive-dlt)
+ENDIF (PKG_CONFIG_FOUND)
+
+
+FIND_PATH(DLT_INCLUDE_DIR dlt/dlt.h
+${DLT_PKG_PATHS_INCLUDE_DIRS}
+/usr/include
+)
+
+
+FIND_LIBRARY(DLT_LIBRARY
+NAMES dlt
+PATHS /lib
+)
+
+SET( DLT_FOUND "NO" )
+IF(DLT_LIBRARY)
+    SET( DLT_FOUND "YES" )
+    message(STATUS "Found Dlt libs: ${DLT_LIBRARY}")
+    message(STATUS "Found Dlt includes: ${DLT_INCLUDE_DIR}")
+ENDIF(DLT_LIBRARY)
+
+MARK_AS_ADVANCED(
+  DLT_INCLUDE_DIR
+  DLT_LIBRARY
+)