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

SystemLogger.h

説明を見る。
00001 // -*- C++ -*-
00019 /*
00020  * $Log: SystemLogger.h,v $
00021  * Revision 1.2  2006/11/04 20:54:09  n-ando
00022  * classes were renamed and soruce code was re-formatted.
00023  *
00024  * Revision 1.1  2006/11/02 15:14:24  n-ando
00025  * RtcSystemLogger.h was moved to SystemLogger.h.
00026  *
00027  * Revision 1.2  2005/05/16 06:40:19  n-ando
00028  * - Dummy macro "__restrict" was defined for Windows port.
00029  * - Some bugs were fixed.
00030  *
00031  * Revision 1.1.1.1  2005/05/12 09:06:18  n-ando
00032  * Public release.
00033  *
00034  *
00035  */
00036 
00037 #ifndef SystemLogger_h
00038 #define SystemLogger_h
00039 
00040 #include <iostream>
00041 #include <fstream>
00042 #include <stdio.h>
00043 #include <stdarg.h>
00044 #include <limits.h>
00045 #include <time.h>
00046 #include <errno.h>
00047 
00048 // ACE
00049 #include <ace/Mutex.h>
00050 
00051 #include "rtm/config_rtc.h"
00052 
00053 #ifdef RTM_GCC2
00054 #define NO_LOGGING
00055 #endif
00056 
00057 #ifdef WIN32
00058 // It's dummy
00059 #define __restrict
00060 #endif
00061 
00062 namespace RTC
00063 {
00064   
00065 #ifndef NO_LOGGING 
00066   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00067   class EXPORTS sync_callback
00068   {
00069   public:
00070     virtual int operator()(const _CharT* s) = 0;
00071   };
00072   
00092   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00093   class EXPORTS basic_logbuf
00094     : public std::basic_filebuf<_CharT, _Traits>
00095   {
00096   public:
00097     // Types:
00098     typedef _CharT                                     char_type;
00099     typedef _Traits                                    traits_type;
00100     typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00101     
00115     basic_logbuf()
00116       : __filebuf_type(), m_pCallBack(NULL)
00117     {;}
00118     
00132     basic_logbuf(const char_type* s,
00133                  std::ios_base::openmode mode = std::ios_base::out, 
00134                  long protection = 0666)
00135       : __filebuf_type(), m_pCallBack(NULL)
00136     {
00137       this->open(s, mode);
00138     }
00139     
00153     virtual ~basic_logbuf()
00154     {
00155       this->sync();
00156       this->close();
00157     };
00158     
00159     virtual std::streamsize sputn(const char_type* s, std::streamsize n)
00160     {
00161       ACE_Guard<ACE_Thread_Mutex> gaurd(m_Mutex);
00162       //          std::string ss(s, n);
00163       //          std::string sss;
00164       //          sss = "HogeDara" + ss;
00165       std::streamsize ssize = this->xsputn(s, n);
00166       /*
00167         if (m_pCallBack != NULL)
00168         {
00169         (*m_pCallBack)(sss.c_str());
00170         }
00171       */
00172       this->sync();
00173       return ssize;
00174     }
00175     
00176     void setSyncCallBack(sync_callback<char_type>& cb)
00177     {
00178       m_pCallBack = &cb;
00179     }
00180     
00181   protected:
00195     virtual int sync()
00196     {
00197       std::string::basic_string<_CharT> s(this->pbase(),
00198                                           this->pptr() - this->pbase());
00199       if (m_pCallBack != NULL)
00200         {
00201           (*m_pCallBack)(s.c_str());
00202         }
00203       
00204       // __filebuf_type::sync() resets the pointer
00205       int ret = __filebuf_type::sync();
00206       
00207       return ret;
00208     }
00209     
00210   private:
00211     ACE_Thread_Mutex m_Mutex;
00212     sync_callback<char_type>* m_pCallBack;
00213     
00214   };
00215   
00216   
00217   
00237   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00238   class EXPORTS basic_medlogbuf
00239     : public std::basic_streambuf<_CharT, _Traits>
00240   {
00241   public:
00242     // Types:
00243     typedef _CharT                                       char_type;
00244     typedef _Traits                                      traits_type;
00245     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00246     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00247     
00262     basic_medlogbuf()
00263       : __streambuf_type(), m_pLogbuf(NULL)
00264     {
00265       // W3C standard date and time format.
00266       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00267     }
00268     
00269     basic_medlogbuf(__filebuf_type& filebuf)
00270       : __streambuf_type(), m_pLogbuf(&filebuf)
00271     {
00272       char *pStart = m_Data;
00273       char *pEnd = m_Data + (LINE_MAX - 1);
00274       this->setp(pStart, pEnd);            // 書き込みポインタ。
00275       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00276       
00277       // W3C standard date and time format.
00278       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00279     }
00280     
00294     virtual ~basic_medlogbuf()
00295     {
00296       this->sync();
00297     }
00298     
00299     void setBuffer(__filebuf_type& filebuf)
00300     {
00301       m_pLogbuf = &filebuf;
00302       char *pStart = m_Data;
00303       char *pEnd = m_Data + (LINE_MAX - 1);
00304       this->setp(pStart, pEnd);            // 書き込みポインタ。
00305       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00306     }
00307     
00345     void setDateFmt(char* fmt)
00346     {
00347       m_DateFmt = std::string(fmt);
00348     }
00349     
00361     void setDateFmt(const std::string& fmt)
00362     {
00363       m_DateFmt = fmt;
00364     }
00365     
00377     std::string getFmtDate()
00378     {
00379       const int maxsize(256);
00380       char buf[maxsize];
00381       
00382       /*
00383         struct timeval tp;
00384         struct timezone tzp;
00385         gettimeofday(&tp, &tzp);
00386       */
00387       time_t timer;
00388       struct tm* date;
00389       
00390       timer = time(NULL);
00391       date = localtime(&timer);
00392       strftime(buf, maxsize, m_DateFmt.c_str(), date);
00393       
00394       std::string ret(buf);
00395       return ret;
00396     }
00397     
00409     void setSuffix(char* suffix)
00410     {
00411       m_Suffix = std::string(suffix);
00412     }
00413     
00425     void setSuffix(const std::string& suffix)
00426     {
00427       m_Suffix = suffix;
00428     }
00429     
00441     std::string getSuffix()
00442     {
00443       return m_Suffix;
00444     }
00445     
00446     /*
00447       void setCallBack(void (*call_back)(std::string s))
00448       {
00449       
00450       }
00451     */
00452     
00453   protected:
00467     virtual int sync()
00468     {
00469       int ret(0); 
00470       if (m_pLogbuf != NULL &&
00471           (this->pptr() - this->pbase()) > 0)
00472         {
00473           {
00474             ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00475             *(this->pptr()) = '\0';
00476             std::string::basic_string<_CharT> tmp(this->pbase(),
00477                                                   this->pptr() - 
00478                                                   this->pbase());
00479             
00480             std::string s = getFmtDate();
00481             s += ( s.size() > 0 ? " " : "" ) + getSuffix();
00482             s += ( getSuffix().size() > 0 ? " " : "" ) + tmp;
00483             // s += (getSuffix().size() > 0 ? " " : "" ) + getSuffix();
00484             // s += (s.size() > 0 ? " " : "") + tmp;
00485             m_pLogbuf->sputn(s.c_str(), s.size());
00486             m_pLogbuf->pubsync();
00487             // Reset pptr() pointer to pbase()
00488             // __streambuf_type::sync() resets the pointer
00489             ret = __streambuf_type::sync();
00490             pbump( this->pbase() - this->pptr() );
00491           }
00492         }
00493       return ret;
00494     }
00495     
00496   private:
00497     __filebuf_type* m_pLogbuf;
00498     char m_Data[LINE_MAX];
00499     std::string m_DateFmt;
00500     std::string m_Suffix;
00501     ACE_Thread_Mutex m_Mutex;
00502   };
00503   
00504   
00523   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00524   class EXPORTS basic_dummybuf
00525     : public std::basic_streambuf<_CharT, _Traits>
00526   {
00527   public:
00528     // Types:
00529     typedef _CharT                               char_type;
00530     typedef _Traits                              traits_type;
00531     typedef typename traits_type::int_type       int_type;
00532     typedef typename traits_type::pos_type       pos_type;
00533     typedef typename traits_type::off_type       off_type;
00534     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00535     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00536     
00537     basic_dummybuf()
00538     {
00539       char *pStart = m_Data;
00540       char *pEnd = m_Data + (LINE_MAX - 1);
00541       this->setp(pStart, pEnd);
00542       this->setg(pStart, pStart, pEnd);
00543     }
00544     
00545     
00546     int_type overflow(int_type c = _Traits::eof() )
00547     {
00548       pbump( this->pbase() - this->pptr() );
00549       return _Traits::not_eof(c);
00550     }
00551     
00552     virtual int sync()
00553     {
00554       pbump( this->pbase() - this->pptr() );
00555       return 0;
00556     }
00557     
00558   private:
00559     char m_Data[255];
00560   };
00561   
00562   
00581   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00582   class EXPORTS basic_logstream
00583     : public std::basic_ostream<_CharT, _Traits>
00584   {
00585   public:
00586     // Loglevel
00587     enum
00588       {          // No: Write out messages include the following.
00589         RTL_SILENT,  // 0: ()
00590         RTL_ERROR,   // 1: (ERROR)
00591         RTL_WARN,    // 2: (ERROR, WARN)
00592         RTL_INFO,    // 3: (ERROR, WARN, INFO)
00593         RTL_NORMAL,  // 4: (ERROR, WARN, INFO, NORMAL)
00594         RTL_DEBUG,   // 5: (ERROR, WARN, INFO, NORMAL, DEBUG)
00595         RTL_TRACE,   // 6: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE)
00596         RTL_VERBOSE, // 7: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE)
00597         RTL_PARANOID,// 8: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARA)
00598         RTL_MANDATORY// This level is used for only LogLockLevel
00599       };
00600     
00601     static int strToLogLevel(const std::string& lv)
00602     {
00603       if (lv == "SILENT")
00604         return basic_logstream::RTL_SILENT;
00605       else if (lv == "ERROR")
00606         return basic_logstream::RTL_ERROR;
00607       else if (lv == "WARN")
00608         return basic_logstream::RTL_WARN;
00609       else if (lv == "INFO")
00610         return basic_logstream::RTL_INFO;
00611       else if (lv == "NORNAL")
00612         return basic_logstream::RTL_NORMAL;
00613       else if (lv == "DEBUG")
00614         return basic_logstream::RTL_DEBUG;
00615       else if (lv == "TRACE")
00616         return basic_logstream::RTL_TRACE;
00617       else if (lv == "VERBOSE")
00618         return basic_logstream::RTL_VERBOSE;
00619       else if (lv == "PARANOID")
00620         return basic_logstream::RTL_PARANOID;
00621       else if (lv == "MANDATORY")
00622         return basic_logstream::RTL_MANDATORY;
00623       else
00624         return basic_logstream::RTL_NORMAL;
00625     }
00626     
00627     // Types:
00628     typedef _CharT                                       char_type;
00629     typedef _Traits                                      traits_type;
00630     typedef basic_logbuf<char_type, traits_type>         __logbuf_type;
00631     typedef basic_dummybuf<char_type, traits_type>       __dummybuf_type;
00632     typedef basic_logstream<char_type, traits_type>      __logstream_type;
00633     typedef std::basic_ostream<char_type, traits_type>   __ostream_type;
00634     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00635     
00651     basic_logstream(__streambuf_type& streambuf)
00652       : __ostream_type(&streambuf),
00653         m_DummyStream(new __dummybuf_type()),
00654         m_LogLevel(RTL_NORMAL), m_LogLock(false)
00655     {
00656       this->init(&streambuf);
00657     }
00658     
00672     ~basic_logstream()
00673     {
00674     }
00675     
00687     /*
00688       __logbuf_type*    rdbuf() const
00689       {
00690       return const_cast<__logbuf_type*>(&m_Streambuf);
00691       }
00692     */
00693     
00707     static std::string printf(char const * __restrict fmt, ...)
00708     {
00709       char str[LINE_MAX];
00710       va_list ap;
00711       
00712       va_start(ap, fmt);
00713 #ifdef WIN32
00714       _vsnprintf(str, LINE_MAX - 1, fmt, ap);
00715 #else
00716       vsnprintf(str, LINE_MAX - 1, fmt, ap);
00717 #endif
00718       va_end(ap);
00719       std::string s(str);
00720       
00721       return s;
00722     }
00723     
00724     
00725     void setLogLevel(const std::string& level)
00726     {
00727       m_LogLevel = strToLogLevel(level);
00728     }
00729 
00730     void setLogLevel(int level)
00731     {
00732       m_LogLevel = level;
00733     }
00734     
00735     void setLogLock(bool lock)
00736     {
00737       m_LogLock = lock;
00738     }
00739     
00740     
00741     void enableLogLock()
00742     {
00743       m_LogLock = true;
00744     }
00745     
00746     void disableLogLock()
00747     {
00748       m_LogLock = false;
00749     }
00750     
00751     __ostream_type& level(int level)
00752     {
00753       if (m_LogLevel >= level)
00754         {
00755           return *this;
00756         }
00757       else
00758         {
00759           return m_DummyStream;
00760         }
00761       
00762     }
00763     
00764     inline void acquire()
00765     {
00766       if (m_LogLock) m_Mutex.acquire();
00767     }
00768     
00769     inline void release()
00770     {
00771       if (m_LogLock) m_Mutex.release();
00772     }
00773     
00774     __ostream_type m_DummyStream;
00775     
00776   private:
00777     int m_LogLevel;
00778     bool m_LogLock;
00779     ACE_Thread_Mutex m_Mutex;
00780     
00781   };
00782   typedef sync_callback<char>   SyncCallback;
00783   typedef basic_logbuf<char>    Logbuf;
00784   typedef basic_medlogbuf<char> MedLogbuf;
00785   typedef basic_logstream<char> LogStream;
00786   
00787 #else 
00788   
00789   class EXPORTS SyncCallback
00790   {
00791   public:
00792     SyncCallback() {;};
00793     virtual int operator()(const char* s) {;};
00794   };
00795   
00796   class EXPORTS Logbuf
00797   {
00798   public:
00799     Logbuf() {;};
00800     Logbuf(const char* s, int m) {;};
00801     void open(const char* s, int m) {;};
00802     void setSyncCallBack(SyncCallback& cb) {;};
00803   };
00804   
00805   class EXPORTS MedLogbuf
00806   {
00807   public:
00808     MedLogbuf() {;};
00809     MedLogbuf(Logbuf& f) {;};
00810     void setDateFmt(char* fmt) {;};
00811     void setDateFmt(const std::string& fmt) {;};
00812     void setSuffix(const char* suffix) {;};
00813     void setSuffix(const std::string& suffix) {;};
00814   };
00815   
00816   class EXPORTS LogStream
00817     : public ostream
00818   {
00819   public:
00820     enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
00821     static int strToLogLevel(const std::string& lv){return NORMAL;}
00822     LogStream(MedLogbuf& buf) {;};
00823     void setLogLevel(int level) {;};
00824     void setLogLock(int lock) {;};
00825     LogStream& level(int level) {return *this;};
00826     /*
00827       LogStream& operator<<(const char* s) {return *this;};
00828       LogStream& operator<<(const string s) {return *this;};
00829       LogStream& operator<<(const ostream& o) {return *this;};
00830       LogStream& operator<<(const ostream o) {return *this;};
00831     */
00832   };
00833   
00834 #endif // NO_LOGGING  
00835   
00836   
00837   // __VA_ARGS__ cannot be used in VC   
00838 #if 0
00839 #define RTC_LOG(LV, fmt, ...) \
00840   rtcout.level(LV) << rtcout.printf(fmt, __VA_ARGS__) << std::endl;
00841 #define RTC_ERROR(fmt, ...) \
00842   RTC_LOG(LogStream::RTL_ERROR, fmt, __VA_ARGS__)
00843 #define RTC_WARN(fmt, ...) \
00844   RTC_LOG(LogStream::RTL_WARN, fmt, __VA_ARGS__)
00845 #define RTC_NORMAL(fmt, ...) \
00846   RTC_LOG(LogStream::RTL_NORMAL, fmt, __VA_ARGS__)
00847 #define RTC_INFO(fmt, ...) \
00848   RTC_LOG(LogStream::RTL_INFO, fmt, __VA_ARGS__)
00849 #define RTC_DEBUG(fmt, ...) \
00850   RTC_LOG(LogStream::RTL_DEBUG, fmt, __VA_ARGS__)
00851 #define RTC_TRACE(fmt, ...) \
00852   RTC_LOG(LogStream::RTL_TRACE, fmt, __VA_ARGS__)
00853 #define RTC_VERBOSE(fmt, ...) \
00854   RTC_LOG(LogStream::RTL_VERBOSE, fmt, __VA_ARGS__)
00855 #define RTC_PARANOID(fmt, ...) \
00856   RTC_LOG(LogStream::RTL_PARANOID, fmt, __VA_ARGS__)
00857 #endif
00858   
00859 #ifndef NO_LOGGING
00860   
00874 #define RTC_LOG(LV, fmt) \
00875   rtcout.acquire(); \
00876   rtcout.level(LV) << rtcout.printf fmt << std::endl; \
00877   rtcout.release()
00878   
00894 #define RTC_ERROR(fmt) \
00895   rtcout.acquire(); \
00896   rtcout.level(LogStream::RTL_ERROR)  << rtcout.printf fmt << std::endl; \
00897   rtcout.release()
00898   
00918 #define RTC_WARN(fmt) \
00919   rtcout.acquire(); \
00920   rtcout.level(LogStream::RTL_WARN) << rtcout.printf fmt << std::endl;\
00921   rtcout.release()
00922   
00942 #define RTC_INFO(fmt) \
00943   rtcout.acquire(); \
00944   rtcout.level(LogStream::RTL_INFO) << rtcout.printf fmt << std::endl;\
00945   rtcout.release()
00946   
00966 #define RTC_NORMAL(fmt) \
00967   rtcout.acquire();     \
00968   rtcout.level(LogStream::RTL_NORMAL) << rtcout.printf fmt << std::endl;\
00969   rtcout.release()
00970   
00990 #define RTC_DEBUG(fmt) \
00991   rtcout.acquire(); \
00992   rtcout.level(LogStream::RTL_DEBUG) << rtcout.printf fmt << std::endl; \
00993   rtcout.release()
00994   
01014 #define RTC_TRACE(fmt) \
01015   rtcout.acquire(); \
01016   rtcout.level(LogStream::RTL_TRACE) << rtcout.printf fmt << std::endl; \
01017   rtcout.release()
01018   
01038 #define RTC_VERBOSE(fmt) \
01039   rtcout.acquire(); \
01040   rtcout.level(LogStream::RTL_VERBOSE) << rtcout.printf fmt << std::endl; \
01041   rtcout.release()
01042   
01062 #define RTC_PARANOID(fmt) \
01063   rtcout.acquire(); \
01064   rtcout.level(LogStream::RTL_PARANOID) << rtcout.printf fmt << std::endl; \
01065   rtcout.release()
01066   
01067 #else
01068 #define RTC_ERROR(fmt)
01069 #define RTC_WARN(fmt)
01070 #define RTC_NORMAL(fmt)
01071 #define RTC_INFO(fmt)
01072 #define RTC_DEBUG(fmt)
01073 #define RTC_TRACE(fmt)
01074 #define RTC_VERBOSE(fmt)
01075 #define RTC_PARANOID(fmt)
01076 #endif
01077   
01078 }; // namespace RTC
01079 
01080 #endif  // SystemLogger_h

OpenRTMに対してMon Jan 15 12:14:45 2007に生成されました。  doxygen 1.4.1