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>
59 std::this_thread::yield();
98 if (
_thread.get_id() != std::this_thread::get_id() )
115 _thread = std::thread( [
this] () {
123 zyppng::blockSignalsForCurrentThread( { SIGTERM, SIGINT, SIGPIPE, } );
125 zyppng::ThreadData::current().setName(
"Zypp-Log");
127 auto ev = zyppng::EventLoop::create();
128 auto server = zyppng::Socket::create( AF_UNIX, SOCK_STREAM, 0 );
129 auto stopNotifyWatch =
_stopSignal.makeNotifier( );
131 std::vector<zyppng::Socket::Ptr> clients;
134 server->bind( std::make_shared<zyppng::UnixSockAddr>(
sockPath(),
true ) );
138 server->sigIncomingConnection().connect( [&](){
140 auto cl = server->accept();
142 clients.push_back( cl );
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 ) );
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 );
164 stopNotifyWatch->sigActivated().connect( [&ev](
const auto &,
auto ) {
171 auto writer = getLineWriter();
173 for (
auto &sock : clients ){
174 while ( sock->canReadLine() ) {
175 auto br = sock->readLine();
176 writer->writeOut( std::string( br.data(), br.size() - 1 ) );
191 boost::shared_ptr<log::LineWriter> _lineWriter{
nullptr };
199 LogThread::instance();
214 _sockFD = ::socket( AF_UNIX, SOCK_STREAM, 0 );
218 zyppng::UnixSockAddr addr( LogThread::sockPath(),
true );
219 return zyppng::trySocketConnection( _sockFD, addr, 100 );
226 if ( inPushMessage ) {
234 inPushMessage =
true;
237 if ( std::this_thread::get_id() == LogThread::instance().threadId() ) {
238 auto writer = LogThread::instance().getLineWriter();
239 writer->writeOut( msg );
243 if(!ensureConnection())
246 if ( msg.back() !=
'\n' )
250 while ( written < msg.size() ) {
251 const auto res = zyppng::eintrSafeCall( ::send, _sockFD, msg.data() + written, msg.size() - written, MSG_NOSIGNAL );
264 bool inPushMessage =
false;
270 void osdlog(
const std::string & msg_r,
unsigned level_r )
281 static const char * ansi[] = {
289 static const unsigned n =
sizeof(ansi)/
sizeof(
const char *);
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;
299 std::cerr << ansi[level_r%n] <<
"OSD[" << msg_r <<
"]\033[0m" << std::endl;
303 unsigned TraceLeave::_depth = 0;
305 TraceLeave::TraceLeave(
const char * file_r,
const char * fnc_r,
int line_r )
307 , _fnc(
std::move(fnc_r) )
319 #endif // ZYPP_NDEBUG
345 int fd = ::open( file_r.
c_str(), O_CREAT|O_EXCL, mode_r );
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);
373 const std::string & message_r )
375 static char hostname[1024];
376 static char nohostname[] =
"unknown";
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 ),
383 zyppng::ThreadData::current().name().c_str(),
385 file_r, func_r, line_r,
394 const char * file_r,
const char * func_r,
int line_r,
395 const std::string & buffer_r );
420 void tagSet(
const char * fil_r,
const char * fnc_r,
int lne_r )
429 virtual std::streamsize
xsputn(
const char * s, std::streamsize n )
430 {
return writeout( s, n ); }
442 virtual int writeout(
const char* s, std::streamsize n )
449 for (
int i = 0; i < n; ++i, ++c )
452 _buffer += std::string( s, c-s );
460 _buffer += std::string( s, c-s );
486 : _mybuf( group_r, level_r )
487 , _mystream( &_mybuf )
491 { _mystream.flush(); }
495 std::ostream &
getStream(
const char * fil_r,
const char * fnc_r,
int lne_r )
497 _mybuf.tagSet( fil_r, fnc_r, lne_r );
520 static std::atomic_int instCount;
541 {
return _excessive; }
544 { _excessive = onOff_r; }
557 _lineFormater = format_r;
564 if ( logfile_r.
empty() )
566 else if ( logfile_r ==
Pathname(
"-" ) )
589 if ( level_r ==
E_XXX && !_excessive )
592 if ( !_streamtable[group_r][level_r] )
594 _streamtable[group_r][level_r].reset(
new Loglinestream( group_r, level_r ) );
596 std::ostream & ret( _streamtable[group_r][level_r]->
getStream( file_r, func_r, line_r ) );
600 ret <<
"---<RESET LOGSTREAM FROM FAILED STATE]" << endl;
611 const std::string & message_r )
613 _logClient.
pushMessage( _lineFormater->format( group_r, level_r,
614 file_r, func_r, line_r,
629 if ( getenv(
"ZYPP_LOGFILE") )
630 logfile( getenv(
"ZYPP_LOGFILE") );
632 if ( getenv(
"ZYPP_PROFILING") )
643 , _excessive( getenv(
"ZYPP_FULLLOG") )
644 , _lineFormater( new
LogControl::LineFormater )
681 return str <<
"LogControlImpl";
696 static std::ostream nstream(NULL);
704 return control->getStream( group_r,
713 const char * file_r,
const char * func_r,
int line_r,
714 const std::string & buffer_r )
720 control->putStream( group_r, level_r,
721 file_r, func_r, line_r,
730 return impl->isExcessive();
744 using logger::LogControlImpl;
752 impl->logfile( logfile_r );
761 impl->logfile( logfile_r, mode_r );
770 return impl->getLineWriter();
778 impl->setLineWriter( writer_r );
786 impl->setLineFormater( formater_r );
794 impl->setLineWriter( shared_ptr<LineWriter>() );
820 impl->excessive(
true );
827 impl->excessive(
false );