00001
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
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
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
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
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
00182
00183
00184 std::streamsize ssize = this->xsputn(s, n);
00185
00186
00187
00188
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
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
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
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
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
00404
00405
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
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
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
00505
00506 m_pLogbuf->sputn(s.c_str(), s.size());
00507 m_pLogbuf->pubsync();
00508
00509
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
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
00611 enum
00612 {
00613 RTL_SILENT,
00614 RTL_ERROR,
00615 RTL_WARN,
00616 RTL_INFO,
00617 RTL_NORMAL,
00618 RTL_DEBUG,
00619 RTL_TRACE,
00620 RTL_VERBOSE,
00621 RTL_PARANOID,
00622 RTL_MANDATORY
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
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
00713
00714
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
00852
00853
00854
00855
00856 };
00857
00858 #endif // NO_LOGGING
00859
00860
00861
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 };
01103
01104 #endif // SystemLogger_h