[openrtm-commit:02389] r2922 - trunk/OpenRTM-aist/src/lib/rtm

openrtm @ openrtm.org openrtm @ openrtm.org
2017年 2月 7日 (火) 01:28:35 JST


Author: n-ando
Date: 2017-02-07 01:28:35 +0900 (Tue, 07 Feb 2017)
New Revision: 2922

Added:
   trunk/OpenRTM-aist/src/lib/rtm/LogstreamBase.h
   trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.cpp
   trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.h
Modified:
   trunk/OpenRTM-aist/src/lib/rtm/FactoryInit.cpp
   trunk/OpenRTM-aist/src/lib/rtm/Makefile.am
   trunk/OpenRTM-aist/src/lib/rtm/Manager.cpp
   trunk/OpenRTM-aist/src/lib/rtm/Manager.h
Log:
[incompat,new func] Logging system now supports logstream loadable modules. refs #3567

Modified: trunk/OpenRTM-aist/src/lib/rtm/FactoryInit.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/FactoryInit.cpp	2017-02-06 15:52:37 UTC (rev 2921)
+++ trunk/OpenRTM-aist/src/lib/rtm/FactoryInit.cpp	2017-02-06 16:28:35 UTC (rev 2922)
@@ -5,7 +5,7 @@
  * @date $Date: 2008-03-06 06:58:40 $
  * @author Noriaki Ando <n-ando at aist.go.jp>
  *
- * Copyright (C) 2009
+ * Copyright (C) 2009-2017
  *     Task-intelligence Research Group,
  *     Intelligent Systems Research Institute,
  *     National Institute of
@@ -16,6 +16,9 @@
  *
  */
 
+// Logstream
+#include <rtm/LogstreamFile.h>
+
 // Buffers
 #include <rtm/CdrRingBuffer.h>
 
@@ -37,6 +40,9 @@
 
 void FactoryInit()
 {
+    // Logstream
+    LogstreamFileInit();
+
     // Buffers
     CdrRingBufferInit();
 

Added: trunk/OpenRTM-aist/src/lib/rtm/LogstreamBase.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/LogstreamBase.h	                        (rev 0)
+++ trunk/OpenRTM-aist/src/lib/rtm/LogstreamBase.h	2017-02-06 16:28:35 UTC (rev 2922)
@@ -0,0 +1,105 @@
+// -*- C++ -*-
+/*!
+ * @file LogstreamBase.h
+ * @brief Logger stream buffer base class
+ * @date $Date$
+ * @author Noriaki Ando <n-ando at aist.go.jp>
+ *
+ * Copyright (C) 2017
+ *     Noriaki Ando
+ *     National Institute of
+ *         Advanced Industrial Science and Technology (AIST), Japan
+ *     All rights reserved.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef RTC_LOGSTREAMBASE_H
+#define RTC_LOGSTREAMBASE_H
+
+#include <coil/Properties.h>
+#include <coil/Factory.h>
+#include <coil/Logger.h>
+
+#include <rtm/RTC.h>
+#include <rtm/CdrBufferBase.h>
+#include <rtm/DataPortStatus.h>
+
+namespace RTC
+{
+  /*!
+   * @if jp
+   *
+   * @class PublisherBase
+   *
+   * @brief Publisher 基底クラス
+   * 
+   * データ送出タイミングを管理して送出を駆動するPublisher* の基底クラス。
+   * 各種 Publisher はこのクラスを継承して詳細を実装する。
+   *
+   * @since 0.4.0
+   *
+   * @else
+   *
+   * @class PublisherBase
+   *
+   * @brief Base class of Publisher.
+   *
+   * This is a base class of Publisher*. This class manages data send timing.
+   * Variation of Publisher* which implements details of Publisher inherits
+   * this PublisherBase class.
+   *
+   * @endif
+   */
+  typedef std::basic_streambuf<char> StreambufType;
+  class LogstreamBase
+  {
+  public:
+    /*!
+     * @if jp
+     *
+     * @brief デストラクタ
+     *
+     * @else
+     *
+     * @brief Destructor
+     *
+     * @endif
+     */
+    virtual ~LogstreamBase(void){};
+
+    /*!
+     * @if jp
+     * @brief 設定初期化
+     *
+     * Logstreamクラスの各種設定を行う。実装クラスでは、与えられた
+     * Propertiesから必要な情報を取得して各種設定を行う。
+     * 
+     * @param prop 設定情報
+     *
+     * @else
+     *
+     * @brief Initializing configuration
+     *
+     * This operation would be called to configure in initialization.
+     * In the concrete class, configuration should be performed
+     * getting appropriate information from the given Properties data.
+     *
+     * @param prop Configuration information
+     *
+     * @endif
+     */
+    virtual bool init(const coil::Properties& prop) = 0;
+    
+    virtual StreambufType* getStreamBuffer() = 0;
+
+  };
+
+  typedef coil::GlobalFactory<LogstreamBase> LogstreamFactory;
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+  EXTERN template class DLL_PLUGIN coil::GlobalFactory<LogstreamBase>;
+#endif
+};
+#endif // RTC_LOGSTREAMBASE_H


