libzypp  17.28.8
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 #include <map>
17 
18 #include <zypp-core/base/Logger.h>
19 #include <zypp-core/base/LogControl.h>
20 #include <zypp-core/base/ProfilingFormater.h>
21 #include <zypp-core/base/String.h>
22 #include <zypp-core/Date.h>
23 #include <zypp-core/TriBool.h>
24 #include <zypp-core/AutoDispose.h>
25 
26 #include <zypp-core/zyppng/io/Socket>
27 #include <zypp-core/zyppng/io/SockAddr>
28 #include <zypp-core/zyppng/base/EventLoop>
29 #include <zypp-core/zyppng/base/EventDispatcher>
30 #include <zypp-core/zyppng/base/Timer>
31 #include <zypp-core/zyppng/base/private/linuxhelpers_p.h>
32 #include <zypp-core/zyppng/thread/Wakeup>
33 #include <zypp-core/zyppng/base/private/threaddata_p.h>
34 #include <zypp-core/zyppng/base/SocketNotifier>
35 
36 #include <thread>
37 #include <variant>
38 #include <atomic>
39 #include <csignal>
40 
41 extern "C"
42 {
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 #include <dirent.h>
48 }
49 
50 using std::endl;
51 
52 std::once_flag flagReadEnvAutomatically;
53 
54 namespace zypp
55 {
56  constexpr std::string_view ZYPP_MAIN_THREAD_NAME( "Zypp-main" );
57 
58  template<class> inline constexpr bool always_false_v = false;
59 
64  class SpinLock {
65  public:
66  void lock () {
67  // acquire lock
68  while ( _atomicLock.test_and_set())
69  // reschedule the current thread while we wait, maybe when its our next turn the lock is free again
70  std::this_thread::yield();
71  }
72 
73  void unlock() {
74  _atomicLock.clear();
75  }
76 
77  private:
78  // we use a lock free atomic flag here so this lock can be safely obtained in a signal handler as well
79  std::atomic_flag _atomicLock = ATOMIC_FLAG_INIT;
80  };
81 
82  class LogThread
83  {
84 
85  public:
86 
88  stop();
89  }
90 
91  static LogThread &instance () {
92  static LogThread t;
93  return t;
94  }
95 
96  void setLineWriter ( boost::shared_ptr<log::LineWriter> writer ) {
97  std::lock_guard lk( _lineWriterLock );
98  _lineWriter = writer;
99  }
100 
101  boost::shared_ptr<log::LineWriter> getLineWriter () {
102  std::lock_guard lk( _lineWriterLock );
103  auto lw = _lineWriter;
104  return lw;
105  }
106 
107  void stop () {
108  _stopSignal.notify();
109  if ( _thread.get_id() != std::this_thread::get_id() )
110  _thread.join();
111  }
112 
113  std::thread::id threadId () {
114  return _thread.get_id();
115  }
116 
117  static std::string sockPath () {
118  static std::string path = zypp::str::Format("zypp-logsocket-%1%") % getpid();
119  return path;
120  }
121 
122  private:
123 
125  {
126  // Name the thread that started the logger assuming it's main thread.
127  zyppng::ThreadData::current().setName(ZYPP_MAIN_THREAD_NAME);
128  _thread = std::thread( [this] () {
129  workerMain();
130  });
131  }
132 
133  void workerMain () {
134 
135  // force the kernel to pick another thread to handle those signals
136  zyppng::blockSignalsForCurrentThread( { SIGTERM, SIGINT, SIGPIPE, } );
137 
138  zyppng::ThreadData::current().setName("Zypp-Log");
139 
140  auto ev = zyppng::EventLoop::create();
141  auto server = zyppng::Socket::create( AF_UNIX, SOCK_STREAM, 0 );
142  auto stopNotifyWatch = _stopSignal.makeNotifier( );
143 
144  std::vector<zyppng::Socket::Ptr> clients;
145 
146  // bind to a abstract unix domain socket address, which means we do not need to care about cleaning it up
147  server->bind( std::make_shared<zyppng::UnixSockAddr>( sockPath(), true ) );
148  server->listen();
149 
150  // wait for incoming connections from other threads
151  server->connectFunc( &zyppng::Socket::sigIncomingConnection, [&](){
152 
153  auto cl = server->accept();
154  if ( !cl ) return;
155  clients.push_back( cl );
156 
157  // wait until data is available, we operate line by line so we only
158  // log a string once we encounter \n
159  cl->connectFunc( &zyppng::Socket::sigReadyRead, [ this, sock = cl.get() ](){
160  auto writer = getLineWriter();
161  if ( !writer ) return;
162  while ( sock->canReadLine() ) {
163  auto br = sock->readLine();
164  writer->writeOut( std::string( br.data(), br.size() - 1 ) );
165  }
166  }, *cl);
167 
168  // once a client disconnects we remove it from the std::vector so that the socket is not leaked
169  cl->connectFunc( &zyppng::Socket::sigDisconnected, [&clients, sock = std::weak_ptr(cl)](){
170  auto lock = sock.lock();
171  if ( !lock )
172  return;
173 
174  auto idx = std::find_if( clients.begin(), clients.end(), [lock]( const auto &s ){ return lock.get() == s.get(); } );
175  clients.erase( idx );
176  });
177 
178  });
179 
180  stopNotifyWatch->connectFunc( &zyppng::SocketNotifier::sigActivated, [&ev]( const auto &, auto ) {
181  ev->quit();
182  });
183 
184  ev->run();
185 
186  // make sure we have written everything
187  auto writer = getLineWriter();
188  if ( writer ) {
189  for ( auto &sock : clients ){
190  while ( sock->canReadLine() ) {
191  auto br = sock->readLine();
192  writer->writeOut( std::string( br.data(), br.size() - 1 ) );
193  }
194  }
195  }
196  }
197 
198  private:
199  std::thread _thread;
200  zyppng::Wakeup _stopSignal;
201 
202  // since the public API uses boost::shared_ptr we can not use the atomic
203  // functionalities provided in std.
204  // this lock type can be used safely in signals
206  // boost shared_ptr has a lock free implementation of reference counting so it can be used from signal handlers as well
207  boost::shared_ptr<log::LineWriter> _lineWriter{ nullptr };
208  };
209 
210  class LogClient
211  {
212  public:
214  // make sure the thread is running
215  LogThread::instance();
216  }
217 
219  ::close( _sockFD );
220  }
221 
227  if ( _sockFD >= 0 )
228  return true;
229 
230  _sockFD = ::socket( AF_UNIX, SOCK_STREAM, 0 );
231  if ( _sockFD == -1 )
232  return false;
233 
234  zyppng::UnixSockAddr addr( LogThread::sockPath(), true );
235  return zyppng::trySocketConnection( _sockFD, addr, 100 );
236  }
237 
241  void pushMessage ( std::string &&msg ) {
242  if ( inPushMessage ) {
243  return;
244  }
245 
246  // make sure we do not end up in a busy loop
247  zypp::AutoDispose<bool *> res( &inPushMessage, [](auto val){
248  *val = false;
249  });
250  inPushMessage = true;
251 
252  // if we are in the same thread as the Log worker we can directly push our messages out, no need to use the socket
253  if ( std::this_thread::get_id() == LogThread::instance().threadId() ) {
254  auto writer = LogThread::instance().getLineWriter();
255  if ( writer )
256  writer->writeOut( msg );
257  return;
258  }
259 
260  if(!ensureConnection())
261  return;
262 
263  if ( msg.back() != '\n' )
264  msg.push_back('\n');
265 
266  size_t written = 0;
267  while ( written < msg.size() ) {
268  const auto res = zyppng::eintrSafeCall( ::send, _sockFD, msg.data() + written, msg.size() - written, MSG_NOSIGNAL );
269  if ( res == -1 ) {
270  //assume broken socket
271  ::close( _sockFD );
272  _sockFD = -1;
273  return;
274  }
275  written += res;
276  }
277  }
278 
279  private:
280  int _sockFD = -1;
281  bool inPushMessage = false;
282  };
283 
284 #ifndef ZYPP_NDEBUG
285  namespace debug
286  {
287  // Fg::Black: 30 Bg: 40 Attr::Normal: 22;27
288  // Fg::Red: 31 ... Attr::Bright: 1
289  // Fg::Green: 32 Attr::Reverse: 7
290  // Fg::Yellow: 33
291  // Fg::Blue: 34
292  // Fg::Magenta: 35
293  // Fg::Cyan: 36
294  // Fg::White: 37
295  // Fg::Default: 39
296  static constexpr std::string_view OO { "\033[0m" };
297  static constexpr std::string_view WH { "\033[37;40m" };
298  static constexpr std::string_view CY { "\033[36;40m" };
299  static constexpr std::string_view YE { "\033[33;1;40m" };
300  static constexpr std::string_view GR { "\033[32;40m" };
301  static constexpr std::string_view RE { "\033[31;1;40m" };
302  static constexpr std::string_view MA { "\033[35;40m" };
303 
304  unsigned TraceLeave::_depth = 1;
305 
306  std::string tracestr( char tag_r, unsigned depth_r, const char * file_r, const char * fnc_r, int line_r )
307  {
308  static str::Format fmt { "*** %s %s(%s):%d" };
309  fmt % std::string(depth_r,tag_r) % file_r % fnc_r % line_r;
310  return fmt;
311  }
312 
313  TraceLeave::TraceLeave( const char * file_r, const char * fnc_r, int line_r )
314  : _file( std::move(file_r) )
315  , _fnc( std::move(fnc_r) )
316  , _line( line_r )
317  {
318  const std::string & m { tracestr( '>',_depth++, _file,_fnc,_line ) };
319  USR << m << endl;
320  Osd(L_USR("TRACE"),1) << m << endl;
321  }
322 
324  {
325  const std::string & m { tracestr( '<',--_depth, _file,_fnc,_line ) };
326  USR << m << endl;
327  Osd(L_USR("TRACE"),1) << m << endl;
328  }
329 
330  Osd::Osd( std::ostream & str, int i )
331  : _strout { std::cerr }
332  , _strlog { str }
333  { _strout << (i?WH:YE); }
334 
336  { _strout << OO; }
337 
338  Osd & Osd::operator<<( std::ostream& (*iomanip)( std::ostream& ) )
339  {
340  _strout << iomanip;
341  _strlog << iomanip;
342  return *this;
343  }
344 }
345 #endif // ZYPP_NDEBUG
346 
348  namespace log
349  {
350 
352  : StreamLineWriter( std::cout )
353  {}
354 
356  : StreamLineWriter( std::cerr )
357  {}
358 
359  FileLineWriter::FileLineWriter( const Pathname & file_r, mode_t mode_r )
360  {
361  if ( file_r == Pathname("-") )
362  {
363  _str = &std::cerr;
364  }
365  else
366  {
367  if ( mode_r )
368  {
369  // not filesystem::assert_file as filesystem:: functions log,
370  // and this FileWriter is not yet in place.
371  int fd = ::open( file_r.c_str(), O_CREAT|O_EXCL, mode_r );
372  if ( fd != -1 )
373  ::close( fd );
374  }
375  // set unbuffered write
376  std::ofstream * fstr = 0;
377  _outs.reset( (fstr = new std::ofstream( file_r.asString().c_str(), std::ios_base::app )) );
378  fstr->rdbuf()->pubsetbuf(0,0);
379  _str = &(*fstr);
380  }
381  }
382 
384  } // namespace log
386 
388  namespace base
389  {
391  namespace logger
392  {
393 
394  inline void putStream( const std::string & group_r, LogLevel level_r,
395  const char * file_r, const char * func_r, int line_r,
396  const std::string & buffer_r );
397 
399  //
400  // CLASS NAME : Loglinebuf
401  //
402  class Loglinebuf : public std::streambuf {
403 
404  public:
406  Loglinebuf( const std::string & group_r, LogLevel level_r )
407  : _group( group_r )
408  , _level( level_r )
409  , _file( "" )
410  , _func( "" )
411  , _line( -1 )
412  {}
415  {
416  if ( !_buffer.empty() )
417  writeout( "\n", 1 );
418  }
419 
421  void tagSet( const char * fil_r, const char * fnc_r, int lne_r )
422  {
423  _file = fil_r;
424  _func = fnc_r;
425  _line = lne_r;
426  }
427 
428  private:
430  virtual std::streamsize xsputn( const char * s, std::streamsize n )
431  { return writeout( s, n ); }
433  virtual int overflow( int ch = EOF )
434  {
435  if ( ch != EOF )
436  {
437  char tmp = ch;
438  writeout( &tmp, 1 );
439  }
440  return 0;
441  }
443  virtual int writeout( const char* s, std::streamsize n )
444  {
445  //logger::putStream( _group, _level, _file, _func, _line, _buffer );
446  //return n;
447  if ( s && n )
448  {
449  const char * c = s;
450  for ( int i = 0; i < n; ++i, ++c )
451  {
452  if ( *c == '\n' ) {
453  _buffer += std::string( s, c-s );
455  _buffer = std::string();
456  s = c+1;
457  }
458  }
459  if ( s < c )
460  {
461  _buffer += std::string( s, c-s );
462  }
463  }
464  return n;
465  }
466 
467  private:
468  std::string _group;
470  const char * _file;
471  const char * _func;
472  int _line;
473  std::string _buffer;
474  };
475 
477 
479  //
480  // CLASS NAME : Loglinestream
481  //
483 
484  public:
486  Loglinestream( const std::string & group_r, LogLevel level_r )
487  : _mybuf( group_r, level_r )
488  , _mystream( &_mybuf )
489  {}
492  { _mystream.flush(); }
493 
494  public:
496  std::ostream & getStream( const char * fil_r, const char * fnc_r, int lne_r )
497  {
498  _mybuf.tagSet( fil_r, fnc_r, lne_r );
499  return _mystream;
500  }
501 
502  private:
504  std::ostream _mystream;
505  };
507 
508  struct LogControlImpl;
509 
510  /*
511  * Ugly hack to prevent the use of LogControlImpl when libzypp is shutting down.
512  * Due to the c++ std thread_local static instances are cleaned up before the first global static
513  * destructor is called. So all classes that use logging after that point in time would crash the
514  * application because its accessing a variable that has already been destroyed.
515  */
517  // We are using a POD flag that does not have a destructor,
518  // to flag if the thread_local destructors were already executed.
519  // Since TLS data is stored in a segment that is available until the thread ceases to exist it should still be readable
520  // after thread_local c++ destructors were already executed. Or so I hope.
521  static thread_local int logControlValid = 0;
522  return logControlValid;
523  }
524 
526  //
527  // CLASS NAME : LogControlImpl
528  //
539  {
540  public:
541  bool isExcessive() const
542  { return _excessive; }
543 
544  void excessive( bool onOff_r )
545  { _excessive = onOff_r; }
546 
547 
549  bool hideThreadName() const
550  {
551  if ( indeterminate(_hideThreadName) )
552  _hideThreadName = ( zyppng::ThreadData::current().name() == ZYPP_MAIN_THREAD_NAME );
553  return bool(_hideThreadName);
554  }
556  void hideThreadName( bool onOff_r )
557  { _hideThreadName = onOff_r; }
560  {
561  auto impl = LogControlImpl::instance();
562  return impl ? impl->hideThreadName() : false;
563  }
565  static void instanceHideThreadName( bool onOff_r )
566  {
567  auto impl = LogControlImpl::instance();
568  if ( impl ) impl->hideThreadName( onOff_r );
569  }
570 
571 
573  void setLineWriter( const shared_ptr<LogControl::LineWriter> & writer_r )
574  { LogThread::instance().setLineWriter( writer_r ); }
575 
576  shared_ptr<LogControl::LineWriter> getLineWriter() const
577  { return LogThread::instance().getLineWriter(); }
578 
580  void setLineFormater( const shared_ptr<LogControl::LineFormater> & format_r )
581  {
582  if ( format_r )
583  _lineFormater = format_r;
584  else
586  }
587 
588  void logfile( const Pathname & logfile_r, mode_t mode_r = 0640 )
589  {
590  if ( logfile_r.empty() )
591  setLineWriter( shared_ptr<LogControl::LineWriter>() );
592  else if ( logfile_r == Pathname( "-" ) )
593  setLineWriter( shared_ptr<LogControl::LineWriter>(new log::StderrLineWriter) );
594  else
595  setLineWriter( shared_ptr<LogControl::LineWriter>(new log::FileLineWriter(logfile_r, mode_r)) );
596  }
597 
598  private:
600  std::ostream _no_stream;
602  mutable TriBool _hideThreadName = indeterminate;
603 
604  shared_ptr<LogControl::LineFormater> _lineFormater;
605 
606  public:
608  std::ostream & getStream( const std::string & group_r,
609  LogLevel level_r,
610  const char * file_r,
611  const char * func_r,
612  const int line_r )
613  {
614  if ( ! getLineWriter() )
615  return _no_stream;
616  if ( level_r == E_XXX && !_excessive )
617  return _no_stream;
618 
619  if ( !_streamtable[group_r][level_r] )
620  {
621  _streamtable[group_r][level_r].reset( new Loglinestream( group_r, level_r ) );
622  }
623  std::ostream & ret( _streamtable[group_r][level_r]->getStream( file_r, func_r, line_r ) );
624  if ( !ret )
625  {
626  ret.clear();
627  ret << "---<RESET LOGSTREAM FROM FAILED STATE]" << endl;
628  }
629  return ret;
630  }
631 
633  void putStream( const std::string & group_r,
634  LogLevel level_r,
635  const char * file_r,
636  const char * func_r,
637  int line_r,
638  const std::string & message_r )
639  {
640  _logClient.pushMessage( _lineFormater->format( group_r, level_r,
641  file_r, func_r, line_r,
642  message_r ) );
643  }
644 
645  private:
646  typedef shared_ptr<Loglinestream> StreamPtr;
647  typedef std::map<LogLevel,StreamPtr> StreamSet;
648  typedef std::map<std::string,StreamSet> StreamTable;
651  zyppng::Socket::Ptr _sock;
652 
653  private:
654 
655  void readEnvVars () {
656  if ( getenv("ZYPP_LOGFILE") )
657  logfile( getenv("ZYPP_LOGFILE") );
658 
659  if ( getenv("ZYPP_PROFILING") )
660  {
661  shared_ptr<LogControl::LineFormater> formater(new ProfilingFormater);
662  setLineFormater(formater);
663  }
664  }
669  : _no_stream( NULL )
670  , _excessive( getenv("ZYPP_FULLLOG") )
671  , _lineFormater( new LogControl::LineFormater )
672  {
673  logControlValidFlag() = 1;
674  std::call_once( flagReadEnvAutomatically, &LogControlImpl::readEnvVars, this);
675 
676  // make sure the LogControl is invalidated when we fork
677  pthread_atfork( nullptr, nullptr, &LogControl::notifyFork );
678  }
679 
680  public:
681 
683  {
684  logControlValidFlag() = 0;
685  }
686 
693  static LogControlImpl *instance();
694  };
696 
697  // 'THE' LogControlImpl singleton
699  {
700  thread_local static LogControlImpl _instance;
701  if ( logControlValidFlag() > 0 )
702  return &_instance;
703  return nullptr;
704  }
705 
707 
709  inline std::ostream & operator<<( std::ostream & str, const LogControlImpl & )
710  {
711  return str << "LogControlImpl";
712  }
713 
715  //
716  // Access from logger::
717  //
719 
720  std::ostream & getStream( const char * group_r,
721  LogLevel level_r,
722  const char * file_r,
723  const char * func_r,
724  const int line_r )
725  {
726  static std::ostream nstream(NULL);
727  auto control = LogControlImpl::instance();
728  if ( !control || !group_r || strlen(group_r ) == 0 ) {
729  return nstream;
730  }
731 
732 
733 
734  return control->getStream( group_r,
735  level_r,
736  file_r,
737  func_r,
738  line_r );
739  }
740 
742  inline void putStream( const std::string & group_r, LogLevel level_r,
743  const char * file_r, const char * func_r, int line_r,
744  const std::string & buffer_r )
745  {
746  auto control = LogControlImpl::instance();
747  if ( !control )
748  return;
749 
750  control->putStream( group_r, level_r,
751  file_r, func_r, line_r,
752  buffer_r );
753  }
754 
755  bool isExcessive()
756  {
757  auto impl = LogControlImpl::instance();
758  if ( !impl )
759  return false;
760  return impl->isExcessive();
761  }
762 
764  } // namespace logger
766 
767  using logger::LogControlImpl;
768 
770  // LineFormater
772  std::string LogControl::LineFormater::format( const std::string & group_r,
773  logger::LogLevel level_r,
774  const char * file_r,
775  const char * func_r,
776  int line_r,
777  const std::string & message_r )
778  {
779  static char hostname[1024];
780  static char nohostname[] = "unknown";
781  std::string now( Date::now().form( "%Y-%m-%d %H:%M:%S" ) );
782  std::string ret;
784  ret = str::form( "%s <%d> %s(%d) [%s] %s(%s):%d %s",
785  now.c_str(), level_r,
786  ( gethostname( hostname, 1024 ) ? nohostname : hostname ),
787  getpid(),
788  group_r.c_str(),
789  file_r, func_r, line_r,
790  message_r.c_str() );
791  else
792  ret = str::form( "%s <%d> %s(%d) [%s] %s(%s):%d {T:%s} %s",
793  now.c_str(), level_r,
794  ( gethostname( hostname, 1024 ) ? nohostname : hostname ),
795  getpid(),
796  group_r.c_str(),
797  file_r, func_r, line_r,
798  zyppng::ThreadData::current().name().c_str(),
799  message_r.c_str() );
800  return ret;
801  }
802 
804  //
805  // CLASS NAME : LogControl
806  // Forward to LogControlImpl singleton.
807  //
809 
810 
811  void LogControl::logfile( const Pathname & logfile_r )
812  {
813  auto impl = LogControlImpl::instance();
814  if ( !impl )
815  return;
816 
817  impl->logfile( logfile_r );
818  }
819 
820  void LogControl::logfile( const Pathname & logfile_r, mode_t mode_r )
821  {
822  auto impl = LogControlImpl::instance();
823  if ( !impl )
824  return;
825 
826  impl->logfile( logfile_r, mode_r );
827  }
828 
829  shared_ptr<LogControl::LineWriter> LogControl::getLineWriter() const
830  {
831  auto impl = LogControlImpl::instance();
832  if ( !impl )
833  return nullptr;
834 
835  return impl->getLineWriter();
836  }
837 
838  void LogControl::setLineWriter( const shared_ptr<LineWriter> & writer_r )
839  {
840  auto impl = LogControlImpl::instance();
841  if ( !impl )
842  return;
843  impl->setLineWriter( writer_r );
844  }
845 
846  void LogControl::setLineFormater( const shared_ptr<LineFormater> & formater_r )
847  {
848  auto impl = LogControlImpl::instance();
849  if ( !impl )
850  return;
851  impl->setLineFormater( formater_r );
852  }
853 
855  {
856  auto impl = LogControlImpl::instance();
857  if ( !impl )
858  return;
859  impl->setLineWriter( shared_ptr<LineWriter>() );
860  }
861 
863  {
864  auto impl = LogControlImpl::instance();
865  if ( !impl )
866  return;
867  impl->setLineWriter( shared_ptr<LineWriter>( new log::StderrLineWriter ) );
868  }
869 
871  {
873  }
874 
876  {
878  }
879 
881  //
882  // LogControl::TmpExcessive
883  //
886  {
887  auto impl = LogControlImpl::instance();
888  if ( !impl )
889  return;
890  impl->excessive( true );
891  }
893  {
894  auto impl = LogControlImpl::instance();
895  if ( !impl )
896  return;
897  impl->excessive( false );
898  }
899 
900  /******************************************************************
901  **
902  ** FUNCTION NAME : operator<<
903  ** FUNCTION TYPE : std::ostream &
904  */
905  std::ostream & operator<<( std::ostream & str, const LogControl & )
906  {
907  auto impl = LogControlImpl::instance();
908  if ( !impl )
909  return str;
910  return str << *impl;
911  }
912 
914  } // namespace base
917 } // namespace zypp
std::once_flag flagReadEnvAutomatically
Definition: LogControl.cc:52
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:94
static Date now()
Return the current time.
Definition: Date.h:78
bool ensureConnection()
Definition: LogControl.cc:226
void pushMessage(std::string &&msg)
Definition: LogControl.cc:241
std::thread _thread
Definition: LogControl.cc:199
zyppng::Wakeup _stopSignal
Definition: LogControl.cc:200
std::thread::id threadId()
Definition: LogControl.cc:113
boost::shared_ptr< log::LineWriter > getLineWriter()
Definition: LogControl.cc:101
SpinLock _lineWriterLock
Definition: LogControl.cc:205
static std::string sockPath()
Definition: LogControl.cc:117
boost::shared_ptr< log::LineWriter > _lineWriter
Definition: LogControl.cc:207
void setLineWriter(boost::shared_ptr< log::LineWriter > writer)
Definition: LogControl.cc:96
static LogThread & instance()
Definition: LogControl.cc:91
std::atomic_flag _atomicLock
Definition: LogControl.cc:79
Maintain logfile related options.
Definition: LogControl.h:97
shared_ptr< LineWriter > getLineWriter() const
Get the current LineWriter.
Definition: LogControl.cc:829
void setLineWriter(const shared_ptr< LineWriter > &writer_r)
Assign a LineWriter.
Definition: LogControl.cc:838
void emergencyShutdown()
will cause the log thread to exit and flush all sockets
Definition: LogControl.cc:870
void logToStdErr()
Log to std::err.
Definition: LogControl.cc:862
void logNothing()
Turn off logging.
Definition: LogControl.cc:854
static void notifyFork()
This will completely disable logging, its supposed to be called in the child process after fork() was...
Definition: LogControl.cc:875
void setLineFormater(const shared_ptr< LineFormater > &formater_r)
Assign a LineFormater.
Definition: LogControl.cc:846
void logfile(const Pathname &logfile_r)
Set path for the logfile.
Definition: LogControl.cc:811
friend std::ostream & operator<<(std::ostream &str, const LogControl &obj)
Definition: LogControl.cc:905
virtual int overflow(int ch=EOF)
Definition: LogControl.cc:433
virtual std::streamsize xsputn(const char *s, std::streamsize n)
Definition: LogControl.cc:430
Loglinebuf(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:406
void tagSet(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:421
virtual int writeout(const char *s, std::streamsize n)
Definition: LogControl.cc:443
Loglinestream(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:486
std::ostream & getStream(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:496
const std::string & asString() const
String representation.
Definition: Pathname.h:91
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
const char * c_str() const
String representation.
Definition: Pathname.h:110
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition: String.h:30
Definition: Arch.h:348
String related utilities and Regular expression matching.
int & logControlValidFlag()
Definition: LogControl.cc:516
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's what Loglinebuf calls.
Definition: LogControl.cc:742
LogLevel
Definition of log levels.
Definition: Logger.h:145
@ E_XXX
Excessive logging.
Definition: Logger.h:146
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:720
static constexpr std::string_view WH
Definition: LogControl.cc:297
std::string tracestr(char tag_r, unsigned depth_r, const char *file_r, const char *fnc_r, int line_r)
Definition: LogControl.cc:306
static constexpr std::string_view OO
Definition: LogControl.cc:296
static constexpr std::string_view YE
Definition: LogControl.cc:299
static constexpr std::string_view CY
Definition: LogControl.cc:298
static constexpr std::string_view GR
Definition: LogControl.cc:300
static constexpr std::string_view MA
Definition: LogControl.cc:302
static constexpr std::string_view RE
Definition: LogControl.cc:301
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
constexpr bool always_false_v
Definition: LogControl.cc:58
Pathname _file
Definition: SystemCheck.cc:34
constexpr std::string_view ZYPP_MAIN_THREAD_NAME("Zypp-main")
If you want to format loglines by yourself, derive from this, and overload format.
Definition: LogControl.h:115
virtual std::string format(const std::string &, logger::LogLevel, const char *, const char *, int, const std::string &)
Definition: LogControl.cc:772
LogControl implementation (thread_local Singleton).
Definition: LogControl.cc:539
void setLineWriter(const shared_ptr< LogControl::LineWriter > &writer_r)
NULL _lineWriter indicates no loggin.
Definition: LogControl.cc:573
static LogControlImpl * instance()
The LogControlImpl singleton.
Definition: LogControl.cc:698
shared_ptr< LogControl::LineWriter > getLineWriter() const
Definition: LogControl.cc:576
std::ostream & operator<<(std::ostream &str, const LogControlImpl &)
Stream output.
Definition: LogControl.cc:709
static void instanceHideThreadName(bool onOff_r)
Definition: LogControl.cc:565
StreamTable _streamtable
one streambuffer per group and level
Definition: LogControl.cc:650
std::map< LogLevel, StreamPtr > StreamSet
Definition: LogControl.cc:647
std::map< std::string, StreamSet > StreamTable
Definition: LogControl.cc:648
shared_ptr< Loglinestream > StreamPtr
Definition: LogControl.cc:646
void setLineFormater(const shared_ptr< LogControl::LineFormater > &format_r)
Assert _lineFormater is not NULL.
Definition: LogControl.cc:580
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:608
void logfile(const Pathname &logfile_r, mode_t mode_r=0640)
Definition: LogControl.cc:588
shared_ptr< LogControl::LineFormater > _lineFormater
Definition: LogControl.cc:604
bool hideThreadName() const
Hint for Formater whether to hide the thread name.
Definition: LogControl.cc:549
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:633
void hideThreadName(bool onOff_r)
Definition: LogControl.cc:556
TriBool _hideThreadName
Hint for Formater whether to hide the thread name.
Definition: LogControl.cc:602
std::ostream & _strlog
Definition: Logger.h:59
Osd & operator<<(Tp &&val)
Definition: Logger.h:48
Osd(std::ostream &, int=0)
Definition: LogControl.cc:330
std::ostream & _strout
Definition: Logger.h:58
static unsigned _depth
Definition: Logger.h:34
const char * _fnc
Definition: Logger.h:36
const char * _file
Definition: Logger.h:35
LineWriter to file.
Definition: LogControl.h:73
shared_ptr< void > _outs
Definition: LogControl.h:76
FileLineWriter(const Pathname &file_r, mode_t mode_r=0)
Definition: LogControl.cc:359
LineWriter to stderr.
Definition: LogControl.h:64
Base class for ostream based LineWriter.
Definition: LogControl.h:45
Convenient building of std::string with boost::format.
Definition: String.h:253
#define USR
Definition: Logger.h:101
#define L_USR(GROUP)
Definition: Logger.h:110