00001
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
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
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
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
00163
00164
00165 std::streamsize ssize = this->xsputn(s, n);
00166
00167
00168
00169
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
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
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
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
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
00384
00385
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
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
00484
00485 m_pLogbuf->sputn(s.c_str(), s.size());
00486 m_pLogbuf->pubsync();
00487
00488
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
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
00587 enum
00588 {
00589 RTL_SILENT,
00590 RTL_ERROR,
00591 RTL_WARN,
00592 RTL_INFO,
00593 RTL_NORMAL,
00594 RTL_DEBUG,
00595 RTL_TRACE,
00596 RTL_VERBOSE,
00597 RTL_PARANOID,
00598 RTL_MANDATORY
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
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
00689
00690
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
00828
00829
00830
00831
00832 };
00833
00834 #endif // NO_LOGGING
00835
00836
00837
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 };
01079
01080 #endif // SystemLogger_h