00001
00019
00020
00021
00022
00023
00024
00025
00026
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
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
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
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
00157
00158
00159 streamsize ssize = this->xsputn(s, n);
00160
00161
00162
00163
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
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
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
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
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
00378
00379
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
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
00477
00478 m_pLogbuf->sputn(s.c_str(), s.size());
00479 m_pLogbuf->pubsync();
00480
00481
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
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
00580 enum
00581 {
00582 RTL_SILENT,
00583 RTL_ERROR,
00584 RTL_WARN,
00585 RTL_INFO,
00586 RTL_NORMAL,
00587 RTL_DEBUG,
00588 RTL_TRACE,
00589 RTL_VERBOSE,
00590 RTL_PARANOID,
00591 RTL_MANDATORY
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
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
00682
00683
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
00823
00824
00825
00826
00827 };
00828
00829 #endif // NO_LOGGING
00830
00831
00832
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 };
01074
01075 #endif // RtcSystemLogger_h