SystemLogger.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00019 #ifndef SystemLogger_h
00020 #define SystemLogger_h
00021 
00022 #include <rtm/RTC.h>
00023 
00024 #include <iostream>
00025 #include <fstream>
00026 #include <stdio.h>
00027 #include <stdarg.h>
00028 #include <limits.h>
00029 #include <time.h>
00030 #include <errno.h>
00031 
00032 // ACE
00033 #include <ace/Mutex.h>
00034 
00035 #include <rtm/config_rtc.h>
00036 
00037 #ifdef RTM_GCC2
00038 #define NO_LOGGING
00039 #endif
00040 
00041 #ifdef WIN32
00042 // It's dummy
00043 #define __restrict
00044 #endif
00045 
00046 namespace RTC
00047 {
00048   
00049 #ifndef NO_LOGGING 
00050 
00066   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00067   class sync_callback
00068   {
00069   public:
00079     virtual ~sync_callback(){}
00080     
00103     virtual int operator()(const _CharT* s) = 0;
00104   };
00105   
00106   //============================================================
00128   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00129   class basic_logbuf
00130     : public std::basic_filebuf<_CharT, _Traits>
00131   {
00132   public:
00133     // Types:
00134     typedef _CharT                                     char_type;
00135     typedef _Traits                                    traits_type;
00136     typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00137     
00153     basic_logbuf()
00154       : __filebuf_type(), m_pCallBack(NULL)
00155     {;}
00156     
00180     basic_logbuf(const char_type* s,
00181                  std::ios_base::openmode mode = std::ios_base::out, 
00182                  long protection = 0666)
00183       : __filebuf_type(), m_pCallBack(NULL)
00184     {
00185       this->open(s, mode);
00186     }
00187     
00203     virtual ~basic_logbuf()
00204     {
00205       this->sync();
00206       this->close();
00207     };
00208     
00235     virtual std::streamsize sputn(const char_type* s, std::streamsize n)
00236     {
00237       ACE_Guard<ACE_Thread_Mutex> gaurd(m_Mutex);
00238       //          std::string ss(s, n);
00239       //          std::string sss;
00240       //          sss = "HogeDara" + ss;
00241       std::streamsize ssize = this->xsputn(s, n);
00242       /*
00243         if (m_pCallBack != NULL)
00244         {
00245         (*m_pCallBack)(sss.c_str());
00246         }
00247       */
00248       this->sync();
00249       return ssize;
00250     }
00251     
00271     void setSyncCallBack(sync_callback<char_type>& cb)
00272     {
00273       m_pCallBack = &cb;
00274     }
00275     
00276   protected:
00296     virtual int sync()
00297     {
00298       std::basic_string<_CharT> s(this->pbase(),
00299                                   this->pptr() - this->pbase());
00300       if (m_pCallBack != NULL)
00301         {
00302           (*m_pCallBack)(s.c_str());
00303         }
00304       // __filebuf_type::sync() resets the pointer
00305       int ret = __filebuf_type::sync();
00306       
00307       return ret;
00308     }
00309     
00310   private:
00311     ACE_Thread_Mutex m_Mutex;
00312     sync_callback<char_type>* m_pCallBack;
00313   };
00314   
00315   //============================================================
00339   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00340   class basic_medlogbuf
00341     : public std::basic_streambuf<_CharT, _Traits>
00342   {
00343   public:
00344     // Types:
00345     typedef _CharT                                       char_type;
00346     typedef _Traits                                      traits_type;
00347     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00348     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00349     
00363     basic_medlogbuf()
00364       : __streambuf_type(), m_pLogbuf(NULL)
00365     {
00366       // W3C standard date and time format.
00367       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00368     }
00369     
00387     basic_medlogbuf(__filebuf_type& filebuf)
00388       : __streambuf_type(), m_pLogbuf(&filebuf)
00389     {
00390       char *pStart = m_Data;
00391       char *pEnd = m_Data + (LINE_MAX - 1);
00392       this->setp(pStart, pEnd);            // 書き込みポインタ。
00393       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00394       
00395       // W3C standard date and time format.
00396       m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00397     }
00398     
00410     basic_medlogbuf(const basic_medlogbuf& x)
00411       : __streambuf_type(), m_pLogbuf(x.m_pLogbuf),
00412         m_DateFmt(x.m_DateFmt), m_Suffix(x.m_Suffix)
00413     {
00414       char *pStart = m_Data;
00415       char *pEnd = m_Data + (LINE_MAX - 1);
00416       this->setp(pStart, pEnd);            // 書き込みポインタ。
00417       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00418     }
00419     
00435     virtual ~basic_medlogbuf()
00436     {
00437       this->sync();
00438     }
00439     
00457     void setBuffer(__filebuf_type& filebuf)
00458     {
00459       m_pLogbuf = &filebuf;
00460       char *pStart = m_Data;
00461       char *pEnd = m_Data + (LINE_MAX - 1);
00462       this->setp(pStart, pEnd);            // 書き込みポインタ。
00463       this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00464     }
00465     
00537     void setDateFmt(char* fmt)
00538     {
00539       m_DateFmt = std::string(fmt);
00540     }
00541     
00562     void setDateFmt(const std::string& fmt)
00563     {
00564       m_DateFmt = fmt;
00565     }
00566     
00586     std::string getFmtDate()
00587     {
00588       const int maxsize = 256;
00589       char buf[maxsize];
00590       /*
00591         struct timeval tp;
00592         struct timezone tzp;
00593         gettimeofday(&tp, &tzp);
00594       */
00595       time_t timer;
00596       struct tm* date;
00597       
00598       timer = time(NULL);
00599       date = localtime(&timer);
00600       strftime(buf, maxsize, m_DateFmt.c_str(), date);
00601       
00602       std::string ret(buf);
00603       return ret;
00604     }
00605     
00625     void setSuffix(char* suffix)
00626     {
00627       m_Suffix = std::string(suffix);
00628     }
00629     
00649     void setSuffix(const std::string& suffix)
00650     {
00651       m_Suffix = suffix;
00652     }
00653     
00673     std::string getSuffix()
00674     {
00675       return m_Suffix;
00676     }
00677     
00678     /*
00679       void setCallBack(void (*call_back)(std::string s))
00680       {
00681       
00682       }
00683     */
00684     
00685   protected:
00705     virtual int sync()
00706     {
00707       ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00708       int ret(0); 
00709       if (m_pLogbuf != NULL && (this->pptr() - this->pbase()) > 0)
00710         {
00711           {
00712             //ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00713             *(this->pptr()) = '\0';
00714             std::basic_string<_CharT> tmp(this->pbase(),
00715                                                   this->pptr() - 
00716                                                   this->pbase());
00717             
00718             std::string s = getFmtDate();
00719             s += ( s.size() > 0 ? " " : "" ) + getSuffix();
00720             s += ( getSuffix().size() > 0 ? " " : "" ) + tmp;
00721             // s += (getSuffix().size() > 0 ? " " : "" ) + getSuffix();
00722             // s += (s.size() > 0 ? " " : "") + tmp;
00723             m_pLogbuf->sputn(s.c_str(), s.size());
00724             m_pLogbuf->pubsync();
00725             // Reset pptr() pointer to pbase()
00726             // __streambuf_type::sync() resets the pointer
00727             ret = __streambuf_type::sync();
00728             pbump( this->pbase() - this->pptr() );
00729           }
00730         }
00731       return ret;
00732     }
00733     
00734   private:
00735     __filebuf_type* m_pLogbuf;
00736     char m_Data[LINE_MAX];
00737     std::string m_DateFmt;
00738     std::string m_Suffix;
00739     ACE_Thread_Mutex m_Mutex;
00740   };
00741   
00761   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00762   class basic_dummybuf
00763     : public std::basic_streambuf<_CharT, _Traits>
00764   {
00765   public:
00766     // Types:
00767     typedef _CharT                               char_type;
00768     typedef _Traits                              traits_type;
00769     typedef typename traits_type::int_type       int_type;
00770     typedef typename traits_type::pos_type       pos_type;
00771     typedef typename traits_type::off_type       off_type;
00772     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00773     typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00774     
00788     basic_dummybuf()
00789     {
00790       char *pStart = m_Data;
00791       char *pEnd = m_Data + (LINE_MAX - 1);
00792       this->setp(pStart, pEnd);
00793       this->setg(pStart, pStart, pEnd);
00794     }
00795     
00811     ~basic_dummybuf()
00812     {
00813     }
00814     
00840     int_type overflow(int_type c = _Traits::eof() )
00841     {
00842       pbump( this->pbase() - this->pptr() );
00843       return _Traits::not_eof(c);
00844     }
00845     
00865     virtual int sync()
00866     {
00867       pbump( this->pbase() - this->pptr() );
00868       return 0;
00869     }
00870     
00871   private:
00872     char m_Data[255];
00873   };
00874   
00894   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00895   class basic_logstream
00896     : public std::basic_ostream<_CharT, _Traits>
00897   {
00898   public:
00899     // Loglevel
00900     enum
00901       {          // No: Write out messages include the following.
00902         RTL_SILENT,  // 0: ()
00903         RTL_ERROR,   // 1: (ERROR)
00904         RTL_WARN,    // 2: (ERROR, WARN)
00905         RTL_INFO,    // 3: (ERROR, WARN, INFO)
00906         RTL_NORMAL,  // 4: (ERROR, WARN, INFO, NORMAL)
00907         RTL_DEBUG,   // 5: (ERROR, WARN, INFO, NORMAL, DEBUG)
00908         RTL_TRACE,   // 6: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE)
00909         RTL_VERBOSE, // 7: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE)
00910         RTL_PARANOID,// 8: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARA)
00911         RTL_MANDATORY// This level is used for only LogLockLevel
00912       };
00913     
00937     static int strToLogLevel(const std::string& lv)
00938     {
00939       if (lv == "SILENT")
00940         return basic_logstream::RTL_SILENT;
00941       else if (lv == "ERROR")
00942         return basic_logstream::RTL_ERROR;
00943       else if (lv == "WARN")
00944         return basic_logstream::RTL_WARN;
00945       else if (lv == "INFO")
00946         return basic_logstream::RTL_INFO;
00947       else if (lv == "NORNAL")
00948         return basic_logstream::RTL_NORMAL;
00949       else if (lv == "DEBUG")
00950         return basic_logstream::RTL_DEBUG;
00951       else if (lv == "TRACE")
00952         return basic_logstream::RTL_TRACE;
00953       else if (lv == "VERBOSE")
00954         return basic_logstream::RTL_VERBOSE;
00955       else if (lv == "PARANOID")
00956         return basic_logstream::RTL_PARANOID;
00957       else if (lv == "MANDATORY")
00958         return basic_logstream::RTL_MANDATORY;
00959       else
00960         return basic_logstream::RTL_NORMAL;
00961     }
00962     
00963     // Types:
00964     typedef _CharT                                       char_type;
00965     typedef _Traits                                      traits_type;
00966     typedef basic_logbuf<char_type, traits_type>         __logbuf_type;
00967     typedef basic_dummybuf<char_type, traits_type>       __dummybuf_type;
00968     typedef basic_logstream<char_type, traits_type>      __logstream_type;
00969     typedef std::basic_ostream<char_type, traits_type>   __ostream_type;
00970     typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00971     
00991     basic_logstream(__streambuf_type& streambuf)
00992       : __ostream_type(&streambuf),
00993         m_DummyStream(new __dummybuf_type()),
00994         m_LogLevel(RTL_NORMAL), m_LogLock(false)
00995     {
00996       this->init(&streambuf);
00997     }
00998     
01014     ~basic_logstream()
01015     {
01016     }
01017     
01018     /***
01019      * @if jp
01020      *
01021      * @brief 現在保持しているバッファへのポインタを返す。
01022      *
01023      * @else
01024      *
01025      * @brief Return a pointer of a current holding buffer.
01026      *
01027      * @endif
01028      */
01029     /*
01030       __logbuf_type*    rdbuf() const
01031       {
01032       return const_cast<__logbuf_type*>(&m_Streambuf);
01033       }
01034     */
01035     
01059     static std::string printf(char const * __restrict fmt, ...)
01060     {
01061       char str[LINE_MAX];
01062       va_list ap;
01063       
01064       va_start(ap, fmt);
01065 #ifdef WIN32
01066       _vsnprintf(str, LINE_MAX - 1, fmt, ap);
01067 #else
01068       vsnprintf(str, LINE_MAX - 1, fmt, ap);
01069 #endif
01070       va_end(ap);
01071       std::string s(str);
01072       
01073       return s;
01074     }
01075     
01095     void setLogLevel(const std::string& level)
01096     {
01097       m_LogLevel = strToLogLevel(level);
01098     }
01099     
01119     void setLogLevel(int level)
01120     {
01121       m_LogLevel = level;
01122     }
01123     
01143     void setLogLock(bool lock)
01144     {
01145       m_LogLock = lock;
01146     }
01147     
01163     void enableLogLock()
01164     {
01165       m_LogLock = true;
01166     }
01167     
01183     void disableLogLock()
01184     {
01185       m_LogLock = false;
01186     }
01187     
01219     __ostream_type& level(int level)
01220     {
01221       if (m_LogLevel >= level)
01222         {
01223           return *this;
01224         }
01225       else
01226         {
01227           return m_DummyStream;
01228         }
01229     }
01230     
01244     inline void acquire()
01245     {
01246       if (m_LogLock) m_Mutex.acquire();
01247     }
01248     
01262     inline void release()
01263     {
01264       if (m_LogLock) m_Mutex.release();
01265     }
01266     
01274     __ostream_type m_DummyStream;
01275     
01276   private:
01277     int m_LogLevel;
01278     bool m_LogLock;
01279     ACE_Thread_Mutex m_Mutex;
01280   };
01281   typedef sync_callback<char>   SyncCallback;
01282   typedef basic_logbuf<char>    Logbuf;
01283   typedef basic_medlogbuf<char> MedLogbuf;
01284   typedef basic_logstream<char> LogStream;
01285   
01286 #else 
01287   
01288 
01304   class SyncCallback
01305   {
01306   public:
01320     SyncCallback() {;};
01321     
01343     virtual int operator()(const char* s) {;};
01344   };
01345   
01365   class Logbuf
01366   {
01367   public:
01383     Logbuf() {;};
01384     
01408     Logbuf(const char* s, int m) {;};
01409     
01433     void open(const char* s, int m) {;};
01434     
01456     void setSyncCallBack(SyncCallback& cb) {;};
01457   };
01458   
01474   class MedLogbuf
01475   {
01476   public:
01490     MedLogbuf() {;};
01491     
01509     MedLogbuf(Logbuf& f) {;};
01510     
01528     void setDateFmt(char* fmt) {;};
01529     
01549     void setDateFmt(const std::string& fmt) {;};
01550     
01572     void setSuffix(const char* suffix) {;};
01573     
01595     void setSuffix(const std::string& suffix) {;};
01596   };
01597   
01617   class LogStream
01618     : public ostream
01619   {
01620   public:
01621     enum
01622       {
01623         SILENT,
01624         ERROR,
01625         WARN,
01626         INFO,
01627         NORMAL,
01628         DEBUG,
01629         TRACE,
01630         VERBOSE,
01631         PARANOID,
01632         MANDATORY
01633       };
01634     
01660     static int strToLogLevel(const std::string& lv){return NORMAL;}
01661     
01683     LogStream(MedLogbuf& buf) {;};
01684     
01706     void setLogLevel(int level) {;};
01707     
01729     void setLogLock(int lock) {;};
01730     
01754     LogStream& level(int level) {return *this;};
01755     /*
01756       LogStream& operator<<(const char* s) {return *this;};
01757       LogStream& operator<<(const string s) {return *this;};
01758       LogStream& operator<<(const ostream& o) {return *this;};
01759       LogStream& operator<<(const ostream o) {return *this;};
01760     */
01761   };
01762   
01763 #endif // NO_LOGGING  
01764   
01765   
01766   // __VA_ARGS__ cannot be used in VC   
01767 #if 0
01768 #define RTC_LOG(LV, fmt, ...)                                           \
01769   rtcout.level(LV) << rtcout.printf(fmt, __VA_ARGS__) << std::endl;
01770 #define RTC_ERROR(fmt, ...)                             \
01771   RTC_LOG(LogStream::RTL_ERROR, fmt, __VA_ARGS__)
01772 #define RTC_WARN(fmt, ...)                              \
01773   RTC_LOG(LogStream::RTL_WARN, fmt, __VA_ARGS__)
01774 #define RTC_NORMAL(fmt, ...)                            \
01775   RTC_LOG(LogStream::RTL_NORMAL, fmt, __VA_ARGS__)
01776 #define RTC_INFO(fmt, ...)                              \
01777   RTC_LOG(LogStream::RTL_INFO, fmt, __VA_ARGS__)
01778 #define RTC_DEBUG(fmt, ...)                             \
01779   RTC_LOG(LogStream::RTL_DEBUG, fmt, __VA_ARGS__)
01780 #define RTC_TRACE(fmt, ...)                             \
01781   RTC_LOG(LogStream::RTL_TRACE, fmt, __VA_ARGS__)
01782 #define RTC_VERBOSE(fmt, ...)                           \
01783   RTC_LOG(LogStream::RTL_VERBOSE, fmt, __VA_ARGS__)
01784 #define RTC_PARANOID(fmt, ...)                          \
01785   RTC_LOG(LogStream::RTL_PARANOID, fmt, __VA_ARGS__)
01786 #endif
01787   
01788 #ifndef NO_LOGGING
01789   
01805 #define RTC_LOG(LV, fmt)                              \
01806   rtcout.acquire();                                   \
01807   rtcout.level(LV) << rtcout.printf fmt << std::endl; \
01808   rtcout.release()
01809   
01829 #define RTC_ERROR(fmt)                                                  \
01830   rtcout.acquire();                                                     \
01831   rtcout.level(LogStream::RTL_ERROR)  << rtcout.printf fmt << std::endl; \
01832   rtcout.release()
01833   
01853 #define RTC_WARN(fmt)                                                   \
01854   rtcout.acquire();                                                     \
01855   rtcout.level(LogStream::RTL_WARN) << rtcout.printf fmt << std::endl;  \
01856   rtcout.release()
01857   
01877 #define RTC_INFO(fmt)                                                   \
01878   rtcout.acquire();                                                     \
01879   rtcout.level(LogStream::RTL_INFO) << rtcout.printf fmt << std::endl;  \
01880   rtcout.release()
01881   
01901 #define RTC_NORMAL(fmt)                                                 \
01902   rtcout.acquire();                                                     \
01903   rtcout.level(LogStream::RTL_NORMAL) << rtcout.printf fmt << std::endl; \
01904   rtcout.release()
01905   
01925 #define RTC_DEBUG(fmt)                                                  \
01926   rtcout.acquire();                                                     \
01927   rtcout.level(LogStream::RTL_DEBUG) << rtcout.printf fmt << std::endl; \
01928   rtcout.release()
01929   
01949 #define RTC_TRACE(fmt)                                                  \
01950   rtcout.acquire();                                                     \
01951   rtcout.level(LogStream::RTL_TRACE) << rtcout.printf fmt << std::endl; \
01952   rtcout.release()
01953   
01973 #define RTC_VERBOSE(fmt)                                                \
01974   rtcout.acquire();                                                     \
01975   rtcout.level(LogStream::RTL_VERBOSE) << rtcout.printf fmt << std::endl; \
01976   rtcout.release()
01977   
01997 #define RTC_PARANOID(fmt)                                               \
01998   rtcout.acquire();                                                     \
01999   rtcout.level(LogStream::RTL_PARANOID) << rtcout.printf fmt << std::endl; \
02000   rtcout.release()
02001   
02002 #else
02003 #define RTC_ERROR(fmt)
02004 #define RTC_WARN(fmt)
02005 #define RTC_NORMAL(fmt)
02006 #define RTC_INFO(fmt)
02007 #define RTC_DEBUG(fmt)
02008 #define RTC_TRACE(fmt)
02009 #define RTC_VERBOSE(fmt)
02010 #define RTC_PARANOID(fmt)
02011 #endif
02012   
02013 }; // namespace RTC
02014 
02015 #endif  // SystemLogger_h

Generated on Thu May 29 15:03:33 2008 for OpenRTM by  doxygen 1.5.3