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 #ifndef SystemLogger_h
00050 #define SystemLogger_h
00051
00052 #include <rtm/RTC.h>
00053
00054 #include <iostream>
00055 #include <fstream>
00056 #include <stdio.h>
00057 #include <stdarg.h>
00058 #include <limits.h>
00059 #include <time.h>
00060 #include <errno.h>
00061
00062
00063 #include <ace/Mutex.h>
00064
00065 #ifdef RTM_GCC2
00066 #define NO_LOGGING
00067 #endif
00068
00069 #ifdef WIN32
00070
00071 #define __restrict
00072 #endif
00073
00074 namespace RTC
00075 {
00076
00077 #ifndef NO_LOGGING
00078 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00079 class sync_callback
00080 {
00081 public:
00082 virtual ~sync_callback(){}
00083 virtual int operator()(const _CharT* s) = 0;
00084 };
00085
00086
00106 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00107 class basic_logbuf
00108 : public std::basic_filebuf<_CharT, _Traits>
00109 {
00110 public:
00111
00112 typedef _CharT char_type;
00113 typedef _Traits traits_type;
00114 typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00115
00129 basic_logbuf()
00130 : __filebuf_type(), m_pCallBack(NULL)
00131 {;}
00132
00146 basic_logbuf(const char_type* s,
00147 std::ios_base::openmode mode = std::ios_base::out,
00148 long protection = 0666)
00149 : __filebuf_type(), m_pCallBack(NULL)
00150 {
00151 this->open(s, mode);
00152 }
00153
00167 virtual ~basic_logbuf()
00168 {
00169 this->sync();
00170 this->close();
00171 };
00172
00173 virtual std::streamsize sputn(const char_type* s, std::streamsize n)
00174 {
00175 ACE_Guard<ACE_Thread_Mutex> gaurd(m_Mutex);
00176
00177
00178
00179 std::streamsize ssize = this->xsputn(s, n);
00180
00181
00182
00183
00184
00185
00186 this->sync();
00187 return ssize;
00188 }
00189
00190 void setSyncCallBack(sync_callback<char_type>& cb)
00191 {
00192 m_pCallBack = &cb;
00193 }
00194
00195 protected:
00209 virtual int sync()
00210 {
00211 std::string::basic_string<_CharT> s(this->pbase(),
00212 this->pptr() - this->pbase());
00213 if (m_pCallBack != NULL)
00214 {
00215 (*m_pCallBack)(s.c_str());
00216 }
00217
00218
00219 int ret = __filebuf_type::sync();
00220
00221 return ret;
00222 }
00223
00224 private:
00225 ACE_Thread_Mutex m_Mutex;
00226 sync_callback<char_type>* m_pCallBack;
00227
00228 };
00229
00230
00231
00232
00252 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00253 class EXPORTS basic_medlogbuf
00254 : public std::basic_streambuf<_CharT, _Traits>
00255 {
00256 public:
00257
00258 typedef _CharT char_type;
00259 typedef _Traits traits_type;
00260 typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00261 typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00262
00277 basic_medlogbuf()
00278 : __streambuf_type(), m_pLogbuf(NULL)
00279 {
00280
00281 m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00282 }
00283
00284 basic_medlogbuf(__filebuf_type& filebuf)
00285 : __streambuf_type(), m_pLogbuf(&filebuf)
00286 {
00287 char *pStart = m_Data;
00288 char *pEnd = m_Data + (LINE_MAX - 1);
00289 this->setp(pStart, pEnd);
00290 this->setg(pStart, pStart, pEnd);
00291
00292
00293 m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00294 }
00295
00309 virtual ~basic_medlogbuf()
00310 {
00311 this->sync();
00312 }
00313
00314 void setBuffer(__filebuf_type& filebuf)
00315 {
00316 m_pLogbuf = &filebuf;
00317 char *pStart = m_Data;
00318 char *pEnd = m_Data + (LINE_MAX - 1);
00319 this->setp(pStart, pEnd);
00320 this->setg(pStart, pStart, pEnd);
00321 }
00322
00360 void setDateFmt(char* fmt)
00361 {
00362 m_DateFmt = std::string(fmt);
00363 }
00364
00376 void setDateFmt(const std::string& fmt)
00377 {
00378 m_DateFmt = fmt;
00379 }
00380
00392 std::string getFmtDate()
00393 {
00394 const int maxsize = 256;
00395 char buf[maxsize];
00396
00397
00398
00399
00400
00401
00402 time_t timer;
00403 struct tm* date;
00404
00405 timer = time(NULL);
00406 date = localtime(&timer);
00407 strftime(buf, maxsize, m_DateFmt.c_str(), date);
00408
00409 std::string ret(buf);
00410 return ret;
00411 }
00412
00424 void setSuffix(char* suffix)
00425 {
00426 m_Suffix = std::string(suffix);
00427 }
00428
00440 void setSuffix(const std::string& suffix)
00441 {
00442 m_Suffix = suffix;
00443 }
00444
00456 std::string getSuffix()
00457 {
00458 return m_Suffix;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468 protected:
00482 virtual int sync()
00483 {
00484 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00485 int ret(0);
00486 if (m_pLogbuf != NULL &&
00487 (this->pptr() - this->pbase()) > 0)
00488 {
00489 {
00490
00491 *(this->pptr()) = '\0';
00492 std::string::basic_string<_CharT> tmp(this->pbase(),
00493 this->pptr() -
00494 this->pbase());
00495
00496 std::string s = getFmtDate();
00497 s += ( s.size() > 0 ? " " : "" ) + getSuffix();
00498 s += ( getSuffix().size() > 0 ? " " : "" ) + tmp;
00499
00500
00501 m_pLogbuf->sputn(s.c_str(), s.size());
00502 m_pLogbuf->pubsync();
00503
00504
00505 ret = __streambuf_type::sync();
00506 pbump( this->pbase() - this->pptr() );
00507 }
00508 }
00509 return ret;
00510 }
00511
00512 private:
00513 __filebuf_type* m_pLogbuf;
00514 char m_Data[LINE_MAX];
00515 std::string m_DateFmt;
00516 std::string m_Suffix;
00517 ACE_Thread_Mutex m_Mutex;
00518 };
00519
00520
00539 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00540 class basic_dummybuf
00541 : public std::basic_streambuf<_CharT, _Traits>
00542 {
00543 public:
00544
00545 typedef _CharT char_type;
00546 typedef _Traits traits_type;
00547 typedef typename traits_type::int_type int_type;
00548 typedef typename traits_type::pos_type pos_type;
00549 typedef typename traits_type::off_type off_type;
00550 typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00551 typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00552
00553 basic_dummybuf()
00554 {
00555 char *pStart = m_Data;
00556 char *pEnd = m_Data + (LINE_MAX - 1);
00557 this->setp(pStart, pEnd);
00558 this->setg(pStart, pStart, pEnd);
00559 }
00560
00561 ~basic_dummybuf()
00562 {
00563 }
00564
00565 int_type overflow(int_type c = _Traits::eof() )
00566 {
00567 pbump( this->pbase() - this->pptr() );
00568 return _Traits::not_eof(c);
00569 }
00570
00571 virtual int sync()
00572 {
00573 pbump( this->pbase() - this->pptr() );
00574 return 0;
00575 }
00576
00577 private:
00578 char m_Data[255];
00579 };
00580
00581
00600 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00601 class EXPORTS basic_logstream
00602 : public std::basic_ostream<_CharT, _Traits>
00603 {
00604 public:
00605
00606 enum
00607 {
00608 RTL_SILENT,
00609 RTL_ERROR,
00610 RTL_WARN,
00611 RTL_INFO,
00612 RTL_NORMAL,
00613 RTL_DEBUG,
00614 RTL_TRACE,
00615 RTL_VERBOSE,
00616 RTL_PARANOID,
00617 RTL_MANDATORY
00618 };
00619
00620 static int strToLogLevel(const std::string& lv)
00621 {
00622 if (lv == "SILENT")
00623 return basic_logstream::RTL_SILENT;
00624 else if (lv == "ERROR")
00625 return basic_logstream::RTL_ERROR;
00626 else if (lv == "WARN")
00627 return basic_logstream::RTL_WARN;
00628 else if (lv == "INFO")
00629 return basic_logstream::RTL_INFO;
00630 else if (lv == "NORNAL")
00631 return basic_logstream::RTL_NORMAL;
00632 else if (lv == "DEBUG")
00633 return basic_logstream::RTL_DEBUG;
00634 else if (lv == "TRACE")
00635 return basic_logstream::RTL_TRACE;
00636 else if (lv == "VERBOSE")
00637 return basic_logstream::RTL_VERBOSE;
00638 else if (lv == "PARANOID")
00639 return basic_logstream::RTL_PARANOID;
00640 else if (lv == "MANDATORY")
00641 return basic_logstream::RTL_MANDATORY;
00642 else
00643 return basic_logstream::RTL_NORMAL;
00644 }
00645
00646
00647 typedef _CharT char_type;
00648 typedef _Traits traits_type;
00649 typedef basic_logbuf<char_type, traits_type> __logbuf_type;
00650 typedef basic_dummybuf<char_type, traits_type> __dummybuf_type;
00651 typedef basic_logstream<char_type, traits_type> __logstream_type;
00652 typedef std::basic_ostream<char_type, traits_type> __ostream_type;
00653 typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00654
00670 basic_logstream(__streambuf_type& streambuf)
00671 : __ostream_type(&streambuf),
00672 m_DummyStream(new __dummybuf_type()),
00673 m_LogLevel(RTL_NORMAL), m_LogLock(false)
00674 {
00675 this->init(&streambuf);
00676 }
00677
00691 ~basic_logstream()
00692 {
00693 }
00694
00706
00707
00708
00709
00710
00711
00712
00726 static std::string printf(char const * __restrict fmt, ...)
00727 {
00728 char str[LINE_MAX];
00729 va_list ap;
00730
00731 va_start(ap, fmt);
00732 #ifdef WIN32
00733 _vsnprintf(str, LINE_MAX - 1, fmt, ap);
00734 #else
00735 vsnprintf(str, LINE_MAX - 1, fmt, ap);
00736 #endif
00737 va_end(ap);
00738 std::string s(str);
00739
00740 return s;
00741 }
00742
00743
00744 void setLogLevel(const std::string& level)
00745 {
00746 m_LogLevel = strToLogLevel(level);
00747 }
00748
00749 void setLogLevel(int level)
00750 {
00751 m_LogLevel = level;
00752 }
00753
00754 void setLogLock(bool lock)
00755 {
00756 m_LogLock = lock;
00757 }
00758
00759
00760 void enableLogLock()
00761 {
00762 m_LogLock = true;
00763 }
00764
00765 void disableLogLock()
00766 {
00767 m_LogLock = false;
00768 }
00769
00770 __ostream_type& level(int level)
00771 {
00772 if (m_LogLevel >= level)
00773 {
00774 return *this;
00775 }
00776 else
00777 {
00778 return m_DummyStream;
00779 }
00780
00781 }
00782
00783 inline void acquire()
00784 {
00785 if (m_LogLock) m_Mutex.acquire();
00786 }
00787
00788 inline void release()
00789 {
00790 if (m_LogLock) m_Mutex.release();
00791 }
00792
00793 __ostream_type m_DummyStream;
00794
00795 private:
00796 int m_LogLevel;
00797 bool m_LogLock;
00798 ACE_Thread_Mutex m_Mutex;
00799
00800 };
00801 typedef sync_callback<char> SyncCallback;
00802 typedef basic_logbuf<char> Logbuf;
00803 typedef basic_medlogbuf<char> MedLogbuf;
00804 typedef basic_logstream<char> LogStream;
00805
00806 #else
00807
00808 class SyncCallback
00809 {
00810 public:
00811 SyncCallback() {;};
00812 virtual int operator()(const char* s) {;};
00813 };
00814
00815 class Logbuf
00816 {
00817 public:
00818 Logbuf() {;};
00819 Logbuf(const char* s, int m) {;};
00820 void open(const char* s, int m) {;};
00821 void setSyncCallBack(SyncCallback& cb) {;};
00822 };
00823
00824 class MedLogbuf
00825 {
00826 public:
00827 MedLogbuf() {;};
00828 MedLogbuf(Logbuf& f) {;};
00829 void setDateFmt(char* fmt) {;};
00830 void setDateFmt(const std::string& fmt) {;};
00831 void setSuffix(const char* suffix) {;};
00832 void setSuffix(const std::string& suffix) {;};
00833 };
00834
00835 class LogStream
00836 : public ostream
00837 {
00838 public:
00839 enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
00840 static int strToLogLevel(const std::string& lv){return NORMAL;}
00841 LogStream(MedLogbuf& buf) {;};
00842 void setLogLevel(int level) {;};
00843 void setLogLock(int lock) {;};
00844 LogStream& level(int level) {return *this;};
00845
00846
00847
00848
00849
00850
00851 };
00852
00853 #endif // NO_LOGGING
00854
00855
00856
00857 #if 0
00858 #define RTC_LOG(LV, fmt, ...) \
00859 rtcout.level(LV) << rtcout.printf(fmt, __VA_ARGS__) << std::endl;
00860 #define RTC_ERROR(fmt, ...) \
00861 RTC_LOG(LogStream::RTL_ERROR, fmt, __VA_ARGS__)
00862 #define RTC_WARN(fmt, ...) \
00863 RTC_LOG(LogStream::RTL_WARN, fmt, __VA_ARGS__)
00864 #define RTC_NORMAL(fmt, ...) \
00865 RTC_LOG(LogStream::RTL_NORMAL, fmt, __VA_ARGS__)
00866 #define RTC_INFO(fmt, ...) \
00867 RTC_LOG(LogStream::RTL_INFO, fmt, __VA_ARGS__)
00868 #define RTC_DEBUG(fmt, ...) \
00869 RTC_LOG(LogStream::RTL_DEBUG, fmt, __VA_ARGS__)
00870 #define RTC_TRACE(fmt, ...) \
00871 RTC_LOG(LogStream::RTL_TRACE, fmt, __VA_ARGS__)
00872 #define RTC_VERBOSE(fmt, ...) \
00873 RTC_LOG(LogStream::RTL_VERBOSE, fmt, __VA_ARGS__)
00874 #define RTC_PARANOID(fmt, ...) \
00875 RTC_LOG(LogStream::RTL_PARANOID, fmt, __VA_ARGS__)
00876 #endif
00877
00878 #ifndef NO_LOGGING
00879
00893 #define RTC_LOG(LV, fmt) \
00894 rtcout.acquire(); \
00895 rtcout.level(LV) << rtcout.printf fmt << std::endl; \
00896 rtcout.release()
00897
00913 #define RTC_ERROR(fmt) \
00914 rtcout.acquire(); \
00915 rtcout.level(LogStream::RTL_ERROR) << rtcout.printf fmt << std::endl; \
00916 rtcout.release()
00917
00937 #define RTC_WARN(fmt) \
00938 rtcout.acquire(); \
00939 rtcout.level(LogStream::RTL_WARN) << rtcout.printf fmt << std::endl;\
00940 rtcout.release()
00941
00961 #define RTC_INFO(fmt) \
00962 rtcout.acquire(); \
00963 rtcout.level(LogStream::RTL_INFO) << rtcout.printf fmt << std::endl;\
00964 rtcout.release()
00965
00985 #define RTC_NORMAL(fmt) \
00986 rtcout.acquire(); \
00987 rtcout.level(LogStream::RTL_NORMAL) << rtcout.printf fmt << std::endl;\
00988 rtcout.release()
00989
01009 #define RTC_DEBUG(fmt) \
01010 rtcout.acquire(); \
01011 rtcout.level(LogStream::RTL_DEBUG) << rtcout.printf fmt << std::endl; \
01012 rtcout.release()
01013
01033 #define RTC_TRACE(fmt) \
01034 rtcout.acquire(); \
01035 rtcout.level(LogStream::RTL_TRACE) << rtcout.printf fmt << std::endl; \
01036 rtcout.release()
01037
01057 #define RTC_VERBOSE(fmt) \
01058 rtcout.acquire(); \
01059 rtcout.level(LogStream::RTL_VERBOSE) << rtcout.printf fmt << std::endl; \
01060 rtcout.release()
01061
01081 #define RTC_PARANOID(fmt) \
01082 rtcout.acquire(); \
01083 rtcout.level(LogStream::RTL_PARANOID) << rtcout.printf fmt << std::endl; \
01084 rtcout.release()
01085
01086 #else
01087 #define RTC_ERROR(fmt)
01088 #define RTC_WARN(fmt)
01089 #define RTC_NORMAL(fmt)
01090 #define RTC_INFO(fmt)
01091 #define RTC_DEBUG(fmt)
01092 #define RTC_TRACE(fmt)
01093 #define RTC_VERBOSE(fmt)
01094 #define RTC_PARANOID(fmt)
01095 #endif
01096
01097 };
01098
01099 #endif // SystemLogger_h