メインページ | ネームスペース一覧 | クラス階層 | 構成 | Directories | ファイル一覧 | ネームスペースメンバ | 構成メンバ | ファイルメンバ

SystemLogger.h

説明を見る。
00001 // -*- C++ -*-
00019 /*
00020  * $Log: SystemLogger.h,v $
00021  * Revision 1.5.2.1  2007/07/20 16:10:32  n-ando
00022  * Some trivial fixes.
00023  *
00024  * Revision 1.5  2007/04/26 15:33:44  n-ando
00025  * The header include order was modified to define _REENTRANT before
00026  * including ace/config-lite.h in Linux systems.
00027  * In ace 5.4.7 or later, _REENTRANT flag should be defined explicitly.
00028  *
00029  * Revision 1.4  2007/04/13 16:01:32  n-ando
00030  * Timing of mutex acquisition was changed for buffer synchronization bugs.
00031  *
00032  * Revision 1.3  2007/01/21 10:37:55  n-ando
00033  * Dtor for sync_callback and basic_ummybuf classes was defined.
00034  * A trivial fix;
00035  *
00036  * Revision 1.2  2006/11/04 20:54:09  n-ando
00037  * classes were renamed and soruce code was re-formatted.
00038  *
00039  * Revision 1.1  2006/11/02 15:14:24  n-ando
00040  * RtcSystemLogger.h was moved to SystemLogger.h.
00041  *
00042  * Revision 1.2  2005/05/16 06:40:19  n-ando
00043  * - Dummy macro "__restrict" was defined for Windows port.
00044  * - Some bugs were fixed.
00045  *
00046  * Revision 1.1.1.1  2005/05/12 09:06:18  n-ando
00047  * Public release.
00048  *
00049  *
00050  */
00051 
00052 #ifndef SystemLogger_h
00053 #define SystemLogger_h
00054 
00055 #include <rtm/RTC.h>
00056 
00057 #include <iostream>
00058 #include <fstream>
00059 #include <stdio.h>
00060 #include <stdarg.h>
00061 #include <limits.h>
00062 #include <time.h>
00063 #include <errno.h>
00064 
00065 // ACE
00066 #include <ace/Mutex.h>
00067 
00068 #include <rtm/config_rtc.h>
00069 
00070 #ifdef RTM_GCC2
00071 #define NO_LOGGING
00072 #endif
00073 
00074 #ifdef WIN32
00075 // It's dummy
00076 #define __restrict
00077 #endif
00078 
00079 namespace RTC
00080 {
00081   
00082 #ifndef NO_LOGGING 
00083   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00084   class sync_callback
00085   {
00086   public:
00087     virtual ~sync_callback(){}
00088     virtual int operator()(const _CharT* s) = 0;
00089   };
00090   
00091   //============================================================
00111   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00112   class basic_logbuf
00113     : public std::basic_filebuf<_CharT, _Traits>
00114   {
00115   public:
00116     // Types:
00117     typedef _CharT                                     char_type;
00118     typedef _Traits                                    traits_type;
00119     typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00120     
00134     basic_logbuf()
00135       : __filebuf_type(), m_pCallBack(NULL)
00136     {;}
00137     
00151     basic_logbuf(const char_type* s,
00152                  std::ios_base::openmode mode = std::ios_base::out, 
00153                  long protection = 0666)
00154       : __filebuf_type(), m_pCallBack(NULL)
00155     {
00156       this->open(s, mode);
00157     }
00158     
00172     virtual ~basic_logbuf()
00173     {
00174       this->sync();
00175       this->close();
00176     };
00177     
00178     virtual std::streamsize sputn(const char_type* s, std::streamsize n)
00179     {
00180       ACE_Guard<ACE_Thread_Mutex> gaurd(m_Mutex);
00181       //          std::string ss(s, n);
00182       //          std::string sss;
00183       //          sss = "HogeDara" + ss;
00184       std::streamsize ssize = this->xsputn(s, n);
00185       /*
00186         if (m_pCallBack != NULL)
00187         {
00188         (*m_pCallBack)(sss.c_str());
00189         }
00190       */
00191       this->sync();
00192       return ssize;
00193     }
00194     
00195     void setSyncCallBack(sync_callback<char_type>& cb)
00196     {
00197       m_pCallBack = &cb;
00198     }
00199     
00200   protected:
00214     virtual int sync()
00215     {
00216       std::string::basic_string<_CharT> s(this->pbase(),
00217                                           this->pptr() - this->pbase());
00218       if (m_pCallBack != NULL)
00219         {
00220           (*m_pCallBack)(s.c_str());
00221         }
00222       
00223       // __filebuf_type::sync() resets the pointer
00224       int ret = __filebuf_type::sync();
00225       
00226       return ret;
00227     }
00228     
00229   private:
00230     ACE_Thread_Mutex m_Mutex;
00231     sync_callback<char_type>* m_pCallBack;
00232     
00233   };
00234   
00235   
00236   
00237   //============================================================
00257   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00258   class basic_medlogbuf
00259     : public std::basic_streambuf<_CharT, _Traits>
00260   {
00261   public:
00262     // Types:
00263     typedef _CharT                                       char_type;
00264     typedef _Traits                                      traits_type;
00265     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00266     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00267     
00282     basic_medlogbuf()
00283       : __streambuf_type(), m_pLogbuf(NULL)
00284     {
00285       // W3C standard date and time format.
00286       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00287     }
00288     
00289     basic_medlogbuf(__filebuf_type& filebuf)
00290       : __streambuf_type(), m_pLogbuf(&filebuf)
00291     {
00292       char *pStart = m_Data;
00293       char *pEnd = m_Data + (LINE_MAX - 1);
00294       this->setp(pStart, pEnd);            // 書き込みポインタ。
00295       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00296       
00297       // W3C standard date and time format.
00298       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00299     }
00300     
00314     virtual ~basic_medlogbuf()
00315     {
00316       this->sync();
00317     }
00318     
00319     void setBuffer(__filebuf_type& filebuf)
00320     {
00321       m_pLogbuf = &filebuf;
00322       char *pStart = m_Data;
00323       char *pEnd = m_Data + (LINE_MAX - 1);
00324       this->setp(pStart, pEnd);            // 書き込みポインタ。
00325       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00326     }
00327     
00365     void setDateFmt(char* fmt)
00366     {
00367       m_DateFmt = std::string(fmt);
00368     }
00369     
00381     void setDateFmt(const std::string& fmt)
00382     {
00383       m_DateFmt = fmt;
00384     }
00385     
00397     std::string getFmtDate()
00398     {
00399       const int maxsize = 256;
00400       char buf[maxsize];
00401       
00402       /*
00403         struct timeval tp;
00404         struct timezone tzp;
00405         gettimeofday(&tp, &tzp);
00406       */
00407       time_t timer;
00408       struct tm* date;
00409       
00410       timer = time(NULL);
00411       date = localtime(&timer);
00412       strftime(buf, maxsize, m_DateFmt.c_str(), date);
00413       
00414       std::string ret(buf);
00415       return ret;
00416     }
00417     
00429     void setSuffix(char* suffix)
00430     {
00431       m_Suffix = std::string(suffix);
00432     }
00433     
00445     void setSuffix(const std::string& suffix)
00446     {
00447       m_Suffix = suffix;
00448     }
00449     
00461     std::string getSuffix()
00462     {
00463       return m_Suffix;
00464     }
00465     
00466     /*
00467       void setCallBack(void (*call_back)(std::string s))
00468       {
00469       
00470       }
00471     */
00472     
00473   protected:
00487     virtual int sync()
00488     {
00489       ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00490       int ret(0); 
00491       if (m_pLogbuf != NULL &&
00492           (this->pptr() - this->pbase()) > 0)
00493         {
00494           {
00495             //ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00496             *(this->pptr()) = '\0';
00497             std::string::basic_string<_CharT> tmp(this->pbase(),
00498                                                   this->pptr() - 
00499                                                   this->pbase());
00500             
00501             std::string s = getFmtDate();
00502             s += ( s.size() > 0 ? " " : "" ) + getSuffix();
00503             s += ( getSuffix().size() > 0 ? " " : "" ) + tmp;
00504             // s += (getSuffix().size() > 0 ? " " : "" ) + getSuffix();
00505             // s += (s.size() > 0 ? " " : "") + tmp;
00506             m_pLogbuf->sputn(s.c_str(), s.size());
00507             m_pLogbuf->pubsync();
00508             // Reset pptr() pointer to pbase()
00509             // __streambuf_type::sync() resets the pointer
00510             ret = __streambuf_type::sync();
00511             pbump( this->pbase() - this->pptr() );
00512           }
00513         }
00514       return ret;
00515     }
00516     
00517   private:
00518     __filebuf_type* m_pLogbuf;
00519     char m_Data[LINE_MAX];
00520     std::string m_DateFmt;
00521     std::string m_Suffix;
00522     ACE_Thread_Mutex m_Mutex;
00523   };
00524   
00525   
00544   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00545   class basic_dummybuf
00546     : public std::basic_streambuf<_CharT, _Traits>
00547   {
00548   public:
00549     // Types:
00550     typedef _CharT                               char_type;
00551     typedef _Traits                              traits_type;
00552     typedef typename traits_type::int_type       int_type;
00553     typedef typename traits_type::pos_type       pos_type;
00554     typedef typename traits_type::off_type       off_type;
00555     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00556     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00557     
00558     basic_dummybuf()
00559     {
00560       char *pStart = m_Data;
00561       char *pEnd = m_Data + (LINE_MAX - 1);
00562       this->setp(pStart, pEnd);
00563       this->setg(pStart, pStart, pEnd);
00564     }
00565 
00566     ~basic_dummybuf()
00567     {
00568     }
00569     
00570     int_type overflow(int_type c = _Traits::eof() )
00571     {
00572       pbump( this->pbase() - this->pptr() );
00573       return _Traits::not_eof(c);
00574     }
00575     
00576     virtual int sync()
00577     {
00578       pbump( this->pbase() - this->pptr() );
00579       return 0;
00580     }
00581     
00582   private:
00583     char m_Data[255];
00584   };
00585   
00586   
00605   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00606   class basic_logstream
00607     : public std::basic_ostream<_CharT, _Traits>
00608   {
00609   public:
00610     // Loglevel
00611     enum
00612       {          // No: Write out messages include the following.
00613         RTL_SILENT,  // 0: ()
00614         RTL_ERROR,   // 1: (ERROR)
00615         RTL_WARN,    // 2: (ERROR, WARN)
00616         RTL_INFO,    // 3: (ERROR, WARN, INFO)
00617         RTL_NORMAL,  // 4: (ERROR, WARN, INFO, NORMAL)
00618         RTL_DEBUG,   // 5: (ERROR, WARN, INFO, NORMAL, DEBUG)
00619         RTL_TRACE,   // 6: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE)
00620         RTL_VERBOSE, // 7: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE)
00621         RTL_PARANOID,// 8: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARA)
00622         RTL_MANDATORY// This level is used for only LogLockLevel
00623       };
00624     
00625     static int strToLogLevel(const std::string& lv)
00626     {
00627       if (lv == "SILENT")
00628         return basic_logstream::RTL_SILENT;
00629       else if (lv == "ERROR")
00630         return basic_logstream::RTL_ERROR;
00631       else if (lv == "WARN")
00632         return basic_logstream::RTL_WARN;
00633       else if (lv == "INFO")
00634         return basic_logstream::RTL_INFO;
00635       else if (lv == "NORNAL")
00636         return basic_logstream::RTL_NORMAL;
00637       else if (lv == "DEBUG")
00638         return basic_logstream::RTL_DEBUG;
00639       else if (lv == "TRACE")
00640         return basic_logstream::RTL_TRACE;
00641       else if (lv == "VERBOSE")
00642         return basic_logstream::RTL_VERBOSE;
00643       else if (lv == "PARANOID")
00644         return basic_logstream::RTL_PARANOID;
00645       else if (lv == "MANDATORY")
00646         return basic_logstream::RTL_MANDATORY;
00647       else
00648         return basic_logstream::RTL_NORMAL;
00649     }
00650     
00651     // Types:
00652     typedef _CharT                                       char_type;
00653     typedef _Traits                                      traits_type;
00654     typedef basic_logbuf<char_type, traits_type>         __logbuf_type;
00655     typedef basic_dummybuf<char_type, traits_type>       __dummybuf_type;
00656     typedef basic_logstream<char_type, traits_type>      __logstream_type;
00657     typedef std::basic_ostream<char_type, traits_type>   __ostream_type;
00658     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00659     
00675     basic_logstream(__streambuf_type& streambuf)
00676       : __ostream_type(&streambuf),
00677         m_DummyStream(new __dummybuf_type()),
00678         m_LogLevel(RTL_NORMAL), m_LogLock(false)
00679     {
00680       this->init(&streambuf);
00681     }
00682     
00696     ~basic_logstream()
00697     {
00698     }
00699     
00711     /*
00712       __logbuf_type*    rdbuf() const
00713       {
00714       return const_cast<__logbuf_type*>(&m_Streambuf);
00715       }
00716     */
00717     
00731     static std::string printf(char const * __restrict fmt, ...)
00732     {
00733       char str[LINE_MAX];
00734       va_list ap;
00735       
00736       va_start(ap, fmt);
00737 #ifdef WIN32
00738       _vsnprintf(str, LINE_MAX - 1, fmt, ap);
00739 #else
00740       vsnprintf(str, LINE_MAX - 1, fmt, ap);
00741 #endif
00742       va_end(ap);
00743       std::string s(str);
00744       
00745       return s;
00746     }
00747     
00748     
00749     void setLogLevel(const std::string& level)
00750     {
00751       m_LogLevel = strToLogLevel(level);
00752     }
00753 
00754     void setLogLevel(int level)
00755     {
00756       m_LogLevel = level;
00757     }
00758     
00759     void setLogLock(bool lock)
00760     {
00761       m_LogLock = lock;
00762     }
00763     
00764     
00765     void enableLogLock()
00766     {
00767       m_LogLock = true;
00768     }
00769     
00770     void disableLogLock()
00771     {
00772       m_LogLock = false;
00773     }
00774     
00775     __ostream_type& level(int level)
00776     {
00777       if (m_LogLevel >= level)
00778         {
00779           return *this;
00780         }
00781       else
00782         {
00783           return m_DummyStream;
00784         }
00785       
00786     }
00787     
00788     inline void acquire()
00789     {
00790       if (m_LogLock) m_Mutex.acquire();
00791     }
00792     
00793     inline void release()
00794     {
00795       if (m_LogLock) m_Mutex.release();
00796     }
00797     
00798     __ostream_type m_DummyStream;
00799     
00800   private:
00801     int m_LogLevel;
00802     bool m_LogLock;
00803     ACE_Thread_Mutex m_Mutex;
00804     
00805   };
00806   typedef sync_callback<char>   SyncCallback;
00807   typedef basic_logbuf<char>    Logbuf;
00808   typedef basic_medlogbuf<char> MedLogbuf;
00809   typedef basic_logstream<char> LogStream;
00810   
00811 #else 
00812   
00813   class SyncCallback
00814   {
00815   public:
00816     SyncCallback() {;};
00817     virtual int operator()(const char* s) {;};
00818   };
00819   
00820   class Logbuf
00821   {
00822   public:
00823     Logbuf() {;};
00824     Logbuf(const char* s, int m) {;};
00825     void open(const char* s, int m) {;};
00826     void setSyncCallBack(SyncCallback& cb) {;};
00827   };
00828   
00829   class MedLogbuf
00830   {
00831   public:
00832     MedLogbuf() {;};
00833     MedLogbuf(Logbuf& f) {;};
00834     void setDateFmt(char* fmt) {;};
00835     void setDateFmt(const std::string& fmt) {;};
00836     void setSuffix(const char* suffix) {;};
00837     void setSuffix(const std::string& suffix) {;};
00838   };
00839   
00840   class LogStream
00841     : public ostream
00842   {
00843   public:
00844     enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
00845     static int strToLogLevel(const std::string& lv){return NORMAL;}
00846     LogStream(MedLogbuf& buf) {;};
00847     void setLogLevel(int level) {;};
00848     void setLogLock(int lock) {;};
00849     LogStream& level(int level) {return *this;};
00850     /*
00851       LogStream& operator<<(const char* s) {return *this;};
00852       LogStream& operator<<(const string s) {return *this;};
00853       LogStream& operator<<(const ostream& o) {return *this;};
00854       LogStream& operator<<(const ostream o) {return *this;};
00855     */
00856   };
00857   
00858 #endif // NO_LOGGING  
00859   
00860   
00861   // __VA_ARGS__ cannot be used in VC   
00862 #if 0
00863 #define RTC_LOG(LV, fmt, ...) \
00864   rtcout.level(LV) << rtcout.printf(fmt, __VA_ARGS__) << std::endl;
00865 #define RTC_ERROR(fmt, ...) \
00866   RTC_LOG(LogStream::RTL_ERROR, fmt, __VA_ARGS__)
00867 #define RTC_WARN(fmt, ...) \
00868   RTC_LOG(LogStream::RTL_WARN, fmt, __VA_ARGS__)
00869 #define RTC_NORMAL(fmt, ...) \
00870   RTC_LOG(LogStream::RTL_NORMAL, fmt, __VA_ARGS__)
00871 #define RTC_INFO(fmt, ...) \
00872   RTC_LOG(LogStream::RTL_INFO, fmt, __VA_ARGS__)
00873 #define RTC_DEBUG(fmt, ...) \
00874   RTC_LOG(LogStream::RTL_DEBUG, fmt, __VA_ARGS__)
00875 #define RTC_TRACE(fmt, ...) \
00876   RTC_LOG(LogStream::RTL_TRACE, fmt, __VA_ARGS__)
00877 #define RTC_VERBOSE(fmt, ...) \
00878   RTC_LOG(LogStream::RTL_VERBOSE, fmt, __VA_ARGS__)
00879 #define RTC_PARANOID(fmt, ...) \
00880   RTC_LOG(LogStream::RTL_PARANOID, fmt, __VA_ARGS__)
00881 #endif
00882   
00883 #ifndef NO_LOGGING
00884   
00898 #define RTC_LOG(LV, fmt) \
00899   rtcout.acquire(); \
00900   rtcout.level(LV) << rtcout.printf fmt << std::endl; \
00901   rtcout.release()
00902   
00918 #define RTC_ERROR(fmt) \
00919   rtcout.acquire(); \
00920   rtcout.level(LogStream::RTL_ERROR)  << rtcout.printf fmt << std::endl; \
00921   rtcout.release()
00922   
00942 #define RTC_WARN(fmt) \
00943   rtcout.acquire(); \
00944   rtcout.level(LogStream::RTL_WARN) << rtcout.printf fmt << std::endl;\
00945   rtcout.release()
00946   
00966 #define RTC_INFO(fmt) \
00967   rtcout.acquire(); \
00968   rtcout.level(LogStream::RTL_INFO) << rtcout.printf fmt << std::endl;\
00969   rtcout.release()
00970   
00990 #define RTC_NORMAL(fmt) \
00991   rtcout.acquire();     \
00992   rtcout.level(LogStream::RTL_NORMAL) << rtcout.printf fmt << std::endl;\
00993   rtcout.release()
00994   
01014 #define RTC_DEBUG(fmt) \
01015   rtcout.acquire(); \
01016   rtcout.level(LogStream::RTL_DEBUG) << rtcout.printf fmt << std::endl; \
01017   rtcout.release()
01018   
01038 #define RTC_TRACE(fmt) \
01039   rtcout.acquire(); \
01040   rtcout.level(LogStream::RTL_TRACE) << rtcout.printf fmt << std::endl; \
01041   rtcout.release()
01042   
01062 #define RTC_VERBOSE(fmt) \
01063   rtcout.acquire(); \
01064   rtcout.level(LogStream::RTL_VERBOSE) << rtcout.printf fmt << std::endl; \
01065   rtcout.release()
01066   
01086 #define RTC_PARANOID(fmt) \
01087   rtcout.acquire(); \
01088   rtcout.level(LogStream::RTL_PARANOID) << rtcout.printf fmt << std::endl; \
01089   rtcout.release()
01090   
01091 #else
01092 #define RTC_ERROR(fmt)
01093 #define RTC_WARN(fmt)
01094 #define RTC_NORMAL(fmt)
01095 #define RTC_INFO(fmt)
01096 #define RTC_DEBUG(fmt)
01097 #define RTC_TRACE(fmt)
01098 #define RTC_VERBOSE(fmt)
01099 #define RTC_PARANOID(fmt)
01100 #endif
01101   
01102 }; // namespace RTC
01103 
01104 #endif  // SystemLogger_h

OpenRTMに対してFri Oct 5 05:14:57 2007に生成されました。  doxygen 1.4.1