libzypp  17.25.2
LogControl.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <fstream>
14 #include <string>
15 #include <mutex>
16 
17 #include <zypp/base/Logger.h>
18 #include <zypp/base/LogControl.h>
20 #include <zypp/base/String.h>
21 #include <zypp/Date.h>
22 #include <zypp/PathInfo.h>
23 #include <zypp/AutoDispose.h>
24 
25 #include <zypp/zyppng/io/Socket>
26 #include <zypp/zyppng/io/SockAddr>
27 #include <zypp/zyppng/base/EventLoop>
28 #include <zypp/zyppng/base/EventDispatcher>
29 #include <zypp/zyppng/base/Timer>
30 #include <zypp/zyppng/base/private/linuxhelpers_p.h>
31 #include <zypp/zyppng/thread/Wakeup>
32 #include <zypp/zyppng/base/private/threaddata_p.h>
33 #include <zypp/zyppng/base/SocketNotifier>
34 
35 #include <thread>
36 #include <variant>
37 #include <atomic>
38 #include <csignal>
39 
40 using std::endl;
41 
42 std::once_flag flagReadEnvAutomatically;
43 
44 namespace zypp
45 {
46 
47  template<class> inline constexpr bool always_false_v = false;
48 
53  class SpinLock {
54  public:
55  void lock () {
56  // acquire lock
57  while ( _atomicLock.test_and_set())
58  // reschedule the current thread while we wait, maybe when its our next turn the lock is free again
59  std::this_thread::yield();
60  }
61 
62  void unlock() {
63  _atomicLock.clear();
64  }
65 
66  private:
67  // we use a lock free atomic flag here so this lock can be safely obtained in a signal handler as well
68  std::atomic_flag _atomicLock = ATOMIC_FLAG_INIT;
69  };
70 
71  class LogThread
72  {
73 
74  public:
75 
77  stop();
78  }
79 
80  static LogThread &instance () {
81  static LogThread t;
82  return t;
83  }
84 
85  void setLineWriter ( boost::shared_ptr<log::LineWriter> writer ) {
86  std::lock_guard lk( _lineWriterLock );
87  _lineWriter = writer;
88  }
89 
90  boost::shared_ptr<log::LineWriter> getLineWriter () {
91  std::lock_guard lk( _lineWriterLock );
92  auto lw = _lineWriter;
93  return lw;
94  }
95 
96  void stop () {
97  _stopSignal.notify();
98  if ( _thread.get_id() != std::this_thread::get_id() )
99  _thread.join();
100  }
101 
102  std::thread::id threadId () {
103  return _thread.get_id();
104  }
105 
106  static std::string sockPath () {
107  static std::string path = zypp::str::Format("zypp-logsocket-%1%") % getpid();
108  return path;
109  }
110 
111  private:
112 
114  {
115  _thread = std::thread( [this] () {
116  workerMain();
117  });
118  }
119 
120  void workerMain () {
121 
122  // force the kernel to pick another thread to handle those signals
123  zyppng::blockSignalsForCurrentThread( { SIGTERM, SIGINT, SIGPIPE, } );
124 
125  zyppng::ThreadData::current().setName("Zypp-Log");
126 
127  auto ev = zyppng::EventLoop::create();
128  auto server = zyppng::Socket::create( AF_UNIX, SOCK_STREAM, 0 );
129  auto stopNotifyWatch = _stopSignal.makeNotifier( );
130 
131  std::vector<zyppng::Socket::Ptr> clients;
132 
133  // bind to a abstract unix domain socket address, which means we do not need to care about cleaning it up
134  server->bind( std::make_shared<zyppng::UnixSockAddr>( sockPath(), true ) );
135  server->listen();
136 
137  // wait for incoming connections from other threads
138  server->sigIncomingConnection().connect( [&](){
139 
140  auto cl = server->accept();
141  if ( !cl ) return;
142  clients.push_back( cl );
143 
144  // wait until data is available, we operate line by line so we only
145  // log a string once we encounter \n
146  cl->sigReadyRead().connect( [ this, sock = cl.get() ](){
147  auto writer = getLineWriter();
148  if ( !writer ) return;
149  while ( sock->canReadLine() ) {
150  auto br = sock->readLine();
151  writer->writeOut( std::string( br.data(), br.size() - 1 ) );
152  }
153  });
154 
155  // once a client disconnects we remove it from the std::vector so that the socket is not leaked
156  cl->sigDisconnected().connect( [&clients, &ev, sock = cl.get()](){
157  auto idx = std::find_if( clients.begin(), clients.end(), [sock]( const auto &s ){ return sock == s.get(); } );
158  ev->eventDispatcher()->unrefLater( *idx );
159  clients.erase( idx );
160  });
161 
162  });
163 
164  stopNotifyWatch->sigActivated().connect( [&ev]( const auto &, auto ) {
165  ev->quit();
166  });
167 
168  ev->run();
169 
170  // make sure we have written everything
171  auto writer = getLineWriter();
172  if ( writer ) {
173  for ( auto &sock : clients ){
174  while ( sock->canReadLine() ) {
175  auto br = sock->readLine();
176  writer->writeOut( std::string( br.data(), br.size() - 1 ) );
177  }
178  }
179  }
180  }
181 
182  private:
183  std::thread _thread;
184  zyppng::Wakeup _stopSignal;
185 
186  // since the public API uses boost::shared_ptr we can not use the atomic
187  // functionalities provided in std.
188  // this lock type can be used safely in signals
190  // boost shared_ptr has a lock free implementation of reference counting so it can be used from signal handlers as well
191  boost::shared_ptr<log::LineWriter> _lineWriter{ nullptr };
192  };
193 
194  class LogClient
195  {
196  public:
198  // make sure the thread is running
200  }
201 
203  ::close( _sockFD );
204  }
205 
211  if ( _sockFD >= 0 )
212  return true;
213 
214  _sockFD = ::socket( AF_UNIX, SOCK_STREAM, 0 );
215  if ( _sockFD == -1 )
216  return false;
217 
218  zyppng::UnixSockAddr addr( LogThread::sockPath(), true );
219  return zyppng::trySocketConnection( _sockFD, addr, 100 );
220  }
221 
225  void pushMessage ( std::string &&msg ) {
226  if ( inPushMessage ) {
227  return;
228  }
229 
230  // make sure we do not end up in a busy loop
231  zypp::AutoDispose<bool *> res( &inPushMessage, [](auto val){
232  *val = false;
233  });
234  inPushMessage = true;
235 
236  // if we are in the same thread as the Log worker we can directly push our messages out, no need to use the socket
237  if ( std::this_thread::get_id() == LogThread::instance().threadId() ) {
238  auto writer = LogThread::instance().getLineWriter();
239  writer->writeOut( msg );
240  return;
241  }
242 
243  if(!ensureConnection())
244  return;
245 
246  if ( msg.back() != '\n' )
247  msg.push_back('\n');
248 
249  size_t written = 0;
250  while ( written < msg.size() ) {
251  const auto res = zyppng::eintrSafeCall( ::send, _sockFD, msg.data() + written, msg.size() - written, MSG_NOSIGNAL );
252  if ( res == -1 ) {
253  //assume broken socket
254  ::close( _sockFD );
255  _sockFD = -1;
256  return;
257  }
258  written += res;
259  }
260  }
261 
262  private:
263  int _sockFD = -1;
264  bool inPushMessage = false;
265  };
266 
267 #ifndef ZYPP_NDEBUG
268  namespace debug
269  {
270  void osdlog( const std::string & msg_r, unsigned level_r )
271  {
272  // Fg::Black: 30 Bg: 40 Attr::Normal: 22;27
273  // Fg::Red: 31 ... Attr::Bright: 1
274  // Fg::Green: 32 Attr::Reverse: 7
275  // Fg::Yellow: 33
276  // Fg::Blue: 34
277  // Fg::Magenta: 35
278  // Fg::Cyan: 36
279  // Fg::White: 37
280  // Fg::Default: 39
281  static const char * ansi[] = {
282  "\033[37;40m", // 0 w
283  "\033[36;40m", // 1 c
284  "\033[33;1;40m", // 2 y
285  "\033[32;40m", // 3 g
286  "\033[31;1;40m", // 4 r
287  "\033[35;40m", // 5 m
288  };
289  static const unsigned n = sizeof(ansi)/sizeof(const char *);
290  switch ( level_r )
291  {
292  case 'w': level_r = 0; break;
293  case 'c': level_r = 1; break;
294  case 'y': level_r = 2; break;
295  case 'g': level_r = 3; break;
296  case 'r': level_r = 4; break;
297  case 'm': level_r = 5; break;
298  }
299  std::cerr << ansi[level_r%n] << "OSD[" << msg_r << "]\033[0m" << std::endl;
300  }
301 
302 
303  unsigned TraceLeave::_depth = 0;
304 
305  TraceLeave::TraceLeave( const char * file_r, const char * fnc_r, int line_r )
306  : _file( std::move(file_r) )
307  , _fnc( std::move(fnc_r) )
308  , _line( line_r )
309  {
310  //std::string::size_type p( _file.find_last_of( '/' ) );
311  //if ( p != std::string::npos )
312  //_file.erase( 0, p+1 );
313  USR << ">>> " << std::string(_depth++,'>') << " " << _file << "(" << _fnc << "):" << _line << endl;
314  }
315 
317  { USR << "<<< " << std::string(--_depth,'<') << " " << _file << "(" << _fnc << "):" << _line << endl; }
318 }
319 #endif // ZYPP_NDEBUG
320 
322  namespace log
323  {
324 
326  : StreamLineWriter( std::cout )
327  {}
328 
330  : StreamLineWriter( std::cerr )
331  {}
332 
333  FileLineWriter::FileLineWriter( const Pathname & file_r, mode_t mode_r )
334  {
335  if ( file_r == Pathname("-") )
336  {
337  _str = &std::cerr;
338  }
339  else
340  {
341  if ( mode_r )
342  {
343  // not filesystem::assert_file as filesystem:: functions log,
344  // and this FileWriter is not yet in place.
345  int fd = ::open( file_r.c_str(), O_CREAT|O_EXCL, mode_r );
346  if ( fd != -1 )
347  ::close( fd );
348  }
349  // set unbuffered write
350  std::ofstream * fstr = 0;
351  _outs.reset( (fstr = new std::ofstream( file_r.asString().c_str(), std::ios_base::app )) );
352  fstr->rdbuf()->pubsetbuf(0,0);
353  _str = &(*fstr);
354  }
355  }
356 
358  } // namespace log
360 
362  namespace base
363  {
364 
366  // LineFormater
368  std::string LogControl::LineFormater::format( const std::string & group_r,
369  logger::LogLevel level_r,
370  const char * file_r,
371  const char * func_r,
372  int line_r,
373  const std::string & message_r )
374  {
375  static char hostname[1024];
376  static char nohostname[] = "unknown";
377  std::string now( Date::now().form( "%Y-%m-%d %H:%M:%S" ) );
378 
379  return str::form( "%s <%d> %s(%d) [Thread: %s] [%s] %s(%s):%d %s",
380  now.c_str(), level_r,
381  ( gethostname( hostname, 1024 ) ? nohostname : hostname ),
382  getpid(),
383  zyppng::ThreadData::current().name().c_str(),
384  group_r.c_str(),
385  file_r, func_r, line_r,
386  message_r.c_str() );
387  }
388 
390  namespace logger
391  {
392 
393  inline void putStream( const std::string & group_r, LogLevel level_r,
394  const char * file_r, const char * func_r, int line_r,
395  const std::string & buffer_r );
396 
398  //
399  // CLASS NAME : Loglinebuf
400  //
401  class Loglinebuf : public std::streambuf {
402 
403  public:
405  Loglinebuf( const std::string & group_r, LogLevel level_r )
406  : _group( group_r )
407  , _level( level_r )
408  , _file( "" )
409  , _func( "" )
410  , _line( -1 )
411  {}
414  {
415  if ( !_buffer.empty() )
416  writeout( "\n", 1 );
417  }
418 
420  void tagSet( const char * fil_r, const char * fnc_r, int lne_r )
421  {
422  _file = fil_r;
423  _func = fnc_r;
424  _line = lne_r;
425  }
426 
427  private:
429  virtual std::streamsize xsputn( const char * s, std::streamsize n )
430  { return writeout( s, n ); }
432  virtual int overflow( int ch = EOF )
433  {
434  if ( ch != EOF )
435  {
436  char tmp = ch;
437  writeout( &tmp, 1 );
438  }
439  return 0;
440  }
442  virtual int writeout( const char* s, std::streamsize n )
443  {
444  //logger::putStream( _group, _level, _file, _func, _line, _buffer );
445  //return n;
446  if ( s && n )
447  {
448  const char * c = s;
449  for ( int i = 0; i < n; ++i, ++c )
450  {
451  if ( *c == '\n' ) {
452  _buffer += std::string( s, c-s );
453  logger::putStream( _group, _level, _file, _func, _line, _buffer );
454  _buffer = std::string();
455  s = c+1;
456  }
457  }
458  if ( s < c )
459  {
460  _buffer += std::string( s, c-s );
461  }
462  }
463  return n;
464  }
465 
466  private:
467  std::string _group;
469  const char * _file;
470  const char * _func;
471  int _line;
472  std::string _buffer;
473  };
474 
476 
478  //
479  // CLASS NAME : Loglinestream
480  //
482 
483  public:
485  Loglinestream( const std::string & group_r, LogLevel level_r )
486  : _mybuf( group_r, level_r )
487  , _mystream( &_mybuf )
488  {}
491  { _mystream.flush(); }
492 
493  public:
495  std::ostream & getStream( const char * fil_r, const char * fnc_r, int lne_r )
496  {
497  _mybuf.tagSet( fil_r, fnc_r, lne_r );
498  return _mystream;
499  }
500 
501  private:
503  std::ostream _mystream;
504  };
506 
507  struct LogControlImpl;
508 
509  /*
510  * Horrible ugly hack to prevent the use of LogControlImpl when libzypp is shutting down.
511  * Due to the c++ std thread_local static instances are cleaned up before the first global static
512  * destructor is called. So all classes that use logging after that point in time would crash the
513  * application because its accessing a variable that has already been destroyed.
514  *
515  * This does not check if the current thread requesting a instance actually has one, it just keeps count
516  * of how many instances are still available. Usually only the main thread should run into the condition
517  * of getting a nullptr back.
518  */
519  static std::atomic_int & logControlImplReg() {
520  static std::atomic_int instCount;
521  return instCount;
522  }
523 
525  //
526  // CLASS NAME : LogControlImpl
527  //
538  {
539  public:
540  bool isExcessive()
541  { return _excessive; }
542 
543  void excessive( bool onOff_r )
544  { _excessive = onOff_r; }
545 
547  void setLineWriter( const shared_ptr<LogControl::LineWriter> & writer_r )
548  { LogThread::instance().setLineWriter( writer_r ); }
549 
550  shared_ptr<LogControl::LineWriter> getLineWriter() const
551  { return LogThread::instance().getLineWriter(); }
552 
554  void setLineFormater( const shared_ptr<LogControl::LineFormater> & format_r )
555  {
556  if ( format_r )
557  _lineFormater = format_r;
558  else
559  _lineFormater.reset( new LogControl::LineFormater );
560  }
561 
562  void logfile( const Pathname & logfile_r, mode_t mode_r = 0640 )
563  {
564  if ( logfile_r.empty() )
565  setLineWriter( shared_ptr<LogControl::LineWriter>() );
566  else if ( logfile_r == Pathname( "-" ) )
567  setLineWriter( shared_ptr<LogControl::LineWriter>(new log::StderrLineWriter) );
568  else
569  setLineWriter( shared_ptr<LogControl::LineWriter>(new log::FileLineWriter(logfile_r, mode_r)) );
570  }
571 
572  private:
574  std::ostream _no_stream;
576 
577  shared_ptr<LogControl::LineFormater> _lineFormater;
578 
579  public:
581  std::ostream & getStream( const std::string & group_r,
582  LogLevel level_r,
583  const char * file_r,
584  const char * func_r,
585  const int line_r )
586  {
587  if ( ! getLineWriter() )
588  return _no_stream;
589  if ( level_r == E_XXX && !_excessive )
590  return _no_stream;
591 
592  if ( !_streamtable[group_r][level_r] )
593  {
594  _streamtable[group_r][level_r].reset( new Loglinestream( group_r, level_r ) );
595  }
596  std::ostream & ret( _streamtable[group_r][level_r]->getStream( file_r, func_r, line_r ) );
597  if ( !ret )
598  {
599  ret.clear();
600  ret << "---<RESET LOGSTREAM FROM FAILED STATE]" << endl;
601  }
602  return ret;
603  }
604 
606  void putStream( const std::string & group_r,
607  LogLevel level_r,
608  const char * file_r,
609  const char * func_r,
610  int line_r,
611  const std::string & message_r )
612  {
613  _logClient.pushMessage( _lineFormater->format( group_r, level_r,
614  file_r, func_r, line_r,
615  message_r ) );
616  }
617 
618  private:
619  typedef shared_ptr<Loglinestream> StreamPtr;
620  typedef std::map<LogLevel,StreamPtr> StreamSet;
621  typedef std::map<std::string,StreamSet> StreamTable;
624  zyppng::Socket::Ptr _sock;
625 
626  private:
627 
628  void readEnvVars () {
629  if ( getenv("ZYPP_LOGFILE") )
630  logfile( getenv("ZYPP_LOGFILE") );
631 
632  if ( getenv("ZYPP_PROFILING") )
633  {
634  shared_ptr<LogControl::LineFormater> formater(new ProfilingFormater);
635  setLineFormater(formater);
636  }
637  }
642  : _no_stream( NULL )
643  , _excessive( getenv("ZYPP_FULLLOG") )
644  , _lineFormater( new LogControl::LineFormater )
645  {
646  logControlImplReg().fetch_add(1);
647  std::call_once( flagReadEnvAutomatically, &LogControlImpl::readEnvVars, this);
648  }
649 
650  public:
651 
653  {
654  logControlImplReg().fetch_sub(1);
655  }
656 
663  static LogControlImpl *instance();
664  };
666 
667  // 'THE' LogControlImpl singleton
669  {
670  thread_local static LogControlImpl _instance;
671  if ( logControlImplReg().load() > 0 )
672  return &_instance;
673  return nullptr;
674  }
675 
677 
679  inline std::ostream & operator<<( std::ostream & str, const LogControlImpl & obj )
680  {
681  return str << "LogControlImpl";
682  }
683 
685  //
686  // Access from logger::
687  //
689 
690  std::ostream & getStream( const char * group_r,
691  LogLevel level_r,
692  const char * file_r,
693  const char * func_r,
694  const int line_r )
695  {
696  static std::ostream nstream(NULL);
697  auto control = LogControlImpl::instance();
698  if ( !control ) {
699  return nstream;
700  }
701 
702 
703 
704  return control->getStream( group_r,
705  level_r,
706  file_r,
707  func_r,
708  line_r );
709  }
710 
712  inline void putStream( const std::string & group_r, LogLevel level_r,
713  const char * file_r, const char * func_r, int line_r,
714  const std::string & buffer_r )
715  {
716  auto control = LogControlImpl::instance();
717  if ( !control )
718  return;
719 
720  control->putStream( group_r, level_r,
721  file_r, func_r, line_r,
722  buffer_r );
723  }
724 
725  bool isExcessive()
726  {
727  auto impl = LogControlImpl::instance();
728  if ( !impl )
729  return false;
730  return impl->isExcessive();
731  }
732 
734  } // namespace logger
736 
738  //
739  // CLASS NAME : LogControl
740  // Forward to LogControlImpl singleton.
741  //
743 
744  using logger::LogControlImpl;
745 
746  void LogControl::logfile( const Pathname & logfile_r )
747  {
748  auto impl = LogControlImpl::instance();
749  if ( !impl )
750  return;
751 
752  impl->logfile( logfile_r );
753  }
754 
755  void LogControl::logfile( const Pathname & logfile_r, mode_t mode_r )
756  {
757  auto impl = LogControlImpl::instance();
758  if ( !impl )
759  return;
760 
761  impl->logfile( logfile_r, mode_r );
762  }
763 
764  shared_ptr<LogControl::LineWriter> LogControl::getLineWriter() const
765  {
766  auto impl = LogControlImpl::instance();
767  if ( !impl )
768  return nullptr;
769 
770  return impl->getLineWriter();
771  }
772 
773  void LogControl::setLineWriter( const shared_ptr<LineWriter> & writer_r )
774  {
775  auto impl = LogControlImpl::instance();
776  if ( !impl )
777  return;
778  impl->setLineWriter( writer_r );
779  }
780 
781  void LogControl::setLineFormater( const shared_ptr<LineFormater> & formater_r )
782  {
783  auto impl = LogControlImpl::instance();
784  if ( !impl )
785  return;
786  impl->setLineFormater( formater_r );
787  }
788 
790  {
791  auto impl = LogControlImpl::instance();
792  if ( !impl )
793  return;
794  impl->setLineWriter( shared_ptr<LineWriter>() );
795  }
796 
798  {
799  auto impl = LogControlImpl::instance();
800  if ( !impl )
801  return;
802  impl->setLineWriter( shared_ptr<LineWriter>( new log::StderrLineWriter ) );
803  }
804 
806  {
808  }
809 
811  //
812  // LogControl::TmpExcessive
813  //
816  {
817  auto impl = LogControlImpl::instance();
818  if ( !impl )
819  return;
820  impl->excessive( true );
821  }
823  {
824  auto impl = LogControlImpl::instance();
825  if ( !impl )
826  return;
827  impl->excessive( false );
828  }
829 
830  /******************************************************************
831  **
832  ** FUNCTION NAME : operator<<
833  ** FUNCTION TYPE : std::ostream &
834  */
835  std::ostream & operator<<( std::ostream & str, const LogControl & obj )
836  {
837  auto impl = LogControlImpl::instance();
838  if ( !impl )
839  return str;
840  return str << *impl;
841  }
842 
844  } // namespace base
847 } // namespace zypp
std::map< LogLevel, StreamPtr > StreamSet
Definition: LogControl.cc:620
std::atomic_flag _atomicLock
Definition: LogControl.cc:68
LogLevel
Definition of log levels.
Definition: Logger.h:118
constexpr bool always_false_v
Definition: LogControl.cc:47
std::ostream & getStream(const std::string &group_r, LogLevel level_r, const char *file_r, const char *func_r, const int line_r)
Provide the log stream to write (logger interface)
Definition: LogControl.cc:581
Base class for ostream based LineWriter.
Definition: LogControl.h:44
void tagSet(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:420
Loglinestream(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:485
static std::atomic_int & logControlImplReg()
Definition: LogControl.cc:519
const char * c_str() const
String representation.
Definition: Pathname.h:110
String related utilities and Regular expression matching.
Definition: Arch.h:347
LineWriter to file.
Definition: LogControl.h:72
If you want to format loglines by yourself, derive from this, and overload format.
Definition: LogControl.h:114
Convenient building of std::string with boost::format.
Definition: String.h:249
LineWriter to stderr.
Definition: LogControl.h:63
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
void setLineWriter(const shared_ptr< LogControl::LineWriter > &writer_r)
NULL _lineWriter indicates no loggin.
Definition: LogControl.cc:547
static std::string sockPath()
Definition: LogControl.cc:106
void logfile(const Pathname &logfile_r, mode_t mode_r=0640)
Definition: LogControl.cc:562
void logfile(const Pathname &logfile_r)
Set path for the logfile.
Definition: LogControl.cc:746
void osdlog(const std::string &msg_r, unsigned level_r)
Definition: LogControl.cc:270
static LogControl instance()
Singleton access.
Definition: LogControl.h:102
std::ostream & operator<<(std::ostream &str, const LogControlImpl &obj)
Definition: LogControl.cc:679
void setLineWriter(const shared_ptr< LineWriter > &writer_r)
Assign a LineWriter.
Definition: LogControl.cc:773
void logToStdErr()
Log to std::err.
Definition: LogControl.cc:797
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
const char * _fnc
Definition: Logger.h:39
TraceLeave(const TraceLeave &)=delete
std::thread::id threadId()
Definition: LogControl.cc:102
const std::string & _buffer
Definition: PluginScript.cc:62
shared_ptr< LogControl::LineWriter > getLineWriter() const
Definition: LogControl.cc:550
zyppng::Wakeup _stopSignal
Definition: LogControl.cc:184
const std::string & asString() const
String representation.
Definition: Pathname.h:91
friend std::ostream & operator<<(std::ostream &str, const LogControl &obj)
Definition: LogControl.cc:835
#define USR
Definition: Logger.h:84
virtual int overflow(int ch=EOF)
Definition: LogControl.cc:432
void setLineFormater(const shared_ptr< LogControl::LineFormater > &format_r)
Assert _lineFormater is not NULL.
Definition: LogControl.cc:554
shared_ptr< LogControl::LineFormater > _lineFormater
Definition: LogControl.cc:577
std::ostream & getStream(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:495
static LogControlImpl * instance()
The LogControlImpl singleton.
Definition: LogControl.cc:668
std::thread _thread
Definition: LogControl.cc:183
boost::shared_ptr< log::LineWriter > _lineWriter
Definition: LogControl.cc:191
boost::shared_ptr< log::LineWriter > getLineWriter()
Definition: LogControl.cc:90
std::once_flag flagReadEnvAutomatically
Definition: LogControl.cc:42
std::map< std::string, StreamSet > StreamTable
Definition: LogControl.cc:621
static unsigned _depth
Definition: Logger.h:37
void logNothing()
Turn off logging.
Definition: LogControl.cc:789
void setLineWriter(boost::shared_ptr< log::LineWriter > writer)
Definition: LogControl.cc:85
virtual std::string format(const std::string &, logger::LogLevel, const char *, const char *, int, const std::string &)
Definition: LogControl.cc:368
Maintain logfile related options.
Definition: LogControl.h:96
virtual int writeout(const char *s, std::streamsize n)
Definition: LogControl.cc:442
void putStream(const std::string &group_r, LogLevel level_r, const char *file_r, const char *func_r, int line_r, const std::string &buffer_r)
That&#39;s what Loglinebuf calls.
Definition: LogControl.cc:712
static Date now()
Return the current time.
Definition: Date.h:78
void putStream(const std::string &group_r, LogLevel level_r, const char *file_r, const char *func_r, int line_r, const std::string &message_r)
Format and write out a logline from Loglinebuf.
Definition: LogControl.cc:606
virtual std::streamsize xsputn(const char *s, std::streamsize n)
Definition: LogControl.cc:429
bool ensureConnection()
Definition: LogControl.cc:210
shared_ptr< LineWriter > getLineWriter() const
Get the current LineWriter.
Definition: LogControl.cc:764
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:92
SpinLock _lineWriterLock
Definition: LogControl.cc:189
Loglinebuf(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:405
Pathname _file
Definition: SystemCheck.cc:34
void setLineFormater(const shared_ptr< LineFormater > &formater_r)
Assign a LineFormater.
Definition: LogControl.cc:781
shared_ptr< void > _outs
Definition: LogControl.h:76
shared_ptr< Loglinestream > StreamPtr
Definition: LogControl.cc:619
const char * _file
Definition: Logger.h:38
void pushMessage(std::string &&msg)
Definition: LogControl.cc:225
Excessive logging.
Definition: Logger.h:119
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
void emergencyShutdown()
will cause the log thread to exit and flush all sockets
Definition: LogControl.cc:805
std::ostream & getStream(const char *group_r, LogLevel level_r, const char *file_r, const char *func_r, const int line_r)
Return a log stream to write on.
Definition: LogControl.cc:690
static LogThread & instance()
Definition: LogControl.cc:80
LogControl implementation (Singleton).
Definition: LogControl.cc:537
FileLineWriter(const Pathname &file_r, mode_t mode_r=0)
Definition: LogControl.cc:333
StreamTable _streamtable
one streambuffer per group and level
Definition: LogControl.cc:623