Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

RtcSystemLogger.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00019 /*
00020  * $Log: RtcSystemLogger.h,v $
00021  * Revision 1.2  2005/05/16 06:40:19  n-ando
00022  * - Dummy macro "__restrict" was defined for Windows port.
00023  * - Some bugs were fixed.
00024  *
00025  * Revision 1.1.1.1  2005/05/12 09:06:18  n-ando
00026  * Public release.
00027  *
00028  *
00029  */
00030 
00031 #ifndef RtcSystemLogger_h
00032 #define RtcSystemLogger_h
00033 
00034 #include <iostream>
00035 #include <fstream>
00036 #include <stdio.h>
00037 #include <stdarg.h>
00038 #include <limits.h>
00039 #include <time.h>
00040 #include <errno.h>
00041 
00042 // ACE
00043 #include <ace/Mutex.h>
00044 
00045 #include "rtm/config_rtc.h"
00046 
00047 #ifdef RTM_GCC2
00048 #define NO_LOGGING
00049 #endif
00050 
00051 #ifdef WIN32
00052 // It's dummy
00053 #define __restrict
00054 #endif
00055 
00056 namespace RTM
00057 {
00058 
00059 #ifndef NO_LOGGING 
00060   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00061   class EXPORTS sync_callback
00062   {
00063   public:
00064         virtual int operator()(const _CharT* s) = 0;
00065   };
00066 
00086   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00087   class EXPORTS basic_logbuf
00088         : public std::basic_filebuf<_CharT, _Traits>
00089   {
00090   public:
00091         // Types:
00092         typedef _CharT                                     char_type;
00093         typedef _Traits                                    traits_type;
00094         typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00095 
00109         basic_logbuf()
00110           : __filebuf_type(), m_pCallBack(NULL)
00111         {;}
00112 
00126         basic_logbuf(const char_type* s,
00127                                  std::ios_base::openmode mode = std::ios_base::out, 
00128                                  long protection = 0666)
00129           : __filebuf_type(), m_pCallBack(NULL)
00130         {
00131           this->open(s, mode);
00132         }
00133 
00147         virtual ~basic_logbuf()
00148         {
00149           this->sync();
00150           this->close();
00151         };
00152 
00153         virtual streamsize sputn(const char_type* s, streamsize n)
00154         {
00155           ACE_Guard<ACE_Thread_Mutex> gaurd(m_Mutex);
00156           //      std::string ss(s, n);
00157           //      std::string sss;
00158           //      sss = "HogeDara" + ss;
00159           streamsize ssize = this->xsputn(s, n);
00160           /*
00161           if (m_pCallBack != NULL)
00162                 {
00163                   (*m_pCallBack)(sss.c_str());
00164                 }
00165           */
00166           this->sync();
00167           return ssize;
00168         }
00169 
00170         void setSyncCallBack(sync_callback<char_type>& cb)
00171         {
00172           m_pCallBack = &cb;
00173         }
00174 
00175   protected:
00189         virtual int sync()
00190         {
00191           std::string::basic_string<_CharT> s(this->pbase(),
00192                                                                                   this->pptr() - this->pbase());
00193           if (m_pCallBack != NULL)
00194                 {
00195                   (*m_pCallBack)(s.c_str());
00196                 }
00197 
00198           // __filebuf_type::sync() resets the pointer
00199           int ret = __filebuf_type::sync();
00200 
00201           return ret;
00202         }
00203 
00204   private:
00205         ACE_Thread_Mutex m_Mutex;
00206         sync_callback<char_type>* m_pCallBack;
00207         
00208   };
00209 
00210 
00211 
00231   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00232   class EXPORTS basic_medlogbuf
00233         : public std::basic_streambuf<_CharT, _Traits>
00234   {
00235   public:
00236         // Types:
00237         typedef _CharT                                       char_type;
00238         typedef _Traits                                      traits_type;
00239         typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00240         typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00241 
00256         basic_medlogbuf()
00257           : __streambuf_type(), m_pLogbuf(NULL)
00258         {
00259           // W3C standard date and time format.
00260           m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00261         }
00262 
00263         basic_medlogbuf(__filebuf_type& filebuf)
00264           : __streambuf_type(), m_pLogbuf(&filebuf)
00265         {
00266           char *pStart = m_Data;
00267           char *pEnd = m_Data + (LINE_MAX - 1);
00268           this->setp(pStart, pEnd);            // 書き込みポインタ。
00269           this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00270 
00271           // W3C standard date and time format.
00272           m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00273         }
00274 
00288         virtual ~basic_medlogbuf()
00289         {
00290           this->sync();
00291         }
00292 
00293         void setBuffer(__filebuf_type& filebuf)
00294         {
00295           m_pLogbuf = &filebuf;
00296           char *pStart = m_Data;
00297           char *pEnd = m_Data + (LINE_MAX - 1);
00298           this->setp(pStart, pEnd);            // 書き込みポインタ。
00299           this->setg(pStart, pStart, pEnd);    // 読み取りポインタ。
00300         }
00301         
00339         void setDateFmt(char* fmt)
00340         {
00341           m_DateFmt = std::string(fmt);
00342         }
00343 
00355         void setDateFmt(std::string fmt)
00356         {
00357           m_DateFmt = fmt;
00358         }
00359 
00371         std::string getFmtDate()
00372         {
00373           const int maxsize(256);
00374           char buf[maxsize];
00375      
00376           /*
00377           struct timeval tp;
00378           struct timezone tzp;
00379           gettimeofday(&tp, &tzp);
00380           */
00381           time_t timer;
00382           struct tm* date;
00383 
00384           timer = time(NULL);
00385           date = localtime(&timer);
00386           strftime(buf, maxsize, m_DateFmt.c_str(), date);
00387 
00388           std::string ret(buf);
00389           return ret;
00390         }
00391 
00403         void setSuffix(char* suffix)
00404         {
00405           m_Suffix = std::string(suffix);
00406         }
00407 
00419         void setSuffix(std::string suffix)
00420         {
00421           m_Suffix = suffix;
00422         }
00423 
00435         std::string getSuffix()
00436         {
00437           return m_Suffix;
00438         }
00439 
00440         /*
00441         void setCallBack(void (*call_back)(std::string s))
00442         {
00443           
00444         }
00445         */
00446 
00447   protected:
00461         virtual int sync()
00462         {
00463           int ret(0); 
00464           if (m_pLogbuf != NULL &&
00465                   (this->pptr() - this->pbase()) > 0)
00466                 {
00467                   {
00468                         ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00469                         *(this->pptr()) = '\0';
00470                         std::string::basic_string<_CharT> tmp(this->pbase(),
00471                                                                                                   this->pptr() - this->pbase());
00472                         
00473                         std::string s = getFmtDate();
00474                         s += ( s.size() > 0 ? " " : "" ) + getSuffix();
00475                         s += ( getSuffix().size() > 0 ? " " : "" ) + tmp;
00476                   //                    s += (getSuffix().size() > 0 ? " " : "" ) + getSuffix();
00477                   //                    s += (s.size() > 0 ? " " : "") + tmp;
00478                         m_pLogbuf->sputn(s.c_str(), s.size());
00479                         m_pLogbuf->pubsync();
00480                         // Reset pptr() pointer to pbase()
00481                         // __streambuf_type::sync() resets the pointer
00482                         ret = __streambuf_type::sync();
00483                         pbump( this->pbase() - this->pptr() );
00484                   }
00485                 }
00486           return ret;
00487         }
00488 
00489   private:
00490         __filebuf_type* m_pLogbuf;
00491         char m_Data[LINE_MAX];
00492         std::string m_DateFmt;
00493         std::string m_Suffix;
00494         ACE_Thread_Mutex m_Mutex;
00495   };
00496 
00497 
00516   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00517   class EXPORTS basic_dummybuf
00518         : public std::basic_streambuf<_CharT, _Traits>
00519   {
00520   public:
00521         // Types:
00522         typedef _CharT                               char_type;
00523         typedef _Traits                              traits_type;
00524         typedef typename traits_type::int_type       int_type;
00525         typedef typename traits_type::pos_type       pos_type;
00526         typedef typename traits_type::off_type       off_type;
00527         typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00528         typedef std::basic_filebuf<char_type, traits_type>   __filebuf_type;
00529         
00530         basic_dummybuf()
00531         {
00532           char *pStart = m_Data;
00533           char *pEnd = m_Data + (LINE_MAX - 1);
00534           this->setp(pStart, pEnd);
00535           this->setg(pStart, pStart, pEnd);
00536         }
00537 
00538         
00539         int_type overflow(int_type c = _Traits::eof() )
00540         {
00541           pbump( this->pbase() - this->pptr() );
00542           return _Traits::not_eof(c);
00543         }
00544         
00545         virtual int sync()
00546         {
00547           pbump( this->pbase() - this->pptr() );
00548           return 0;
00549         }
00550         
00551   private:
00552         char m_Data[255];
00553   };
00554 
00555 
00574   template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00575   class EXPORTS basic_logstream
00576         : public std::basic_ostream<_CharT, _Traits>
00577   {
00578   public:
00579         // Loglevel
00580         enum
00581           {          // No: Write out messages include the following.
00582                 RTL_SILENT,  // 0: ()
00583                 RTL_ERROR,   // 1: (ERROR)
00584                 RTL_WARN,    // 2: (ERROR, WARN)
00585                 RTL_INFO,    // 3: (ERROR, WARN, INFO)
00586                 RTL_NORMAL,  // 4: (ERROR, WARN, INFO, NORMAL)
00587                 RTL_DEBUG,   // 5: (ERROR, WARN, INFO, NORMAL, DEBUG)
00588                 RTL_TRACE,   // 6: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE)
00589                 RTL_VERBOSE, // 7: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE)
00590                 RTL_PARANOID,// 8: (ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARA)
00591                 RTL_MANDATORY// This level is used for only LogLockLevel
00592           };
00593 
00594         static int strToLogLevel(std::string lv)
00595         {
00596           if (lv == "SILENT")
00597                 return basic_logstream::RTL_SILENT;
00598           else if (lv == "ERROR")
00599                   return basic_logstream::RTL_ERROR;
00600           else if (lv == "WARN")
00601                   return basic_logstream::RTL_WARN;
00602           else if (lv == "INFO")
00603                   return basic_logstream::RTL_INFO;
00604           else if (lv == "NORNAL")
00605                   return basic_logstream::RTL_NORMAL;
00606           else if (lv == "DEBUG")
00607                   return basic_logstream::RTL_DEBUG;
00608           else if (lv == "TRACE")
00609                   return basic_logstream::RTL_TRACE;
00610           else if (lv == "VERBOSE")
00611                   return basic_logstream::RTL_VERBOSE;
00612           else if (lv == "PARANOID")
00613                   return basic_logstream::RTL_PARANOID;
00614           else if (lv == "MANDATORY")
00615                   return basic_logstream::RTL_MANDATORY;
00616           else
00617                 return basic_logstream::RTL_NORMAL;
00618         }
00619         
00620         // Types:
00621         typedef _CharT                                       char_type;
00622         typedef _Traits                                      traits_type;
00623         typedef basic_logbuf<char_type, traits_type>         __logbuf_type;
00624         typedef basic_dummybuf<char_type, traits_type>       __dummybuf_type;
00625         typedef basic_logstream<char_type, traits_type>      __logstream_type;
00626         typedef std::basic_ostream<char_type, traits_type>   __ostream_type;
00627         typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00628 
00644         basic_logstream(__streambuf_type& streambuf)
00645           : __ostream_type(&streambuf),
00646                 m_DummyStream(new __dummybuf_type()),
00647                 m_LogLevel(RTL_NORMAL), m_LogLock(false)
00648         {
00649           this->init(&streambuf);
00650         }
00651 
00665         ~basic_logstream()
00666         {
00667         }
00668         
00680         /*
00681         __logbuf_type*  rdbuf() const
00682         {
00683           return const_cast<__logbuf_type*>(&m_Streambuf);
00684         }
00685         */
00686         
00700         static std::string printf(char const * __restrict fmt, ...)
00701         {
00702           char str[LINE_MAX];
00703           va_list ap;
00704 
00705           va_start(ap, fmt);
00706 #ifdef WIN32
00707           int ret = _vsnprintf(str, LINE_MAX - 1, fmt, ap);
00708 #else
00709           int ret = vsnprintf(str, LINE_MAX - 1, fmt, ap);
00710 #endif
00711           va_end(ap);
00712           std::string s(str);
00713 
00714           return s;
00715         }
00716 
00717         
00718         void setLogLevel(int level)
00719         {
00720           m_LogLevel = level;
00721         }
00722 
00723         void setLogLock(int lock)
00724         {
00725           if      (lock == 1)
00726                 {
00727                   m_LogLock = true;
00728                 }
00729           else if (lock == 0)
00730                 {
00731                   m_LogLock = false;
00732                 }
00733         }
00734 
00735 
00736         void enableLogLock()
00737         {
00738           m_LogLock = true;
00739         }
00740 
00741         void disableLogLock()
00742         {
00743           m_LogLock = false;
00744         }
00745 
00746         __ostream_type& level(int level)
00747         {
00748           if (m_LogLevel >= level)
00749                 {
00750                   return *this;
00751                 }
00752           else
00753                 {
00754                   return m_DummyStream;
00755                 }
00756 
00757         }
00758 
00759         inline void acquire()
00760         {
00761           if (m_LogLock) m_Mutex.acquire();
00762         }
00763 
00764         inline void release()
00765         {
00766           if (m_LogLock) m_Mutex.release();
00767         }
00768 
00769         __ostream_type m_DummyStream;
00770 
00771   private:
00772         int m_LogLevel;
00773         bool m_LogLock;
00774         ACE_Thread_Mutex m_Mutex;
00775 
00776   };
00777   typedef sync_callback<char> RtcSyncCallback;
00778   typedef basic_logbuf<char> RtcLogbuf;
00779   typedef basic_medlogbuf<char> RtcMedLogbuf;
00780   typedef basic_logstream<char> RtcLogStream;
00781 
00782 #else 
00783 
00784   class EXPORTS RtcSyncCallback
00785   {
00786   public:
00787         RtcSyncCallback() {;};
00788         virtual int operator()(const char* s) {;};
00789   };
00790 
00791   class EXPORTS RtcLogbuf
00792   {
00793   public:
00794         RtcLogbuf() {;};
00795         RtcLogbuf(const char* s, int m) {;};
00796         void open(const char* s, int m) {;};
00797         void setSyncCallBack(RtcSyncCallback& cb) {;};
00798   };
00799 
00800   class EXPORTS RtcMedLogbuf
00801   {
00802   public:
00803         RtcMedLogbuf() {;};
00804         RtcMedLogbuf(RtcLogbuf& f) {;};
00805         void  setDateFmt(char* fmt) {;};
00806         void  setDateFmt(std::string fmt) {;};
00807         void setSuffix(char* suffix) {;};
00808         void setSuffix(std::string suffix) {;};
00809   };
00810 
00811   class EXPORTS RtcLogStream
00812         : public ostream
00813   {
00814   public:
00815         enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
00816         static int strToLogLevel(std::string lv){return NORMAL;}
00817         RtcLogStream(RtcMedLogbuf& buf) {;};
00818         void setLogLevel(int level) {;};
00819         void setLogLock(int lock) {;};
00820         RtcLogStream& level(int level) {return *this;};
00821         /*
00822         RtcLogStream& operator<<(const char* s) {return *this;};
00823         RtcLogStream& operator<<(const string s) {return *this;};
00824         RtcLogStream& operator<<(const ostream& o) {return *this;};
00825         RtcLogStream& operator<<(const ostream o) {return *this;};
00826         */
00827   };
00828   
00829 #endif // NO_LOGGING  
00830   
00831 
00832   // __VA_ARGS__ cannot be used in VC   
00833 #if 0
00834 #define RTC_LOG(LV, fmt, ...) \
00835   rtcout.level(LV) << rtcout.printf(fmt, __VA_ARGS__) << std::endl;
00836 #define RTC_ERROR(fmt, ...) \
00837   RTC_LOG(RtcLogStream::RTL_ERROR, fmt, __VA_ARGS__)
00838 #define RTC_WARN(fmt, ...) \
00839   RTC_LOG(RtcLogStream::RTL_WARN, fmt, __VA_ARGS__)
00840 #define RTC_NORMAL(fmt, ...) \
00841   RTC_LOG(RtcLogStream::RTL_NORMAL, fmt, __VA_ARGS__)
00842 #define RTC_INFO(fmt, ...) \
00843   RTC_LOG(RtcLogStream::RTL_INFO, fmt, __VA_ARGS__)
00844 #define RTC_DEBUG(fmt, ...) \
00845   RTC_LOG(RtcLogStream::RTL_DEBUG, fmt, __VA_ARGS__)
00846 #define RTC_TRACE(fmt, ...) \
00847   RTC_LOG(RtcLogStream::RTL_TRACE, fmt, __VA_ARGS__)
00848 #define RTC_VERBOSE(fmt, ...) \
00849   RTC_LOG(RtcLogStream::RTL_VERBOSE, fmt, __VA_ARGS__)
00850 #define RTC_PARANOID(fmt, ...) \
00851   RTC_LOG(RtcLogStream::RTL_PARANOID, fmt, __VA_ARGS__)
00852 #endif
00853 
00854 #ifndef NO_LOGGING
00855 
00869 #define RTC_LOG(LV, fmt)                                                                                                \
00870   rtcout.acquire();                                                                                                             \
00871   rtcout.level(LV) << rtcout.printf fmt << std::endl;                                   \
00872   rtcout.release()
00873 
00889 #define RTC_ERROR(fmt)                                                                                                  \
00890   rtcout.acquire();                                                                                                             \
00891   rtcout.level(RtcLogStream::RTL_ERROR)  << rtcout.printf fmt << std::endl; \
00892   rtcout.release()
00893 
00913 #define RTC_WARN(fmt)                                                                                                   \
00914   rtcout.acquire();                                                                                                             \
00915   rtcout.level(RtcLogStream::RTL_WARN) << rtcout.printf fmt << std::endl;       \
00916   rtcout.release()
00917 
00937 #define RTC_INFO(fmt)                                                                                                   \
00938   rtcout.acquire();                                                                                                             \
00939   rtcout.level(RtcLogStream::RTL_INFO) << rtcout.printf fmt << std::endl;       \
00940   rtcout.release()
00941 
00961 #define RTC_NORMAL(fmt)                                                                                                 \
00962   rtcout.acquire();                                                                                                             \
00963   rtcout.level(RtcLogStream::RTL_NORMAL) << rtcout.printf fmt << std::endl;     \
00964   rtcout.release()
00965 
00985 #define RTC_DEBUG(fmt)                                                                                                  \
00986   rtcout.acquire();                                                                                                             \
00987   rtcout.level(RtcLogStream::RTL_DEBUG) << rtcout.printf fmt << std::endl;      \
00988   rtcout.release()
00989 
01009 #define RTC_TRACE(fmt)                                                                                                  \
01010   rtcout.acquire();                                                                                                             \
01011   rtcout.level(RtcLogStream::RTL_TRACE) << rtcout.printf fmt << std::endl;      \
01012   rtcout.release()
01013 
01033 #define RTC_VERBOSE(fmt)                                                                                                \
01034   rtcout.acquire();                                                                                                             \
01035   rtcout.level(RtcLogStream::RTL_VERBOSE) << rtcout.printf fmt << std::endl;\
01036   rtcout.release()
01037 
01057 #define RTC_PARANOID(fmt)                                                                                               \
01058   rtcout.acquire();                                                                                                             \
01059   rtcout.level(RtcLogStream::RTL_PARANOID) << rtcout.printf fmt << std::endl;   \
01060   rtcout.release()
01061 
01062 #else
01063 #define RTC_ERROR(fmt)
01064 #define RTC_WARN(fmt)
01065 #define RTC_NORMAL(fmt)
01066 #define RTC_INFO(fmt)
01067 #define RTC_DEBUG(fmt)
01068 #define RTC_TRACE(fmt)
01069 #define RTC_VERBOSE(fmt)
01070 #define RTC_PARANOID(fmt)
01071 #endif
01072 
01073 }; // namespace RTM
01074 
01075 #endif  // RtcSystemLogger_h

Generated on Sat Oct 28 02:28:13 2006 for OpenRTM by  doxygen 1.4.1