Property changes on: trunk/OpenRTM-aist/src/lib/rtm/LogstreamBase.h
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.cpp	                        (rev 0)
+++ trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.cpp	2017-02-06 16:28:35 UTC (rev 2922)
@@ -0,0 +1,105 @@
+// -*- C++ -*-
+/*!
+ * @file LogstreamBase.h
+ * @brief Logger stream buffer base class
+ * @date $Date$
+ * @author Noriaki Ando <n-ando at aist.go.jp>
+ *
+ * Copyright (C) 2017
+ *     Noriaki Ando
+ *     National Institute of
+ *         Advanced Industrial Science and Technology (AIST), Japan
+ *     All rights reserved.
+ *
+ * $Id$
+ *
+ */
+#include <algorithm>
+
+#include <rtm/LogstreamBase.h>
+#include <rtm/LogstreamFile.h>
+#include <coil/stringutil.h>
+
+namespace RTC
+{
+  coil::vstring LogstreamFile::s_files;
+  
+  LogstreamFile::LogstreamFile()
+    : m_stdout(NULL), m_fileout(NULL)
+  {
+  }
+
+  LogstreamFile::~LogstreamFile()
+  {
+    s_files.erase(std::remove(s_files.begin(), s_files.end(), m_fileName),
+                  s_files.end());
+    if (m_fileout != NULL)
+      {
+        m_fileout->close();
+      }
+  }
+
+  bool LogstreamFile::init(const coil::Properties& prop)
+  {
+    coil::vstring files = coil::split(prop["file_name"], ",");
+
+    for (size_t i(0); i < files.size(); ++i)
+      {
+        std::cout << "#### file: " << files[i] << std::endl;
+        if (std::count(s_files.begin(), s_files.end(), files[i]) > 0) { continue; }
+        m_fileName = files[i];
+        s_files.push_back(files[i]);
+
+        std::string fname(files[i]);
+        coil::normalize(fname);
+        if (fname == "stdout")
+          {
+            std::cout << "##### STDOUT!! #####" << std::endl;
+            m_stdout = std::cout.rdbuf();
+            return true;
+          }
+        else if (fname == "stderr")
+          {
+            std::cout << "##### STDOUT!! #####" << std::endl;
+            m_stdout = std::cerr.rdbuf();
+            return true;
+          }
+        else
+          {
+            std::cout << "##### file #####" << std::endl;
+            m_fileout = new std::filebuf();
+            m_fileout->open(files[i].c_str(), std::ios::out | std::ios::app);
+            if (m_fileout->is_open()) { return true; }
+          }
+      }
+    return false;
+  }
+
+  StreambufType* LogstreamFile::getStreamBuffer()
+  {
+    if (m_stdout != NULL)
+      {
+        return m_stdout;
+      }
+    else if (m_fileout != NULL)
+      {
+        return m_fileout;
+      }
+    return std::cout.rdbuf();
+  }
+
+};
+
+extern "C"
+{
+  void LogstreamFileInit()
+  {
+    ::RTC::LogstreamFactory::
+      instance().addFactory("file",
+                            ::coil::Creator< ::RTC::LogstreamBase,
+                                             ::RTC::LogstreamFile>,
+                            ::coil::Destructor< ::RTC::LogstreamBase,
+                                                ::RTC::LogstreamFile>);
+  }
+};
+


