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

SystemLogger.h

説明を見る。
00001 // -*- C++ -*-
00019 /*
00020  * $Log: SystemLogger.h,v $
00021  * Revision 1.5  2007/04/26 15:33:44  n-ando
00022  * The header include order was modified to define _REENTRANT before
00023  * including ace/config-lite.h in Linux systems.
00024  * In ace 5.4.7 or later, _REENTRANT flag should be defined explicitly.
00025  *
00026  * Revision 1.4  2007/04/13 16:01:32  n-ando
00027  * Timing of mutex acquisition was changed for buffer synchronization bugs.
00028  *
00029  * Revision 1.3  2007/01/21 10:37:55  n-ando
00030  * Dtor for sync_callback and basic_ummybuf classes was defined.
00031  * A trivial fix;
00032  *
00033  * Revision 1.2  2006/11/04 20:54:09  n-ando
00034  * classes were renamed and soruce code was re-formatted.
00035  *
00036  * Revision 1.1  2006/11/02 15:14:24  n-ando
00037  * RtcSystemLogger.h was moved to SystemLogger.h.
00038  *
00039  * Revision 1.2  2005/05/16 06:40:19  n-ando
00040  * - Dummy macro "__restrict" was defined for Windows port.
00041  * - Some bugs were fixed.
00042  *
00043  * Revision 1.1.1.1  2005/05/12 09:06:18  n-ando
00044  * Public release.
00045  *
00046  *
00047  */
00048 
00049 #ifndef SystemLogger_h
00050 #define SystemLogger_h
00051 
00052 #include <rtm/RTC.h>
00053 
00054 #include <iostream>
00055 #include <fstream>
00056 #include <stdio.h>
00057 #include <stdarg.h>
00058 #include <limits.h>
00059 #include <time.h>
00060 #include <errno.h>
00061 
00062 // ACE
00063 #include <ace/Mutex.h>
00064 
00065 #ifdef RTM_GCC2
00066 #define NO_LOGGING
00067 #endif
00068 
00069 #ifdef WIN32
00070 // It's dummy
00071 #define __restrict
00072 #endif
00073 
00074 namespace RTC
00075 {
00076   
00077 #ifndef NO_LOGGING 
00078   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00079   class sync_callback
00080   {
00081   public:
00082     virtual ~sync_callback(){}
00083     virtual int operator()(const _CharT* s) = 0;
00084   };
00085   
00086   //============================================================
00106   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00107   class basic_logbuf
00108     : public std::basic_filebuf<_CharT, _Traits>
00109   {
00110   public:
00111     // Types:
00112     typedef _CharT                                     char_type;
00113     typedef _Traits                                    traits_type;
00114     typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00115     
00129     basic_logbuf()
00130       : __filebuf_type(), m_pCallBack(NULL)
00131     {;}
00132     
00146     basic_logbuf(const char_type* s,
00147                  std::ios_base::openmode mode = std::ios_base::out, 
00148                  long protection = 0666)
00149       : __filebuf_type(), m_pCallBack(NULL)
00150     {
00151       this->open(s, mode);
00152     }
00153     
00167     virtual ~basic_logbuf()
00168     {
00169       this->sync();
00170       this->close();
00171     };
00172     
00173     virtual std::streamsize sputn(const char_type* s, std::streamsize n)
00174     {
00175       ACE_Guard<ACE_Thread_Mutex> gaurd(m_Mutex);
00176       //          std::string ss(s, n);
00177       //          std::string sss;
00178       //          sss = "HogeDara" + ss;
00179       std::streamsize ssize = this->xsputn(s, n);
00180       /*
00181         if (m_pCallBack != NULL)
00182         {
00183         (*m_pCallBack)(sss.c_str());
00184         }
00185       */
00186       this->sync();
00187       return ssize;
00188     }
00189     
00190     void setSyncCallBack(sync_callback<char_type>& cb)
00191     {
00192       m_pCallBack = &cb;
00193     }
00194     
00195   protected:
00209     virtual int sync()
00210     {
00211       std::string::basic_string<_CharT> s(this->pbase(),
00212                                           this->pptr() - this->pbase());
00213       if (m_pCallBack != NULL)
00214         {
00215           (*m_pCallBack)(s.c_str());
00216         }
00217       
00218       // __filebuf_type::sync() resets the pointer
00219       int ret = __filebuf_type::sync();
00220       
00221       return ret;
00222     }
00223     
00224   private:
00225     ACE_Thread_Mutex m_Mutex;
00226     sync_callback<char_type>* m_pCallBack;
00227     
00228   };
00229   
00230   
00231   
00232   //============================================================
00252   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00253   class EXPORTS basic_medlogbuf
00254     : public std::basic_streambuf<_CharT, _Traits>
00255   {
00256   public:
00257     // Types:
00258     typedef _CharT                                       char_type;
00259     typedef _Traits                                      traits_type;
00260     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00261     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00262     
00277     basic_medlogbuf()
00278       : __streambuf_type(), m_pLogbuf(NULL)
00279     {
00280       // W3C standard date and time format.
00281       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00282     }
00283     
00284     basic_medlogbuf(__filebuf_type& filebuf)
00285       : __streambuf_type(), m_pLogbuf(&filebuf)
00286     {
00287       char *pStart = m_Data;
00288       char *pEnd = m_Data + (LINE_MAX - 1);
00289       this->setp(pStart, pEnd);            // 書き込みポインタ。
00290       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00291       
00292       // W3C standard date and time format.
00293       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00294     }
00295     
00309     virtual ~basic_medlogbuf()
00310     {
00311       this->sync();
00312     }
00313     
00314     void setBuffer(__filebuf_type& filebuf)
00315     {
00316       m_pLogbuf = &filebuf;
00317       char *pStart = m_Data;
00318       char *pEnd = m_Data + (LINE_MAX - 1);
00319       this->setp(pStart, pEnd);            // 書き込みポインタ。
00320       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00321     }
00322     
00360     void setDateFmt(char* fmt)
00361     {
00362       m_DateFmt = std::string(fmt);
00363     }
00364     
00376     void setDateFmt(const std::string& fmt)
00377     {
00378       m_DateFmt = fmt;
00379     }
00380     
00392     std::string getFmtDate()
00393     {
00394       const int maxsize = 256;
00395       char buf[maxsize];
00396       
00397       /*
00398         struct timeval tp;
00399         struct timezone tzp;
00400         gettimeofday(&tp, &tzp);
00401       */
00402       time_t timer;
00403       struct tm* date;
00404       
00405       timer = time(NULL);
00406       date = localtime(&timer);
00407       strftime(buf, maxsize, m_DateFmt.c_str(), date);
00408       
00409       std::string ret(buf);
00410       return ret;
00411     }
00412     
00424     void setSuffix(char* suffix)
00425     {
00426       m_Suffix = std::string(suffix);
00427     }
00428     
00440     void setSuffix(const std::string& suffix)
00441     {
00442       m_Suffix = suffix;
00443     }
00444     
00456     std::string getSuffix()
00457     {
00458       return m_Suffix;
00459     }
00460     
00461     /*
00462       void setCallBack(void (*call_back)(std::string s))
00463       {
00464       
00465       }
00466     */
00467     
00468   protected:
00482     virtual int sync()
00483     {
00484       ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00485       int ret(0); 
00486       if (m_pLogbuf != NULL &&
00487           (this->pptr() - this->pbase()) > 0)
00488         {
00489           {
00490             //ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00491             *(this->pptr()) = '\0';
00492             std::string::basic_string<_CharT> tmp(this->pbase(),
00493                                                   this->pptr() - 
00494                                                   this->pbase());
00495             
00496             std::string s = getFmtDate();
00497             s += ( s.size() > 0 ? " " : "" ) + getSuffix();
00498             s += ( getSuffix().size() > 0 ? " " : "" ) + tmp;
00499             // s += (getSuffix().size() > 0 ? " " : "" ) + getSuffix();
00500             // s += (s.size() > 0 ? " " : "") + tmp;
00501             m_pLogbuf->sputn(s.c_str(), s.size());
00502             m_pLogbuf->pubsync();
00503             // Reset pptr() pointer to pbase()
00504             // __streambuf_type::sync() resets the pointer
00505             ret = __streambuf_type::sync();
00506             pbump( this->pbase() - this->pptr() );
00507           }
00508         }
00509       return ret;
00510     }
00511     
00512   private:
00513     __filebuf_type* m_pLogbuf;
00514     char m_Data[LINE_MAX];
00515     std::string m_DateFmt;
00516     std::string m_Suffix;
00517     ACE_Thread_Mutex m_Mutex;
00518   };
00519   
00520   
00539   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00540   class basic_dummybuf
00541     : public std::basic_streambuf<_CharT, _Traits>
00542   {
00543   public:
00544     // Types:
00545     typedef _CharT                               char_type;
00546     typedef _Traits                              traits_type;
00547     typedef typename traits_type::int_type       int_type;
00548     typedef typename traits_type::pos_type       pos_type;
00549     typedef typename traits_type::off_type       off_type;
00550     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00551     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00552     
00553     basic_dummybuf()
00554     {
00555       char *pStart = m_Data;
00556       char *pEnd = m_Data + (LINE_MAX - 1);
00557       this->setp(pStart, pEnd);
00558       this->setg(pStart, pStart, pEnd);
00559     }
00560 
00561     ~basic_dummybuf()
00562     {
00563     }
00564     
00565     int_type overflow(int_type c = _Traits::eof() )
00566     {
00567       pbump( this->pbase() - this->pptr() );
00568       return _Traits::not_eof(c);
00569     }
00570     
00571     virtual int sync()
00572     {
00573       pbump( this->pbase() - this->pptr() );
00574       return 0;
00575     }
00576     
00577   private:
00578     char m_Data[255];
00579   };
00580   
00581   
00600   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00601   class EXPORTS basic_logstream
00602     : public std::basic_ostream<_CharT, _Traits>
00603   {
00604   public:
00605     // Loglevel
00606     enum
00607       {          // No: Write out messages include the following.
00608         RTL_SILENT,  // 0: ()
00609         RTL_ERROR,   // 1: (ERROR)
00610         RTL_WARN,    // 2: (ERROR, WARN)
00611         RTL_INFO,    // 3: (ERROR, WARN, INFO)
00612         RTL_NORMAL,  // 4: (ERROR, WARN, INFO, NORMAL)
00613         RTL_DEBUG,   // 5: (ERROR, WARN, INFO, NORMAL, DEBUG)
00614         RTL_TRACE,   // 6: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE)
00615         RTL_VERBOSE, // 7: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE)
00616         RTL_PARANOID,// 8: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARA)
00617         RTL_MANDATORY// This level is used for only LogLockLevel
00618       };
00619     
00620     static int strToLogLevel(const std::string& lv)
00621     {
00622       if (lv == "SILENT")
00623         return basic_logstream::RTL_SILENT;
00624       else if (lv == "ERROR")
00625         return basic_logstream::RTL_ERROR;
00626       else if (lv == "WARN")
00627         return basic_logstream::RTL_WARN;
00628       else if (lv == "INFO")
00629         return basic_logstream::RTL_INFO;
00630       else if (lv == "NORNAL")
00631         return basic_logstream::RTL_NORMAL;
00632       else if (lv == "DEBUG")
00633         return basic_logstream::RTL_DEBUG;
00634       else if (lv == "TRACE")
00635         return basic_logstream::RTL_TRACE;
00636       else if (lv == "VERBOSE")
00637         return basic_logstream::RTL_VERBOSE;
00638       else if (lv == "PARANOID")
00639         return basic_logstream::RTL_PARANOID;
00640       else if (lv == "MANDATORY")
00641         return basic_logstream::RTL_MANDATORY;
00642       else
00643         return basic_logstream::RTL_NORMAL;
00644     }
00645     
00646     // Types:
00647     typedef _CharT                                       char_type;
00648     typedef _Traits                                      traits_type;
00649     typedef basic_logbuf<char_type, traits_type>         __logbuf_type;
00650     typedef basic_dummybuf<char_type, traits_type>       __dummybuf_type;
00651     typedef basic_logstream<char_type, traits_type>      __logstream_type;
00652     typedef std::basic_ostream<char_type, traits_type>   __ostream_type;
00653     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00654     
00670     basic_logstream(__streambuf_type& streambuf)
00671       : __ostream_type(&streambuf),
00672         m_DummyStream(new __dummybuf_type()),
00673         m_LogLevel(RTL_NORMAL), m_LogLock(false)
00674     {
00675       this->init(&streambuf);
00676     }
00677     
00691     ~basic_logstream()
00692     {
00693     }
00694     
00706     /*
00707       __logbuf_type*    rdbuf() const
00708       {
00709       return const_cast<__logbuf_type*>(&m_Streambuf);
00710       }
00711     */
00712     
00726     static std::string printf(char const * __restrict fmt, ...)
00727     {
00728       char str[LINE_MAX];
00729       va_list ap;
00730       
00731       va_start(ap, fmt);
00732 #ifdef WIN32
00733       _vsnprintf(str, LINE_MAX - 1, fmt, ap);
00734 #else
00735       vsnprintf(str, LINE_MAX - 1, fmt, ap);
00736 #endif
00737       va_end(ap);
00738       std::string s(str);
00739       
00740       return s;
00741     }
00742     
00743     
00744     void setLogLevel(const std::string& level)
00745     {
00746       m_LogLevel = strToLogLevel(level);
00747     }
00748 
00749     void setLogLevel(int level)
00750     {
00751       m_LogLevel = level;
00752     }
00753     
00754     void setLogLock(bool lock)
00755     {
00756       m_LogLock = lock;
00757     }
00758     
00759     
00760     void enableLogLock()
00761     {
00762       m_LogLock = true;
00763     }
00764     
00765     void disableLogLock()
00766     {
00767       m_LogLock = false;
00768     }
00769     
00770     __ostream_type& level(int level)
00771     {
00772       if (m_LogLevel >= level)
00773         {
00774           return *this;
00775         }
00776       else
00777         {
00778           return m_DummyStream;
00779         }
00780       
00781     }
00782     
00783     inline void acquire()
00784     {
00785       if (m_LogLock) m_Mutex.acquire();
00786     }
00787     
00788     inline void release()
00789     {
00790       if (m_LogLock) m_Mutex.release();
00791     }
00792     
00793     __ostream_type m_DummyStream;
00794     
00795   private:
00796     int m_LogLevel;
00797     bool m_LogLock;
00798     ACE_Thread_Mutex m_Mutex;
00799     
00800   };
00801   typedef sync_callback<char>   SyncCallback;
00802   typedef basic_logbuf<char>    Logbuf;
00803   typedef basic_medlogbuf<char> MedLogbuf;
00804   typedef basic_logstream<char> LogStream;
00805   
00806 #else 
00807   
00808   class SyncCallback
00809   {
00810   public:
00811     SyncCallback() {;};
00812     virtual int operator()(const char* s) {;};
00813   };
00814   
00815   class Logbuf
00816   {
00817   public:
00818     Logbuf() {;};
00819     Logbuf(const char* s, int m) {;};
00820     void open(const char* s, int m) {;};
00821     void setSyncCallBack(SyncCallback& cb) {;};
00822   };
00823   
00824   class MedLogbuf
00825   {
00826   public:
00827     MedLogbuf() {;};
00828     MedLogbuf(Logbuf& f) {;};
00829     void setDateFmt(char* fmt) {;};
00830     void setDateFmt(const std::string& fmt) {;};
00831     void setSuffix(const char* suffix) {;};
00832     void setSuffix(const std::string& suffix) {;};
00833   };
00834   
00835   class LogStream
00836     : public ostream
00837   {
00838   public:
00839     enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
00840     static int strToLogLevel(const std::string& lv){return NORMAL;}
00841     LogStream(MedLogbuf& buf) {;};
00842     void setLogLevel(int level) {;};
00843     void setLogLock(int lock) {;};
00844     LogStream& level(int level) {return *this;};
00845     /*
00846       LogStream& operator<<(const char* s) {return *this;};
00847       LogStream& operator<<(const string s) {return *this;};
00848       LogStream& operator<<(const ostream& o) {return *this;};
00849       LogStream& operator<<(const ostream o) {return *this;};
00850     */
00851   };
00852   
00853 #endif // NO_LOGGING  
00854   
00855   
00856   // __VA_ARGS__ cannot be used in VC   
00857 #if 0
00858 #define RTC_LOG(LV, fmt, ...) \
00859   rtcout.level(LV) << rtcout.printf(fmt, __VA_ARGS__) << std::endl;
00860 #define RTC_ERROR(fmt, ...) \
00861   RTC_LOG(LogStream::RTL_ERROR, fmt, __VA_ARGS__)
00862 #define RTC_WARN(fmt, ...) \
00863   RTC_LOG(LogStream::RTL_WARN, fmt, __VA_ARGS__)
00864 #define RTC_NORMAL(fmt, ...) \
00865   RTC_LOG(LogStream::RTL_NORMAL, fmt, __VA_ARGS__)
00866 #define RTC_INFO(fmt, ...) \
00867   RTC_LOG(LogStream::RTL_INFO, fmt, __VA_ARGS__)
00868 #define RTC_DEBUG(fmt, ...) \
00869   RTC_LOG(LogStream::RTL_DEBUG, fmt, __VA_ARGS__)
00870 #define RTC_TRACE(fmt, ...) \
00871   RTC_LOG(LogStream::RTL_TRACE, fmt, __VA_ARGS__)
00872 #define RTC_VERBOSE(fmt, ...) \
00873   RTC_LOG(LogStream::RTL_VERBOSE, fmt, __VA_ARGS__)
00874 #define RTC_PARANOID(fmt, ...) \
00875   RTC_LOG(LogStream::RTL_PARANOID, fmt, __VA_ARGS__)
00876 #endif
00877   
00878 #ifndef NO_LOGGING
00879   
00893 #define RTC_LOG(LV, fmt) \
00894   rtcout.acquire(); \
00895   rtcout.level(LV) << rtcout.printf fmt << std::endl; \
00896   rtcout.release()
00897   
00913 #define RTC_ERROR(fmt) \
00914   rtcout.acquire(); \
00915   rtcout.level(LogStream::RTL_ERROR)  << rtcout.printf fmt << std::endl; \
00916   rtcout.release()
00917   
00937 #define RTC_WARN(fmt) \
00938   rtcout.acquire(); \
00939   rtcout.level(LogStream::RTL_WARN) << rtcout.printf fmt << std::endl;\
00940   rtcout.release()
00941   
00961 #define RTC_INFO(fmt) \
00962   rtcout.acquire(); \
00963   rtcout.level(LogStream::RTL_INFO) << rtcout.printf fmt << std::endl;\
00964   rtcout.release()
00965   
00985 #define RTC_NORMAL(fmt) \
00986   rtcout.acquire();     \
00987   rtcout.level(LogStream::RTL_NORMAL) << rtcout.printf fmt << std::endl;\
00988   rtcout.release()
00989   
01009 #define RTC_DEBUG(fmt) \
01010   rtcout.acquire(); \
01011   rtcout.level(LogStream::RTL_DEBUG) << rtcout.printf fmt << std::endl; \
01012   rtcout.release()
01013   
01033 #define RTC_TRACE(fmt) \
01034   rtcout.acquire(); \
01035   rtcout.level(LogStream::RTL_TRACE) << rtcout.printf fmt << std::endl; \
01036   rtcout.release()
01037   
01057 #define RTC_VERBOSE(fmt) \
01058   rtcout.acquire(); \
01059   rtcout.level(LogStream::RTL_VERBOSE) << rtcout.printf fmt << std::endl; \
01060   rtcout.release()
01061   
01081 #define RTC_PARANOID(fmt) \
01082   rtcout.acquire(); \
01083   rtcout.level(LogStream::RTL_PARANOID) << rtcout.printf fmt << std::endl; \
01084   rtcout.release()
01085   
01086 #else
01087 #define RTC_ERROR(fmt)
01088 #define RTC_WARN(fmt)
01089 #define RTC_NORMAL(fmt)
01090 #define RTC_INFO(fmt)
01091 #define RTC_DEBUG(fmt)
01092 #define RTC_TRACE(fmt)
01093 #define RTC_VERBOSE(fmt)
01094 #define RTC_PARANOID(fmt)
01095 #endif
01096   
01097 }; // namespace RTC
01098 
01099 #endif  // SystemLogger_h

OpenRTMに対してTue May 29 16:45:15 2007に生成されました。  doxygen 1.4.1