libzypp 17.31.23
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
41extern "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
50using std::endl;
51
53
54namespace 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 it is 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
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 the 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 signals
136 zyppng::blockAllSignalsForCurrentThread();
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 auto br = sock->readLine();
191 while ( !br.empty() ) {
192 if ( br.back () == '\n' )
193 writer->writeOut( std::string( br.data(), br.size() - 1 ) );
194 else
195 writer->writeOut( std::string( br.data(), br.size() ) );
196
197 br = sock->readLine();
198 }
199 }
200 }
201 }
202
203 private:
204 std::thread _thread;
205 zyppng::Wakeup _stopSignal;
206
207 // since the public API uses boost::shared_ptr we can not use the atomic
208 // functionalities provided in std.
209 // this lock type can be used safely in signals
211 // boost shared_ptr has a lock free implementation of reference counting so it can be used from signal handlers as well
212 boost::shared_ptr<log::LineWriter> _lineWriter{ nullptr };
213 };
214
216 {
217 public:
219 // make sure the thread is running
220 LogThread::instance();
221 }
222
224 ::close( _sockFD );
225 }
226
232 if ( _sockFD >= 0 )
233 return true;
234
235 _sockFD = ::socket( AF_UNIX, SOCK_STREAM, 0 );
236 if ( _sockFD == -1 )
237 return false;
238
239 zyppng::UnixSockAddr addr( LogThread::sockPath(), true );
240 return zyppng::trySocketConnection( _sockFD, addr, 100 );
241 }
242
246 void pushMessage ( std::string &&msg ) {
247 if ( inPushMessage ) {
248 return;
249 }
250
251 // make sure we do not end up in a busy loop
252 zypp::AutoDispose<bool *> res( &inPushMessage, [](auto val){
253 *val = false;
254 });
255 inPushMessage = true;
256
257 // if we are in the same thread as the Log worker we can directly push our messages out, no need to use the socket
258 if ( std::this_thread::get_id() == LogThread::instance().threadId() ) {
259 auto writer = LogThread::instance().getLineWriter();
260 if ( writer )
261 writer->writeOut( msg );
262 return;
263 }
264
265 if(!ensureConnection())
266 return;
267
268 if ( msg.back() != '\n' )
269 msg.push_back('\n');
270
271 size_t written = 0;
272 while ( written < msg.size() ) {
273 const auto res = zyppng::eintrSafeCall( ::send, _sockFD, msg.data() + written, msg.size() - written, MSG_NOSIGNAL );
274 if ( res == -1 ) {
275 //assume broken socket
276 ::close( _sockFD );
277 _sockFD = -1;
278 return;
279 }
280 written += res;
281 }
282 }
283
284 private:
285 int _sockFD = -1;
286 bool inPushMessage = false;
287 };
288
289#ifndef ZYPP_NDEBUG
290 namespace debug
291 {
292 // Fg::Black: 30 Bg: 40 Attr::Normal: 22;27
293 // Fg::Red: 31 ... Attr::Bright: 1
294 // Fg::Green: 32 Attr::Reverse: 7
295 // Fg::Yellow: 33
296 // Fg::Blue: 34
297 // Fg::Magenta: 35
298 // Fg::Cyan: 36
299 // Fg::White: 37
300 // Fg::Default: 39
301 static constexpr std::string_view OO { "\033[0m" };
302 static constexpr std::string_view WH { "\033[37;40m" };
303 static constexpr std::string_view CY { "\033[36;40m" };
304 static constexpr std::string_view YE { "\033[33;1;40m" };
305 static constexpr std::string_view GR { "\033[32;40m" };
306 static constexpr std::string_view RE { "\033[31;1;40m" };
307 static constexpr std::string_view MA { "\033[35;40m" };
308
309 unsigned TraceLeave::_depth = 1;
310
311 std::string tracestr( char tag_r, unsigned depth_r, const char * file_r, const char * fnc_r, int line_r )
312 {
313 static str::Format fmt { "*** %s %s(%s):%d" };
314 fmt % std::string(depth_r,tag_r) % file_r % fnc_r % line_r;
315 return fmt;
316 }
317
318 TraceLeave::TraceLeave( const char * file_r, const char * fnc_r, int line_r )
319 : _file( std::move(file_r) )
320 , _fnc( std::move(fnc_r) )
321 , _line( line_r )
322 {
323 const std::string & m { tracestr( '>',_depth++, _file,_fnc,_line ) };
324 USR << m << endl;
325 Osd(L_USR("TRACE"),1) << m << endl;
326 }
327
329 {
330 const std::string & m { tracestr( '<',--_depth, _file,_fnc,_line ) };
331 USR << m << endl;
332 Osd(L_USR("TRACE"),1) << m << endl;
333 }
334
335 Osd::Osd( std::ostream & str, int i )
336 : _strout { std::cerr }
337 , _strlog { str }
338 { _strout << (i?WH:YE); }
339
341 { _strout << OO; }
342
343 Osd & Osd::operator<<( std::ostream& (*iomanip)( std::ostream& ) )
344 {
345 _strout << iomanip;
346 _strlog << iomanip;
347 return *this;
348 }
349}
350#endif // ZYPP_NDEBUG
351
353 namespace log
354 {
355
357 : StreamLineWriter( std::cout )
358 {}
359
361 : StreamLineWriter( std::cerr )
362 {}
363
364 FileLineWriter::FileLineWriter( const Pathname & file_r, mode_t mode_r )
365 {
366 if ( file_r == Pathname("-") )
367 {
368 _str = &std::cerr;
369 }
370 else
371 {
372 if ( mode_r )
373 {
374 // not filesystem::assert_file as filesystem:: functions log,
375 // and this FileWriter is not yet in place.
376 int fd = ::open( file_r.c_str(), O_CREAT|O_EXCL, mode_r );
377 if ( fd != -1 )
378 ::close( fd );
379 }
380 // set unbuffered write
381 std::ofstream * fstr = 0;
382 _outs.reset( (fstr = new std::ofstream( file_r.asString().c_str(), std::ios_base::app )) );
383 fstr->rdbuf()->pubsetbuf(0,0);
384 _str = &(*fstr);
385 }
386 }
387
389 } // namespace log
391
393 namespace base
394 {
396 namespace logger
397 {
398
399 inline void putStream( const std::string & group_r, LogLevel level_r,
400 const char * file_r, const char * func_r, int line_r,
401 const std::string & buffer_r );
402
404 //
405 // CLASS NAME : Loglinebuf
406 //
407 class Loglinebuf : public std::streambuf {
408
409 public:
411 Loglinebuf( const std::string & group_r, LogLevel level_r )
412 : _group( group_r )
413 , _level( level_r )
414 , _file( "" )
415 , _func( "" )
416 , _line( -1 )
417 {}
420 {
421 if ( !_buffer.empty() )
422 writeout( "\n", 1 );
423 }
424
426 void tagSet( const char * fil_r, const char * fnc_r, int lne_r )
427 {
428 _file = fil_r;
429 _func = fnc_r;
430 _line = lne_r;
431 }
432
433 private:
435 virtual std::streamsize xsputn( const char * s, std::streamsize n )
436 { return writeout( s, n ); }
438 virtual int overflow( int ch = EOF )
439 {
440 if ( ch != EOF )
441 {
442 char tmp = ch;
443 writeout( &tmp, 1 );
444 }
445 return 0;
446 }
448 virtual int writeout( const char* s, std::streamsize n )
449 {
450 //logger::putStream( _group, _level, _file, _func, _line, _buffer );
451 //return n;
452 if ( s && n )
453 {
454 const char * c = s;
455 for ( int i = 0; i < n; ++i, ++c )
456 {
457 if ( *c == '\n' ) {
458 _buffer += std::string( s, c-s );
460 _buffer = std::string();
461 s = c+1;
462 }
463 }
464 if ( s < c )
465 {
466 _buffer += std::string( s, c-s );
467 }
468 }
469 return n;
470 }
471
472 private:
473 std::string _group;
475 const char * _file;
476 const char * _func;
477 int _line;
478 std::string _buffer;
479 };
480
482
484 //
485 // CLASS NAME : Loglinestream
486 //
488
489 public:
491 Loglinestream( const std::string & group_r, LogLevel level_r )
492 : _mybuf( group_r, level_r )
493 , _mystream( &_mybuf )
494 {}
497 { _mystream.flush(); }
498
499 public:
501 std::ostream & getStream( const char * fil_r, const char * fnc_r, int lne_r )
502 {
503 _mybuf.tagSet( fil_r, fnc_r, lne_r );
504 return _mystream;
505 }
506
507 private:
509 std::ostream _mystream;
510 };
512
513 struct LogControlImpl;
514
515 /*
516 * Ugly hack to prevent the use of LogControlImpl when libzypp is shutting down.
517 * Due to the C++ standard, thread_local static instances are cleaned up before the first global static
518 * destructor is called. So all classes that use logging after that point in time would crash the
519 * application because it is accessing a variable that has already been destroyed.
520 */
522 // We are using a POD flag that does not have a destructor,
523 // to flag if the thread_local destructors were already executed.
524 // Since TLS data is stored in a segment that is available until the thread ceases to exist it should still be readable
525 // after thread_local c++ destructors were already executed. Or so I hope.
526 static thread_local int logControlValid = 0;
527 return logControlValid;
528 }
529
531 //
532 // CLASS NAME : LogControlImpl
533 //
544 {
545 public:
546 bool isExcessive() const
547 { return _excessive; }
548
549 void excessive( bool onOff_r )
550 { _excessive = onOff_r; }
551
552
554 bool hideThreadName() const
555 {
556 if ( indeterminate(_hideThreadName) )
557 _hideThreadName = ( zyppng::ThreadData::current().name() == ZYPP_MAIN_THREAD_NAME );
558 return bool(_hideThreadName);
559 }
561 void hideThreadName( bool onOff_r )
562 { _hideThreadName = onOff_r; }
563
566 {
567 auto impl = LogControlImpl::instance();
568 return impl ? impl->hideThreadName() : false;
569 }
571 static void instanceHideThreadName( bool onOff_r )
572 {
573 auto impl = LogControlImpl::instance();
574 if ( impl ) impl->hideThreadName( onOff_r );
575 }
576
578 static bool instanceLogToPPID( )
579 {
580 auto impl = LogControlImpl::instance();
581 return impl ? impl->_logToPPIDMode : false;
582 }
583
585 static void instanceSetLogToPPID( bool onOff_r )
586 {
587 auto impl = LogControlImpl::instance();
588 if ( impl )
589 impl->_logToPPIDMode = onOff_r;
590 }
591
593 void setLineWriter( const shared_ptr<LogControl::LineWriter> & writer_r )
594 { LogThread::instance().setLineWriter( writer_r ); }
595
596 shared_ptr<LogControl::LineWriter> getLineWriter() const
597 { return LogThread::instance().getLineWriter(); }
598
600 void setLineFormater( const shared_ptr<LogControl::LineFormater> & format_r )
601 {
602 if ( format_r )
603 _lineFormater = format_r;
604 else
606 }
607
608 void logfile( const Pathname & logfile_r, mode_t mode_r = 0640 )
609 {
610 if ( logfile_r.empty() )
611 setLineWriter( shared_ptr<LogControl::LineWriter>() );
612 else if ( logfile_r == Pathname( "-" ) )
613 setLineWriter( shared_ptr<LogControl::LineWriter>(new log::StderrLineWriter) );
614 else
615 setLineWriter( shared_ptr<LogControl::LineWriter>(new log::FileLineWriter(logfile_r, mode_r)) );
616 }
617
618 private:
620 std::ostream _no_stream;
622 bool _logToPPIDMode = false;
623 mutable TriBool _hideThreadName = indeterminate;
624
625 shared_ptr<LogControl::LineFormater> _lineFormater;
626
627 public:
629 std::ostream & getStream( const std::string & group_r,
630 LogLevel level_r,
631 const char * file_r,
632 const char * func_r,
633 const int line_r )
634 {
635 if ( ! getLineWriter() )
636 return _no_stream;
637 if ( level_r == E_XXX && !_excessive )
638 return _no_stream;
639
640 if ( !_streamtable[group_r][level_r] )
641 {
642 _streamtable[group_r][level_r].reset( new Loglinestream( group_r, level_r ) );
643 }
644 std::ostream & ret( _streamtable[group_r][level_r]->getStream( file_r, func_r, line_r ) );
645 if ( !ret )
646 {
647 ret.clear();
648 ret << "---<RESET LOGSTREAM FROM FAILED STATE]" << endl;
649 }
650 return ret;
651 }
652
653 void putRawLine ( std::string &&line ) {
654 _logClient.pushMessage( std::move(line) );
655 }
656
658 void putStream( const std::string & group_r,
659 LogLevel level_r,
660 const char * file_r,
661 const char * func_r,
662 int line_r,
663 const std::string & message_r )
664 {
665 _logClient.pushMessage( _lineFormater->format( group_r, level_r,
666 file_r, func_r, line_r,
667 message_r ) );
668 }
669
670 private:
671 typedef shared_ptr<Loglinestream> StreamPtr;
672 typedef std::map<LogLevel,StreamPtr> StreamSet;
673 typedef std::map<std::string,StreamSet> StreamTable;
676 zyppng::Socket::Ptr _sock;
677
678 private:
679
680 void readEnvVars () {
681 if ( getenv("ZYPP_LOGFILE") )
682 logfile( getenv("ZYPP_LOGFILE") );
683
684 if ( getenv("ZYPP_PROFILING") )
685 {
686 shared_ptr<LogControl::LineFormater> formater(new ProfilingFormater);
687 setLineFormater(formater);
688 }
689 }
694 : _no_stream( NULL )
695 , _excessive( getenv("ZYPP_FULLLOG") )
696 , _lineFormater( new LogControl::LineFormater )
697 {
700
701 // make sure the LogControl is invalidated when we fork
702 pthread_atfork( nullptr, nullptr, &LogControl::notifyFork );
703 }
704
705 public:
706
708 {
710 }
711
718 static LogControlImpl *instance();
719 };
721
722 // 'THE' LogControlImpl singleton
724 {
725 thread_local static LogControlImpl _instance;
726 if ( logControlValidFlag() > 0 )
727 return &_instance;
728 return nullptr;
729 }
730
732
734 inline std::ostream & operator<<( std::ostream & str, const LogControlImpl & )
735 {
736 return str << "LogControlImpl";
737 }
738
740 //
741 // Access from logger::
742 //
744
745 std::ostream & getStream( const char * group_r,
746 LogLevel level_r,
747 const char * file_r,
748 const char * func_r,
749 const int line_r )
750 {
751 static std::ostream nstream(NULL);
752 auto control = LogControlImpl::instance();
753 if ( !control || !group_r || strlen(group_r ) == 0 ) {
754 return nstream;
755 }
756
757
758
759 return control->getStream( group_r,
760 level_r,
761 file_r,
762 func_r,
763 line_r );
764 }
765
767 inline void putStream( const std::string & group_r, LogLevel level_r,
768 const char * file_r, const char * func_r, int line_r,
769 const std::string & buffer_r )
770 {
771 auto control = LogControlImpl::instance();
772 if ( !control )
773 return;
774
775 control->putStream( group_r, level_r,
776 file_r, func_r, line_r,
777 buffer_r );
778 }
779
781 {
782 auto impl = LogControlImpl::instance();
783 if ( !impl )
784 return false;
785 return impl->isExcessive();
786 }
787
789 } // namespace logger
791
792 using logger::LogControlImpl;
793
795 // LineFormater
797 std::string LogControl::LineFormater::format( const std::string & group_r,
798 logger::LogLevel level_r,
799 const char * file_r,
800 const char * func_r,
801 int line_r,
802 const std::string & message_r )
803 {
804 static char hostname[1024];
805 static char nohostname[] = "unknown";
806 std::string now( Date::now().form( "%Y-%m-%d %H:%M:%S" ) );
807 std::string ret;
808
809 const bool logToPPID = LogControlImpl::instanceLogToPPID();
810 if ( !logToPPID && LogControlImpl::instanceHideThreadName() )
811 ret = str::form( "%s <%d> %s(%d) [%s] %s(%s):%d %s",
812 now.c_str(), level_r,
813 ( gethostname( hostname, 1024 ) ? nohostname : hostname ),
814 getpid(),
815 group_r.c_str(),
816 file_r, func_r, line_r,
817 message_r.c_str() );
818 else
819 ret = str::form( "%s <%d> %s(%d) [%s] %s(%s):%d {T:%s} %s",
820 now.c_str(), level_r,
821 ( gethostname( hostname, 1024 ) ? nohostname : hostname ),
822 logToPPID ? getppid() : getpid(),
823 group_r.c_str(),
824 file_r, func_r, line_r,
825 zyppng::ThreadData::current().name().c_str(),
826 message_r.c_str() );
827 return ret;
828 }
829
831 //
832 // CLASS NAME : LogControl
833 // Forward to LogControlImpl singleton.
834 //
836
837
838 void LogControl::logfile( const Pathname & logfile_r )
839 {
840 auto impl = LogControlImpl::instance();
841 if ( !impl )
842 return;
843
844 impl->logfile( logfile_r );
845 }
846
847 void LogControl::logfile( const Pathname & logfile_r, mode_t mode_r )
848 {
849 auto impl = LogControlImpl::instance();
850 if ( !impl )
851 return;
852
853 impl->logfile( logfile_r, mode_r );
854 }
855
856 shared_ptr<LogControl::LineWriter> LogControl::getLineWriter() const
857 {
858 auto impl = LogControlImpl::instance();
859 if ( !impl )
860 return nullptr;
861
862 return impl->getLineWriter();
863 }
864
865 void LogControl::setLineWriter( const shared_ptr<LineWriter> & writer_r )
866 {
867 auto impl = LogControlImpl::instance();
868 if ( !impl )
869 return;
870 impl->setLineWriter( writer_r );
871 }
872
873 void LogControl::setLineFormater( const shared_ptr<LineFormater> & formater_r )
874 {
875 auto impl = LogControlImpl::instance();
876 if ( !impl )
877 return;
878 impl->setLineFormater( formater_r );
879 }
880
882 {
884 }
885
887 {
888 auto impl = LogControlImpl::instance();
889 if ( !impl )
890 return;
891 impl->setLineWriter( shared_ptr<LineWriter>() );
892 }
893
895 {
896 auto impl = LogControlImpl::instance();
897 if ( !impl )
898 return;
899 impl->setLineWriter( shared_ptr<LineWriter>( new log::StderrLineWriter ) );
900 }
901
903 {
905 }
906
908 {
910 }
911
912 void LogControl::logRawLine ( std::string &&line )
913 {
914 LogControlImpl::instance ()->putRawLine ( std::move(line) );
915 }
916
918 //
919 // LogControl::TmpExcessive
920 //
923 {
924 auto impl = LogControlImpl::instance();
925 if ( !impl )
926 return;
927 impl->excessive( true );
928 }
930 {
931 auto impl = LogControlImpl::instance();
932 if ( !impl )
933 return;
934 impl->excessive( false );
935 }
936
937 /******************************************************************
938 **
939 ** FUNCTION NAME : operator<<
940 ** FUNCTION TYPE : std::ostream &
941 */
942 std::ostream & operator<<( std::ostream & str, const LogControl & )
943 {
944 auto impl = LogControlImpl::instance();
945 if ( !impl )
946 return str;
947 return str << *impl;
948 }
949
951 } // namespace base
954} // 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:231
void pushMessage(std::string &&msg)
Definition: LogControl.cc:246
boost::shared_ptr< log::LineWriter > getLineWriter()
Definition: LogControl.cc:101
std::thread _thread
Definition: LogControl.cc:204
zyppng::Wakeup _stopSignal
Definition: LogControl.cc:205
std::thread::id threadId()
Definition: LogControl.cc:113
SpinLock _lineWriterLock
Definition: LogControl.cc:210
static LogThread & instance()
Definition: LogControl.cc:91
static std::string sockPath()
Definition: LogControl.cc:117
boost::shared_ptr< log::LineWriter > _lineWriter
Definition: LogControl.cc:212
void setLineWriter(boost::shared_ptr< log::LineWriter > writer)
Definition: LogControl.cc:96
std::atomic_flag _atomicLock
Definition: LogControl.cc:79
Maintain logfile related options.
Definition: LogControl.h:97
friend std::ostream & operator<<(std::ostream &str, const LogControl &obj)
Definition: LogControl.cc:942
shared_ptr< LineWriter > getLineWriter() const
Get the current LineWriter.
Definition: LogControl.cc:856
void setLineWriter(const shared_ptr< LineWriter > &writer_r)
Assign a LineWriter.
Definition: LogControl.cc:865
void emergencyShutdown()
will cause the log thread to exit and flush all sockets
Definition: LogControl.cc:902
void logToStdErr()
Log to std::err.
Definition: LogControl.cc:894
void logRawLine(std::string &&line)
will push a line to the logthread without formatting it
Definition: LogControl.cc:912
void logNothing()
Turn off logging.
Definition: LogControl.cc:886
static void notifyFork()
This will completely disable logging.
Definition: LogControl.cc:907
void setLineFormater(const shared_ptr< LineFormater > &formater_r)
Assign a LineFormater.
Definition: LogControl.cc:873
void enableLogForwardingMode(bool enable=true)
Definition: LogControl.cc:881
void logfile(const Pathname &logfile_r)
Set path for the logfile.
Definition: LogControl.cc:838
virtual int overflow(int ch=EOF)
Definition: LogControl.cc:438
virtual std::streamsize xsputn(const char *s, std::streamsize n)
Definition: LogControl.cc:435
Loglinebuf(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:411
void tagSet(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:426
virtual int writeout(const char *s, std::streamsize n)
Definition: LogControl.cc:448
Loglinestream(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:491
std::ostream & getStream(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:501
const char * c_str() const
String representation.
Definition: Pathname.h:110
const std::string & asString() const
String representation.
Definition: Pathname.h:91
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition: String.h:30
Definition: Arch.h:361
String related utilities and Regular expression matching.
int & logControlValidFlag()
Definition: LogControl.cc:521
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:767
LogLevel
Definition of log levels.
Definition: Logger.h:152
@ E_XXX
Excessive logging.
Definition: Logger.h:153
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:745
static constexpr std::string_view WH
Definition: LogControl.cc:302
std::string tracestr(char tag_r, unsigned depth_r, const char *file_r, const char *fnc_r, int line_r)
Definition: LogControl.cc:311
static constexpr std::string_view OO
Definition: LogControl.cc:301
static constexpr std::string_view YE
Definition: LogControl.cc:304
static constexpr std::string_view CY
Definition: LogControl.cc:303
static constexpr std::string_view GR
Definition: LogControl.cc:305
static constexpr std::string_view MA
Definition: LogControl.cc:307
static constexpr std::string_view RE
Definition: LogControl.cc:306
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:797
LogControl implementation (thread_local Singleton).
Definition: LogControl.cc:544
void putRawLine(std::string &&line)
Definition: LogControl.cc:653
void setLineWriter(const shared_ptr< LogControl::LineWriter > &writer_r)
NULL _lineWriter indicates no loggin.
Definition: LogControl.cc:593
static LogControlImpl * instance()
The LogControlImpl singleton.
Definition: LogControl.cc:723
std::ostream & operator<<(std::ostream &str, const LogControlImpl &)
Stream output.
Definition: LogControl.cc:734
static void instanceHideThreadName(bool onOff_r)
Definition: LogControl.cc:571
static void instanceSetLogToPPID(bool onOff_r)
Definition: LogControl.cc:585
StreamTable _streamtable
one streambuffer per group and level
Definition: LogControl.cc:675
std::map< LogLevel, StreamPtr > StreamSet
Definition: LogControl.cc:672
static bool instanceLogToPPID()
Hint for formatter wether we forward all logs to a parents log.
Definition: LogControl.cc:578
std::map< std::string, StreamSet > StreamTable
Definition: LogControl.cc:673
shared_ptr< Loglinestream > StreamPtr
Definition: LogControl.cc:671
bool _logToPPIDMode
Hint for formatter to use the PPID and always show the thread name.
Definition: LogControl.cc:622
void setLineFormater(const shared_ptr< LogControl::LineFormater > &format_r)
Assert _lineFormater is not NULL.
Definition: LogControl.cc:600
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:629
void logfile(const Pathname &logfile_r, mode_t mode_r=0640)
Definition: LogControl.cc:608
shared_ptr< LogControl::LineWriter > getLineWriter() const
Definition: LogControl.cc:596
shared_ptr< LogControl::LineFormater > _lineFormater
Definition: LogControl.cc:625
bool hideThreadName() const
Hint for Formater whether to hide the thread name.
Definition: LogControl.cc:554
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:658
void hideThreadName(bool onOff_r)
Definition: LogControl.cc:561
TriBool _hideThreadName
Hint for Formater whether to hide the thread name.
Definition: LogControl.cc:623
std::ostream & _strlog
Definition: Logger.h:59
Osd(std::ostream &, int=0)
Definition: LogControl.cc:335
std::ostream & _strout
Definition: Logger.h:58
Osd & operator<<(Tp &&val)
Definition: Logger.h:48
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:364
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