Property changes on: trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.cpp
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.h	                        (rev 0)
+++ trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.h	2017-02-06 16:28:35 UTC (rev 2922)
@@ -0,0 +1,140 @@
+// -*- C++ -*-
+/*!
+ * @file LogstreamFile.h
+ * @brief File logger stream class
+ * @date $Date$
+ * @author Noriaki Ando <n-ando at aist.go.jp>
+ *
+ * Copyright (C) 2017
+ *     Noriaki Ando
+ *     National Institute of
+ *         Advanced Industrial Science and Technology (AIST), Japan
+ *     All rights reserved.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef RTC_LOGSTREAMFILE_H
+#define RTC_LOGSTREAMFILE_H
+
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <coil/stringutil.h>
+#include <rtm/LogstreamBase.h>
+
+namespace RTC
+{
+  /*!
+   * @if jp
+   *
+   * @class PublisherBase
+   *
+   * @brief Publisher 基底クラス
+   * 
+   * データ送出タイミングを管理して送出を駆動するPublisher* の基底クラス。
+   * 各種 Publisher はこのクラスを継承して詳細を実装する。
+   *
+   * @since 0.4.0
+   *
+   * @else
+   *
+   * @class PublisherBase
+   *
+   * @brief Base class of Publisher.
+   *
+   * This is a base class of Publisher*. This class manages data send timing.
+   * Variation of Publisher* which implements details of Publisher inherits
+   * this PublisherBase class.
+   *
+   * @endif
+   */
+  class LogstreamFile
+    : public LogstreamBase
+  {
+  public:
+    /*!
+     * @if jp
+     *
+     * @brief コンストラクタ
+     *
+     * @else
+     *
+     * @brief Constructor
+     *
+     * @endif
+     */
+    LogstreamFile();
+
+    /*!
+     * @if jp
+     *
+     * @brief デストラクタ
+     *
+     * @else
+     *
+     * @brief Destructor
+     *
+     * @endif
+     */
+    virtual ~LogstreamFile(void);
+
+    /*!
+     * @if jp
+     * @brief 設定初期化
+     *
+     * Logstreamクラスの各種設定を行う。実装クラスでは、与えられた
+     * Propertiesから必要な情報を取得して各種設定を行う。
+     *
+     * @param prop 設定情報
+     *
+     * @else
+     *
+     * @brief Initializing configuration
+     *
+     * This operation would be called to configure in initialization.
+     * In the concrete class, configuration should be performed
+     * getting appropriate information from the given Properties data.
+     *
+     * @param prop Configuration information
+     *
+     * @endif
+     */
+    virtual bool init(const coil::Properties& prop);
+
+    /*!
+     * @if jp
+     * @brief basic_strembuf へのポインタを返す
+     *
+     * Loggerで使用する basic_streambuf へのポインタを返す。
+     *
+     * @return basic_streambuf (coil::LogStreambuf) へのポインタ
+     *
+     * @else
+     *
+     * @brief Returns a pointer to the basic_streambuf 
+     *
+     * This operation would returns a pointer to the basic_streambuf
+     * or its subclass that is kept in this class.
+     *
+     * @return pointer to the basic_streambuf (coil::LogStreambuf)
+     *
+     * @endif
+     */
+    virtual StreambufType* getStreamBuffer();
+
+  protected:
+    static coil::vstring s_files;
+    std::string m_fileName;
+    StreambufType* m_stdout;
+    std::filebuf* m_fileout;
+  };
+}; // namespace RTC
+
+extern "C"
+{
+  void DLL_EXPORT LogstreamFileInit();
+};
+
+#endif // RTC_LOGSTREAMFILE_H


Property changes on: trunk/OpenRTM-aist/src/lib/rtm/LogstreamFile.h
___________________________________________________________________
Added: svn:executable
   + *

Modified: trunk/OpenRTM-aist/src/lib/rtm/Makefile.am
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/Makefile.am	2017-02-06 15:52:37 UTC (rev 2921)
+++ trunk/OpenRTM-aist/src/lib/rtm/Makefile.am	2017-02-06 16:28:35 UTC (rev 2922)
@@ -68,6 +68,7 @@
 	NumberingPolicy.cpp          \
 	ManagerServant.cpp           \
 	SystemLogger.cpp             \
