00001
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef RtcSystemLogger_h
00028 #define RtcSystemLogger_h
00029
00030 #include <iostream>
00031 #include <fstream>
00032 #include <stdio.h>
00033 #include <stdarg.h>
00034 #include <limits.h>
00035 #include <time.h>
00036 #include <errno.h>
00037
00038
00039 #include <ace/Mutex.h>
00040
00041 #include "rtm/config_rtc.h"
00042
00043 #ifdef RTM_GCC2
00044 #define NO_LOGGING
00045 #endif
00046
00047 namespace RTM
00048 {
00049
00050 #ifndef NO_LOGGING
00051 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00052 class sync_callback
00053 {
00054 public:
00055 virtual int operator()(const _CharT* s) = 0;
00056 };
00057
00077 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00078 class basic_logbuf
00079 : public std::basic_filebuf<_CharT, _Traits>
00080 {
00081 public:
00082
00083 typedef _CharT std::char_type;
00084 typedef _Traits std::traits_type;
00085 typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00086
00100 basic_logbuf()
00101 : __filebuf_type(), m_pCallBack(NULL)
00102 {;}
00103
00117 basic_logbuf(const char_type* s,
00118 std::ios_base::openmode mode = std::ios_base::out,
00119 long protection = 0666)
00120 : __filebuf_type(), m_pCallBack(NULL)
00121 {
00122 this->open(s, mode);
00123 }
00124
00138 virtual ~basic_logbuf()
00139 {
00140 this->sync();
00141 this->close();
00142 };
00143
00144 virtual streamsize sputn(const char_type* s, streamsize n)
00145 {
00146 ACE_Guard<ACE_Thread_Mutex> gaurd(m_Mutex);
00147
00148
00149
00150 streamsize ssize = this->xsputn(s, n);
00151
00152
00153
00154
00155
00156
00157 this->sync();
00158 return ssize;
00159 }
00160
00161 void setSyncCallBack(sync_callback<char_type>& cb)
00162 {
00163 m_pCallBack = &cb;
00164 }
00165
00166 protected:
00180 virtual int sync()
00181 {
00182 std::string::basic_string<_CharT> s(this->pbase(),
00183 this->pptr() - this->pbase());
00184 if (m_pCallBack != NULL)
00185 {
00186 (*m_pCallBack)(s.c_str());
00187 }
00188
00189
00190 int ret = __filebuf_type::sync();
00191
00192 return ret;
00193 }
00194
00195 private:
00196 ACE_Thread_Mutex m_Mutex;
00197 sync_callback<char_type>* m_pCallBack;
00198
00199 };
00200
00201
00202
00222 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00223 class basic_medlogbuf
00224 : public std::basic_streambuf<_CharT, _Traits>
00225 {
00226 public:
00227
00228 typedef _CharT std::char_type;
00229 typedef _Traits std::traits_type;
00230 typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00231 typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00232
00247 basic_medlogbuf()
00248 : __streambuf_type(), m_pLogbuf(NULL)
00249 {
00250
00251 m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00252 }
00253
00254 basic_medlogbuf(__filebuf_type& filebuf)
00255 : __streambuf_type(), m_pLogbuf(&filebuf)
00256 {
00257 char *pStart = m_Data;
00258 char *pEnd = m_Data + (LINE_MAX - 1);
00259 this->setp(pStart, pEnd);
00260 this->setg(pStart, pStart, pEnd);
00261
00262
00263 m_DateFmt = "[%Y-%m-%dT%H.%M.%S%Z]";
00264 }
00265
00279 virtual ~basic_medlogbuf()
00280 {
00281 this->sync();
00282 }
00283
00284 void setBuffer(__filebuf_type& filebuf)
00285 {
00286 m_pLogbuf = &filebuf;
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
00330 void setDateFmt(char* fmt)
00331 {
00332 m_DateFmt = std::string(fmt);
00333 }
00334
00346 void setDateFmt(std::string fmt)
00347 {
00348 m_DateFmt = fmt;
00349 }
00350
00362 std::string getFmtDate()
00363 {
00364 int maxsize(256);
00365 char buf[maxsize];
00366
00367
00368
00369
00370
00371
00372 time_t timer;
00373 struct tm* date;
00374
00375 timer = time(NULL);
00376 date = localtime(&timer);
00377 strftime(buf, maxsize, m_DateFmt.c_str(), date);
00378
00379 std::string ret(buf);
00380 return ret;
00381 }
00382
00394 void setSuffix(char* suffix)
00395 {
00396 m_Suffix = std::string(suffix);
00397 }
00398
00410 void setSuffix(std::string suffix)
00411 {
00412 m_Suffix = suffix;
00413 }
00414
00426 std::string getSuffix()
00427 {
00428 return m_Suffix;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 protected:
00452 virtual int sync()
00453 {
00454 int ret(0);
00455 if (m_pLogbuf != NULL &&
00456 (this->pptr() - this->pbase()) > 0)
00457 {
00458 {
00459 ACE_Guard<ACE_Thread_Mutex> guard(m_Mutex);
00460 *(this->pptr()) = '\0';
00461 std::string::basic_string<_CharT> tmp(this->pbase(),
00462 this->pptr() - this->pbase());
00463
00464 std::string s = getFmtDate();
00465 s += ( s.size() > 0 ? " " : "" ) + getSuffix();
00466 s += ( getSuffix().size() > 0 ? " " : "" ) + tmp;
00467
00468
00469 m_pLogbuf->sputn(s.c_str(), s.size());
00470 m_pLogbuf->pubsync();
00471
00472
00473 ret = __streambuf_type::sync();
00474 pbump( this->pbase() - this->pptr() );
00475 }
00476 }
00477 return ret;
00478 }
00479
00480 private:
00481 __filebuf_type* m_pLogbuf;
00482 char m_Data[LINE_MAX];
00483 std::string m_DateFmt;
00484 std::string m_Suffix;
00485 ACE_Thread_Mutex m_Mutex;
00486 };
00487
00488
00507 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00508 class basic_dummybuf
00509 : public std::basic_streambuf<_CharT, _Traits>
00510 {
00511 public:
00512
00513 typedef _CharT std::char_type;
00514 typedef _Traits std::traits_type;
00515 typedef typename traits_type::int_type int_type;
00516 typedef typename traits_type::pos_type pos_type;
00517 typedef typename traits_type::off_type off_type;
00518 typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00519 typedef std::basic_filebuf<char_type, traits_type> __filebuf_type;
00520
00521 basic_dummybuf()
00522 {
00523 char *pStart = m_Data;
00524 char *pEnd = m_Data + (LINE_MAX - 1);
00525 this->setp(pStart, pEnd);
00526 this->setg(pStart, pStart, pEnd);
00527 }
00528
00529
00530 int_type overflow(int_type c = _Traits::eof() )
00531 {
00532 pbump( this->pbase() - this->pptr() );
00533 return _Traits::not_eof(c);
00534 }
00535
00536 virtual int sync()
00537 {
00538 pbump( this->pbase() - this->pptr() );
00539 return 0;
00540 }
00541
00542 private:
00543 char m_Data[255];
00544 };
00545
00546
00565 template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
00566 class basic_logstream
00567 : public std::basic_ostream<_CharT, _Traits>
00568 {
00569 public:
00570
00571 enum
00572 {
00573 SILENT,
00574 ERROR,
00575 WARN,
00576 INFO,
00577 NORMAL,
00578 DEBUG,
00579 TRACE,
00580 VERBOSE,
00581 PARANOID,
00582 MANDATORY
00583 };
00584
00585 static int strToLogLevel(std::string lv)
00586 {
00587 if (lv == "SILENT")
00588 return basic_logstream::SILENT;
00589 else if (lv == "ERROR")
00590 return basic_logstream::ERROR;
00591 else if (lv == "WARN")
00592 return basic_logstream::WARN;
00593 else if (lv == "INFO")
00594 return basic_logstream::INFO;
00595 else if (lv == "NORNAL")
00596 return basic_logstream::NORMAL;
00597 else if (lv == "DEBUG")
00598 return basic_logstream::DEBUG;
00599 else if (lv == "TRACE")
00600 return basic_logstream::TRACE;
00601 else if (lv == "VERBOSE")
00602 return basic_logstream::VERBOSE;
00603 else if (lv == "PARANOID")
00604 return basic_logstream::PARANOID;
00605 else if (lv == "MANDATORY")
00606 return basic_logstream::MANDATORY;
00607 else
00608 return basic_logstream::NORMAL;
00609 }
00610
00611
00612 typedef _CharT std::char_type;
00613 typedef _Traits std::traits_type;
00614 typedef basic_logbuf<char_type, traits_type> __logbuf_type;
00615 typedef basic_dummybuf<char_type, traits_type> __dummybuf_type;
00616 typedef basic_logstream<char_type, traits_type> __logstream_type;
00617 typedef std::basic_ostream<char_type, traits_type> __ostream_type;
00618 typedef std::basic_streambuf<char_type, traits_type> __streambuf_type;
00619
00635 basic_logstream(__streambuf_type& streambuf)
00636 : __ostream_type(&streambuf),
00637 m_DummyStream(new __dummybuf_type()),
00638 m_LogLevel(NORMAL), m_LogLock(false)
00639 {
00640 this->init(&streambuf);
00641 }
00642
00656 ~basic_logstream()
00657 {
00658 }
00659
00671
00672
00673
00674
00675
00676
00677
00691 static std::string printf(char const * __restrict fmt, ...)
00692 {
00693 char str[LINE_MAX];
00694 va_list ap;
00695
00696 va_start(ap, fmt);
00697 int ret = vsnprintf(str, LINE_MAX - 1, fmt, ap);
00698 va_end(ap);
00699 std::string s(str);
00700
00701 return s;
00702 }
00703
00704
00705 void setLogLevel(int level)
00706 {
00707 m_LogLevel = level;
00708 }
00709
00710 void setLogLock(int lock)
00711 {
00712 if (lock == 1)
00713 {
00714 m_LogLock = true;
00715 }
00716 else if (lock == 0)
00717 {
00718 m_LogLock = false;
00719 }
00720 }
00721
00722
00723 void enableLogLock()
00724 {
00725 m_LogLock = true;
00726 }
00727
00728 void disableLogLock()
00729 {
00730 m_LogLock = false;
00731 }
00732
00733 __ostream_type& level(int level)
00734 {
00735 if (m_LogLevel >= level)
00736 {
00737 return *this;
00738 }
00739 else
00740 {
00741 return m_DummyStream;
00742 }
00743
00744 }
00745
00746 inline void acquire()
00747 {
00748 if (m_LogLock) m_Mutex.acquire();
00749 }
00750
00751 inline void release()
00752 {
00753 if (m_LogLock) m_Mutex.release();
00754 }
00755
00756 __ostream_type m_DummyStream;
00757
00758 private:
00759 int m_LogLevel;
00760 bool m_LogLock;
00761 ACE_Thread_Mutex m_Mutex;
00762
00763 };
00764 typedef sync_callback<char> RtcSyncCallback;
00765 typedef basic_logbuf<char> RtcLogbuf;
00766 typedef basic_medlogbuf<char> RtcMedLogbuf;
00767 typedef basic_logstream<char> RtcLogStream;
00768
00769 #else
00770
00771 class RtcSyncCallback
00772 {
00773 public:
00774 RtcSyncCallback() {;};
00775 virtual int operator()(const char* s) {;};
00776 };
00777
00778 class RtcLogbuf
00779 {
00780 public:
00781 RtcLogbuf() {;};
00782 RtcLogbuf(const char* s, int m) {;};
00783 void open(const char* s, int m) {;};
00784 void setSyncCallBack(RtcSyncCallback& cb) {;};
00785 };
00786
00787 class RtcMedLogbuf
00788 {
00789 public:
00790 RtcMedLogbuf() {;};
00791 RtcMedLogbuf(RtcLogbuf& f) {;};
00792 void setDateFmt(char* fmt) {;};
00793 void setDateFmt(std::string fmt) {;};
00794 void setSuffix(char* suffix) {;};
00795 void setSuffix(std::string suffix) {;};
00796 };
00797
00798 class RtcLogStream
00799 : public ostream
00800 {
00801 public:
00802 enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
00803 static int strToLogLevel(std::string lv){return NORMAL;}
00804 RtcLogStream(RtcMedLogbuf& buf) {;};
00805 void setLogLevel(int level) {;};
00806 void setLogLock(int lock) {;};
00807 RtcLogStream& level(int level) {return *this;};
00808
00809
00810
00811
00812
00813
00814 };
00815
00816 #endif // NO_LOGGING
00817
00818
00819
00820 #if 0
00821 #define RTC_LOG(LV, fmt, ...) \
00822 rtcout.level(LV) << rtcout.printf(fmt, __VA_ARGS__) << std::endl;
00823 #define RTC_ERROR(fmt, ...) RTC_LOG(RtcLogStream::ERROR, fmt, __VA_ARGS__)
00824 #define RTC_WARN(fmt, ...) RTC_LOG(RtcLogStream::WARN, fmt, __VA_ARGS__)
00825 #define RTC_NORMAL(fmt, ...) RTC_LOG(RtcLogStream::NORMAL, fmt, __VA_ARGS__)
00826 #define RTC_INFO(fmt, ...) RTC_LOG(RtcLogStream::INFO, fmt, __VA_ARGS__)
00827 #define RTC_DEBUG(fmt, ...) RTC_LOG(RtcLogStream::DEBUG, fmt, __VA_ARGS__)
00828 #define RTC_TRACE(fmt, ...) RTC_LOG(RtcLogStream::TRACE, fmt, __VA_ARGS__)
00829 #define RTC_VERBOSE(fmt, ...) RTC_LOG(RtcLogStream::VERBOSE, fmt, __VA_ARGS__)
00830 #define RTC_PARANOID(fmt, ...) RTC_LOG(RtcLogStream::PARANOID, fmt, __VA_ARGS__)
00831 #endif
00832
00833 #ifndef NO_LOGGING
00834
00848 #define RTC_LOG(LV, fmt) \
00849 rtcout.acquire(); \
00850 rtcout.level(LV) << rtcout.printf fmt << std::endl; \
00851 rtcout.release()
00852
00868 #define RTC_ERROR(fmt) \
00869 rtcout.acquire(); \
00870 rtcout.level(RtcLogStream::ERROR) << rtcout.printf fmt << std::endl; \
00871 rtcout.release()
00872
00892 #define RTC_WARN(fmt) \
00893 rtcout.acquire(); \
00894 rtcout.level(RtcLogStream::WARN) << rtcout.printf fmt << std::endl; \
00895 rtcout.release()
00896
00916 #define RTC_INFO(fmt) \
00917 rtcout.acquire(); \
00918 rtcout.level(RtcLogStream::INFO) << rtcout.printf fmt << std::endl; \
00919 rtcout.release()
00920
00940 #define RTC_NORMAL(fmt) \
00941 rtcout.acquire(); \
00942 rtcout.level(RtcLogStream::NORMAL) << rtcout.printf fmt << std::endl; \
00943 rtcout.release()
00944
00964 #define RTC_DEBUG(fmt) \
00965 rtcout.acquire(); \
00966 rtcout.level(RtcLogStream::DEBUG) << rtcout.printf fmt << std::endl; \
00967 rtcout.release()
00968
00988 #define RTC_TRACE(fmt) \
00989 rtcout.acquire(); \
00990 rtcout.level(RtcLogStream::TRACE) << rtcout.printf fmt << std::endl; \
00991 rtcout.release()
00992
01012 #define RTC_VERBOSE(fmt) \
01013 rtcout.acquire(); \
01014 rtcout.level(RtcLogStream::VERBOSE) << rtcout.printf fmt << std::endl; \
01015 rtcout.release()
01016
01036 #define RTC_PARANOID(fmt) \
01037 rtcout.acquire(); \
01038 rtcout.level(RtcLogStream::PARANOID) << rtcout.printf fmt << std::endl; \
01039 rtcout.release()
01040
01041 #else
01042 #define RTC_ERROR(fmt)
01043 #define RTC_WARN(fmt)
01044 #define RTC_NORMAL(fmt)
01045 #define RTC_INFO(fmt)
01046 #define RTC_DEBUG(fmt)
01047 #define RTC_TRACE(fmt)
01048 #define RTC_VERBOSE(fmt)
01049 #define RTC_PARANOID(fmt)
01050 #endif
01051
01052 };
01053
01054 #endif // RtcSystemLogger_h