coil/common/Logger.h
Go to the documentation of this file.
1 // -*- C++ -*-
20 #ifndef LOGGER_H
21 #define LOGGER_H
22 
23 #include <limits.h>
24 #include <iostream>
25 #include <fstream>
26 #include <vector>
27 #include <string>
28 
29 #include <coil/Mutex.h>
30 #include <coil/Guard.h>
31 
32 #ifndef LINE_MAX
33 #define LINE_MAX 1024
34 #endif
35 
36 #define BUFFER_LEN LINE_MAX
37 
38 namespace coil
39 {
53  template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
55  : public ::std::basic_streambuf<_CharT, _Traits>
56  {
57  public:
58  typedef _CharT char_type;
59  typedef _Traits traits_type;
60  typedef std::basic_streambuf<char_type, traits_type> streambuf_type;
61  typedef coil::Mutex Mutex;
63 
80  : streambuf_type()
81  {
82  char *pStart = m_buf;
83  char *pEnd = m_buf + (BUFFER_LEN - 1);
84  this->setp(pStart, pEnd);
85  this->setg(pStart, pStart, pEnd);
86  }
87 
103  virtual ~log_streambuf()
104  {
105  }
106 
136  void addStream(streambuf_type* stream, bool cleanup = false)
137  {
138  m_streams.push_back(Stream(stream, cleanup));
139  }
140 
163  bool removeStream(streambuf_type* stream)
164  {
165  std::vector<coil::log_streambuf<char>::Stream>::iterator it;
166  for( it = m_streams.begin(); it != m_streams.end(); it++ )
167  {
168  if (it->stream_ == stream)
169  {
170  m_streams.erase(it);
171  return true;
172  }
173  }
174  return false;
175  }
176 
196  std::vector<streambuf_type*> getBuffers()
197  {
198  std::vector<streambuf_type*> buffs;
199  for (int i(0), len(m_streams.size()); i < len; ++i)
200  {
201  buffs.push_back(m_streams[i].stream_);
202  }
203  return buffs;
204  }
205 
206  protected:
226  virtual std::streamsize xsputn(const char_type* s, std::streamsize n)
227  {
228  stream_sputn();
229  for (int i(0), len(m_streams.size()); i < len; ++i)
230  {
231  Guard gaurd(m_streams[i].mutex_);
232  m_streams[i].stream_->sputn(s, n);
233  }
234  return n;
235  }
236 
252  virtual std::streamsize stream_sputn()
253  {
254  int bytes_to_write;
255  bytes_to_write = this->pptr() - this->gptr();
256  if (bytes_to_write > 0)
257  {
258  for (int i(0), len(m_streams.size()); i < len; ++i)
259  {
260  Guard gaurd(m_streams[i].mutex_);
261  m_streams[i].stream_->sputn(this->gptr(), bytes_to_write);
262  }
263  this->gbump(bytes_to_write);
264  if (this->gptr() >= this->pptr())
265  {
266  this->pbump(this->pbase() - this->pptr());
267  this->gbump(this->pbase() - this->gptr());
268  }
269  }
270  return bytes_to_write;
271  }
272 
293  virtual std::streamsize stream_sputn(const char_type* s, std::streamsize n)
294  {
295 
296  for (int i(0), len(m_streams.size()); i < len; ++i)
297  {
298  Guard gaurd(m_streams[i].mutex_);
299  m_streams[i].stream_->sputn(s, n);
300  m_streams[i].stream_->pubsync();
301  }
302  return n;
303  }
322  virtual int overflow (int c = traits_type::eof())
323  {
324  Guard guard(m_mutex);
325 // if (traits_type::eq_int_type(c, traits_type::eof()))
326 // return c;
327 //
328 // char_type last_char = traits_type::to_char_type(c);
329 // if (sputn(&last_char, 1) != 1)
330 // return traits_type::eof();
331 // else
332 // return c;
333 
334  if (this->pbase())
335  {
336  if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
337  return traits_type::eof();
338  // Add extra character to buffer if not EOF
339  if (!traits_type::eq_int_type(c, traits_type::eof()))
340  {
341  this->pbump(-1);
342  *(this->pptr()) = traits_type::to_char_type(c);
343  this->pbump(1);
344  }
345  // Number of characters to write to file
346  int bytes_to_write = this->pptr() - this->gptr();
347  // Overflow doesn't fail if nothing is to be written
348  if (bytes_to_write > 0)
349  {
350  if (stream_sputn(this->gptr(), bytes_to_write) != bytes_to_write)
351  return traits_type::eof();
352  // Reset next pointer to point to pbase on success
353  this->pbump(this->pbase() - this->pptr());
354  this->gbump(this->pbase() - this->gptr());
355  }
356  }
357  // Write extra character to file if not EOF
358  else if (!traits_type::eq_int_type(c, traits_type::eof()))
359  {
360  // Impromptu char buffer (allows "unbuffered" output)
361  char_type last_char = traits_type::to_char_type(c);
362  // If gzipped file won't accept this character, fail
363  if (stream_sputn(&last_char, 1) != 1)
364  return traits_type::eof();
365  }
366  // If you got here, you have succeeded (even if c was EOF)
367  // The return value should therefore be non-EOF
368  if (traits_type::eq_int_type(c, traits_type::eof()))
369  return traits_type::not_eof(c);
370  else
371  return c;
372  }
373 
389  virtual int sync()
390  {
391  if (this->pbase())
392  {
393  Guard guard(m_mutex);
394  if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
395  return -1;
396 
397  int bytes_to_write;
398  bytes_to_write = this->pptr() - this->gptr();
399  if (bytes_to_write > 0)
400  {
401  if (stream_sputn(this->gptr(), bytes_to_write) != bytes_to_write)
402  {
403  return -1;
404  }
405  this->gbump(bytes_to_write);
406  if (this->gptr() >= this->pptr())
407  {
408  this->pbump(this->pbase() - this->pptr());
409  this->gbump(this->pbase() - this->gptr());
410  }
411  }
412  }
413  else
414  {
415  this->overflow();
416  }
417  return 0;
418  }
419 
420  public:
421 
433  struct Stream
434  {
435  Stream(streambuf_type* stream, bool cleanup = false)
436  : stream_(stream), cleanup_(cleanup)
437  {
438  }
439 
440  virtual ~Stream()
441  {
442  }
443 
444  Stream(const Stream& x)
445  : stream_(x.stream_)
446  {
447  }
448 
450  {
451  Stream tmp(x);
452  tmp.swap(*this);
453  return *this;
454  }
455 
456  void swap(Stream& x)
457  {
458  streambuf_type* stream = x.stream_;
459  bool cleanup = x.cleanup_;
460 
461  x.stream_ = this->stream_;
462  x.cleanup_ = this->cleanup_;
463 
464  this->stream_ = stream;
465  this->cleanup_ = cleanup;
466  }
467  mutable Mutex mutex_;
468  streambuf_type* stream_;
469  bool cleanup_;
470  };
471 
472  private:
473 
493  log_streambuf(const log_streambuf& x);
494 
519 
520  std::vector<Stream> m_streams;
521  Mutex m_mutex;
523  };
524 
525 
539  template <typename _CharT, typename _Traits=std::char_traits<_CharT> >
541  : public std::basic_ostream<_CharT, _Traits>
542  {
543  public:
544  // Types:
545  typedef _CharT char_type;
546  typedef _Traits traits_type;
547  typedef std::basic_ostream<char_type, traits_type> ostream_type;
548  typedef std::basic_streambuf<char_type, traits_type> streambuf_type;
551 
577  log_stream(streambuf_type* sb, int levelmin, int levelmax, int level)
578  : ostream_type(sb),
579  m_minLevel(levelmin), m_maxLevel(levelmax), m_logLevel(level)
580  {
581  if (m_minLevel >= m_maxLevel) throw std::bad_alloc();
582  this->init(sb);
583  }
584 
603  virtual void header(int level)
604  {
605  return;
606  }
607 
627  bool setLevel(int level)
628  {
629  if (m_minLevel <= level && level <= m_maxLevel)
630  {
631  m_logLevel = level;
632  return true;
633  }
634  return false;
635  }
636 
656  int getLevel() const
657  {
658  return m_logLevel;
659  }
660 
676  void enableLock()
677  {
678  m_lockEnable = true;
679  }
680 
696  void disableLock()
697  {
698  m_lockEnable = false;
699  }
700 
732  ostream_type& level(int level)
733  {
734  if (m_minLevel <= level && level <= m_logLevel)
735  {
736  header(level);
737  return *this;
738  }
739  else
740  {
741  return m_dummy;
742  }
743  }
744 
769  bool isValid(int level) const
770  {
771  return m_minLevel <= level && level <= m_logLevel;
772  }
773 
787  inline void lock()
788  {
789  if (m_lockEnable) m_mutex.lock();
790  }
791 
805  inline void unlock()
806  {
807  if (m_lockEnable) m_mutex.unlock();
808  }
809 
810 
811  protected:
812 
829 
845  log_stream();
846 
866  log_stream(const log_stream& x);
867 
891  log_stream& operator=(const log_stream& x);
892 
893  private:
894  int m_minLevel, m_maxLevel;
896 
904  std::ofstream m_dummy;
905  public:
906 
914  static bool m_lockEnable;
915 
923  static Mutex m_mutex;
924  };
925 
926  template <typename _CharT, typename _Traits >
928 
929  template <typename _CharT, typename _Traits >
931 
934 
935 };
936 #endif // LOGGER_H
log_streambuf template class
Mutex class.
virtual int sync()
override of basic_streambuf::sync
static Mutex m_mutex
Mutual exclusion object.
Structure for stream management.
coil::Guard< Mutex > Guard
log_stream(streambuf_type *sb, int levelmin, int levelmax, int level)
Constructor.
log_streambuf()
Constructor.
log_stream< char > LogStream
Stream(streambuf_type *stream, bool cleanup=false)
virtual std::streamsize stream_sputn(const char_type *s, std::streamsize n)
Writes up to n characters from the array pointed by s to the output sequence controlled by the stream...
#define BUFFER_LEN
std::vector< streambuf_type * > getBuffers()
Get stream buffer list.
virtual std::streamsize stream_sputn()
Write the stream buffer in stream.
coil::Guard< coil::Mutex > Guard
void addStream(streambuf_type *stream, bool cleanup=false)
Destructor.
virtual ~log_streambuf()
Destructor.
log_stream template class
std::vector< Stream > m_streams
virtual std::streamsize xsputn(const char_type *s, std::streamsize n)
override of basic_streambuf::xsputn
Stream & operator=(const Stream &x)
char m_buf[BUFFER_LEN]
void enableLock()
Enable the lock mode.
bool setLevel(int level)
Set the log level.
std::basic_streambuf< char_type, traits_type > streambuf_type
log_streambuf< char > LogStreamBuffer
ostream_type & level(int level)
Acquire log stream.
std::basic_streambuf< char_type, traits_type > streambuf_type
bool isValid(int level) const
Log level effective check.
virtual int overflow(int c=traits_type::eof())
override of basic_streambuf::overflow
std::basic_ostream< char_type, traits_type > ostream_type
void lock()
Acquire log lock Acquire log lock when the lock mode is set.
virtual void header(int level)
Message header appender function.
std::ofstream m_dummy
Dummy log.
static bool m_lockEnable
Lock enable mode.
int getLevel() const
Get the log level.
void disableLock()
Disable the lock mode.
void unlock()
Release the log lock Release the log lock when the lock mode is set.
bool removeStream(streambuf_type *stream)
Destructor.
~log_stream()
Destructor.
Common Object Interface Layer.


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Mon Feb 28 2022 23:00:43