+	LogstreamFile.cpp               \
 	LocalServiceAdmin.cpp        \
 	ManagerActionListener.cpp
 
@@ -168,6 +169,7 @@
 	StateMachine.h 		 \
 	Typename.h               \
 	LocalServiceBase.h	 \
+	LogstreamBase.h      \
 	ListenerHolder.h         \
 	config_rtc.h
 

Modified: trunk/OpenRTM-aist/src/lib/rtm/Manager.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/Manager.cpp	2017-02-06 15:52:37 UTC (rev 2921)
+++ trunk/OpenRTM-aist/src/lib/rtm/Manager.cpp	2017-02-06 16:28:35 UTC (rev 2922)
@@ -42,6 +42,7 @@
 #include <rtm/SdoServiceConsumerBase.h>
 #include <rtm/LocalServiceAdmin.h>
 #include <rtm/SystemLogger.h>
+#include <rtm/LogstreamBase.h>
 
 #ifdef RTM_OS_LINUX
 #ifndef _GNU_SOURCE
@@ -127,10 +128,10 @@
           {
             manager = new Manager();
             manager->initManager(argc, argv);
+            manager->initFactories();
             manager->initLogger();
             manager->initORB();
             manager->initNaming();
-            manager->initFactories();
             manager->initExecContext();
             manager->initComposite();
             manager->initTimer();
@@ -157,10 +158,10 @@
           {
             manager = new Manager();
             manager->initManager(0, NULL);
+            manager->initFactories();
             manager->initLogger();
             manager->initORB();
             manager->initNaming();
-            manager->initFactories();
             manager->initExecContext();
             manager->initComposite();
             manager->initTimer();
@@ -1209,8 +1210,6 @@
     // load configurations
     ManagerConfig config(argc, argv);
     config.configure(m_config);
-    m_config["logger.file_name"] = 
-      formatString(m_config["logger.file_name"].c_str(), m_config);
     
     // initialize ModuleManager
     m_module = new ModuleManager(m_config);
@@ -1298,73 +1297,137 @@
   //============================================================
   /*!
    * @if jp
-   * @brief System logger の初期化
+   * @brief File logger 初期化
+   * initLoggerから呼ばれる
    * @else
-   * @brief System logger initialization
+   * @brief File logger initialization
+   * This function is called from initLogger.
    * @endif
    */
-  bool Manager::initLogger()
+  void Manager::initLogstreamFile()
   {
-    rtclog.setLevel("SILENT");
-    rtclog.setName("manager");
-    
-    if (!coil::toBool(m_config["logger.enable"], "YES", "NO", true))
-      {
-        return true;
-      }
+    // format logger file name
+    m_config["logger.file_name"] = 
+      formatString(m_config["logger.file_name"].c_str(), m_config);
 
-    std::vector<std::string> logouts;
-    logouts = coil::split(m_config["logger.file_name"], ",");
+    std::vector<std::string> logouts =
+      coil::split(m_config["logger.file_name"], ",");
+    coil::Properties& logprop = m_config.getNode("logger");
 
     for (int i(0), len(logouts.size()); i < len; ++i)
       {
-        std::string logfile(logouts[i]);
-        if (logfile == "") continue;
-	
-        // Open logfile
-        if (logfile == "STDOUT" || logfile == "stdout")
+        if (logouts[i].empty()) { continue; }
+
+        LogstreamBase* logstream =
+          LogstreamFactory::instance().createObject("file");
+        if (logstream == NULL)
           {
-            m_logStreamBuf.addStream(std::cout.rdbuf());
+            std::cerr << "\"file\" logger creation failed" << std::endl;
             continue;
           }
-        
-        std::filebuf* of = new std::filebuf();
-        of->open(logfile.c_str(), std::ios::out | std::ios::app);
+        if (!logstream->init(logprop))
+          {
+            std::cerr << "\"file\" logger initialization failed" << std::endl;
+            LogstreamFactory::instance().deleteObject("file", logstream);
+            continue;
+          }
+        m_logStreamBuf.addStream(logstream->getStreamBuffer());
+      }
+  }
 
-        if (!of->is_open())
+  void Manager::initLogstreamPlugins()
+  {
+    // loading logstream module
+    // create logstream object and attach to the logger
+    coil::vstring mods = coil::split(m_config["logger.plugins"], ",");
+    for (size_t i(0); i < mods.size(); ++i)
+      {
+        std::string basename = mods[i].substr(0, mods[i].find('.'));
+        basename += "Init";
+        try
           {
-            std::cerr << "Error: cannot open logfile: "
-                      << logfile << std::endl;
-            delete of;
+            m_module->load(mods[i], basename);
+          }
+        catch (...)
+          {
+            RTC_WARN(("Logstream plugin module load failed: %s",
+                      mods[i].c_str()));
             continue;
           }
-        m_logStreamBuf.addStream(of, true);
-        m_logfiles.push_back(of);
       }
-	
+  }
 
+  void Manager::initLogstreamOthers()
+  {
+    LogstreamFactory& factory(LogstreamFactory::instance());
+
+    coil::Properties pp(m_config.getNode("logger.logstream"));
+
+    const std::vector<Properties*>& leaf0 = pp.getLeaf();
+    for (size_t i(0); i < leaf0.size(); ++i)
+      {
+        std::string lstype = leaf0[i]->getName();
+        LogstreamBase* logstream = factory.createObject(lstype);
+        if (logstream == NULL)
+          {
+            RTC_WARN(("Logstream %s creation failed.", lstype.c_str()));
+            continue;
+          }
+        RTC_INFO(("Logstream %s created.", lstype.c_str()));
+        if (!logstream->init(*leaf0[i]))
+          {
+            RTC_WARN(("Logstream %s init failed.", lstype.c_str()));
+            factory.deleteObject(lstype.c_str(), logstream);
+            RTC_WARN(("Logstream %s deleted.", lstype.c_str()));
+          }
+        RTC_INFO(("Logstream %s added.", lstype.c_str()));
+        m_logStreamBuf.addStream(logstream->getStreamBuffer());
+      }
+  }
+
+  /*!
+   * @if jp
+   * @brief System logger の初期化
+   * @else
+   * @brief System logger initialization
+   * @endif
+   */
+  bool Manager::initLogger()
+  {
+    // Enable logger or not
+    rtclog.setLevel("SILENT");
+    rtclog.setName("manager");
+    if (!coil::toBool(m_config["logger.enable"], "YES", "NO", true))
+      {
+        return true;
+      }
+
     // Set date format for log entry header
     rtclog.setDateFormat(m_config["logger.date_format"].c_str());
     rtclog.setClockType(m_config["logger.clock_type"]);
     // Loglevel was set from configuration file.
     rtclog.setLevel(m_config["logger.log_level"].c_str());
-	
     // Log stream mutex locking mode
-    coil::toBool(m_config["logger.stream_lock"],
-                 "enable", "disable", false) ? 
+    coil::toBool(m_config["logger.stream_lock"], "enable", "disable", false) ?
       rtclog.enableLock() : rtclog.disableLock();
-                 
-	
+
+    // File Logstream init
+    initLogstreamFile();
+    // Load logstream plugin
+    initLogstreamPlugins();
+    // Initialize other logstreams
+    initLogstreamOthers();
+
     RTC_INFO(("%s", m_config["openrtm.version"].c_str()));
-    RTC_INFO(("Copyright (C) 2003-2012"));
+    RTC_INFO(("Copyright (C) 2003-2017"));
     RTC_INFO(("  Noriaki Ando"));
     RTC_INFO(("  Intelligent Systems Research Institute, AIST"));
     RTC_INFO(("Manager starting."));
     RTC_INFO(("Starting local logging."));
 
-    return true;;
+    return true;
   }
-  
+
   /*!
    * @if jp
    * @brief System Logger の終了処理

Modified: trunk/OpenRTM-aist/src/lib/rtm/Manager.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/Manager.h	2017-02-06 15:52:37 UTC (rev 2921)
+++ trunk/OpenRTM-aist/src/lib/rtm/Manager.h	2017-02-06 16:28:35 UTC (rev 2922)
@@ -1187,6 +1187,9 @@
     //============================================================
     // Logger initialize and terminator
     //============================================================
+    void initLogstreamFile();
+    void initLogstreamPlugins();
+    void initLogstreamOthers();
     /*!
      * @if jp
      * @brief System logger の初期化



More information about the openrtm-commit mailing list