libzypp  17.27.0
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 
16 #include <zypp/base/Logger.h>
17 #include <zypp/base/LogControl.h>
19 #include <zypp/base/String.h>
20 #include <zypp/Date.h>
21 #include <zypp/PathInfo.h>
22 
23 using std::endl;
24 
26 namespace zypp
27 {
28 
29 #ifndef ZYPP_NDEBUG
30  namespace debug
31  {
32  // Fg::Black: 30 Bg: 40 Attr::Normal: 22;27
33  // Fg::Red: 31 ... Attr::Bright: 1
34  // Fg::Green: 32 Attr::Reverse: 7
35  // Fg::Yellow: 33
36  // Fg::Blue: 34
37  // Fg::Magenta: 35
38  // Fg::Cyan: 36
39  // Fg::White: 37
40  // Fg::Default: 39
41  static constexpr std::string_view OO { "\033[0m" };
42  static constexpr std::string_view WH { "\033[37;40m" };
43  static constexpr std::string_view CY { "\033[36;40m" };
44  static constexpr std::string_view YE { "\033[33;1;40m" };
45  static constexpr std::string_view GR { "\033[32;40m" };
46  static constexpr std::string_view RE { "\033[31;1;40m" };
47  static constexpr std::string_view MA { "\033[35;40m" };
48 
49  unsigned TraceLeave::_depth = 1;
50 
51  std::string tracestr( char tag_r, unsigned depth_r, const char * file_r, const char * fnc_r, int line_r )
52  {
53  static str::Format fmt { "*** %s %s(%s):%d" };
54  fmt % std::string(depth_r,tag_r) % file_r % fnc_r % line_r;
55  return fmt;
56  }
57 
58  TraceLeave::TraceLeave( const char * file_r, const char * fnc_r, int line_r )
59  : _file( std::move(file_r) )
60  , _fnc( std::move(fnc_r) )
61  , _line( line_r )
62  {
63  const std::string & m { tracestr( '>',_depth++, _file,_fnc,_line ) };
64  USR << m << endl;
65  Osd(L_USR("TRACE"),1) << m << endl;
66  }
67 
69  {
70  const std::string & m { tracestr( '<',--_depth, _file,_fnc,_line ) };
71  USR << m << endl;
72  Osd(L_USR("TRACE"),1) << m << endl;
73  }
74 
75  Osd::Osd( std::ostream & str, int i )
76  : _strout { std::cerr }
77  , _strlog { str }
78  { _strout << (i?WH:YE); }
79 
81  { _strout << OO; }
82 
83  Osd & Osd::operator<<( std::ostream& (*iomanip)( std::ostream& ) )
84  {
85  _strout << iomanip;
86  _strlog << iomanip;
87  return *this;
88  }
89 }
90 #endif // ZYPP_NDEBUG
91 
93  namespace log
94  {
95 
97  : StreamLineWriter( std::cout )
98  {}
99 
101  : StreamLineWriter( std::cerr )
102  {}
103 
104  FileLineWriter::FileLineWriter( const Pathname & file_r, mode_t mode_r )
105  {
106  if ( file_r == Pathname("-") )
107  {
108  _str = &std::cerr;
109  }
110  else
111  {
112  if ( mode_r )
113  {
114  // not filesystem::assert_file as filesystem:: functions log,
115  // and this FileWriter is not yet in place.
116  int fd = ::open( file_r.c_str(), O_CREAT|O_EXCL, mode_r );
117  if ( fd != -1 )
118  ::close( fd );
119  }
120  // set unbuffered write
121  std::ofstream * fstr = 0;
122  _outs.reset( (fstr = new std::ofstream( file_r.asString().c_str(), std::ios_base::app )) );
123  fstr->rdbuf()->pubsetbuf(0,0);
124  _str = &(*fstr);
125  }
126  }
127 
129  } // namespace log
131 
133  namespace base
134  {
135 
137  // LineFormater
139  std::string LogControl::LineFormater::format( const std::string & group_r,
140  logger::LogLevel level_r,
141  const char * file_r,
142  const char * func_r,
143  int line_r,
144  const std::string & message_r )
145  {
146  static char hostname[1024];
147  static char nohostname[] = "unknown";
148  std::string now( Date::now().form( "%Y-%m-%d %H:%M:%S" ) );
149  return str::form( "%s <%d> %s(%d) [%s] %s(%s):%d %s",
150  now.c_str(), level_r,
151  ( gethostname( hostname, 1024 ) ? nohostname : hostname ),
152  getpid(),
153  group_r.c_str(),
154  file_r, func_r, line_r,
155  message_r.c_str() );
156  }
157 
159  namespace logger
160  {
161 
162  inline void putStream( const std::string & group_r, LogLevel level_r,
163  const char * file_r, const char * func_r, int line_r,
164  const std::string & buffer_r );
165 
167  //
168  // CLASS NAME : Loglinebuf
169  //
170  class Loglinebuf : public std::streambuf {
171 
172  public:
174  Loglinebuf( const std::string & group_r, LogLevel level_r )
175  : _group( group_r )
176  , _level( level_r )
177  , _file( "" )
178  , _func( "" )
179  , _line( -1 )
180  {}
183  {
184  if ( !_buffer.empty() )
185  writeout( "\n", 1 );
186  }
187 
189  void tagSet( const char * fil_r, const char * fnc_r, int lne_r )
190  {
191  _file = fil_r;
192  _func = fnc_r;
193  _line = lne_r;
194  }
195 
196  private:
198  virtual std::streamsize xsputn( const char * s, std::streamsize n )
199  { return writeout( s, n ); }
201  virtual int overflow( int ch = EOF )
202  {
203  if ( ch != EOF )
204  {
205  char tmp = ch;
206  writeout( &tmp, 1 );
207  }
208  return 0;
209  }
211  virtual int writeout( const char* s, std::streamsize n )
212  {
213  //logger::putStream( _group, _level, _file, _func, _line, _buffer );
214  //return n;
215  if ( s && n )
216  {
217  const char * c = s;
218  for ( int i = 0; i < n; ++i, ++c )
219  {
220  if ( *c == '\n' ) {
221  _buffer += std::string( s, c-s );
222  logger::putStream( _group, _level, _file, _func, _line, _buffer );
223  _buffer = std::string();
224  s = c+1;
225  }
226  }
227  if ( s < c )
228  {
229  _buffer += std::string( s, c-s );
230  }
231  }
232  return n;
233  }
234 
235  private:
236  std::string _group;
238  const char * _file;
239  const char * _func;
240  int _line;
241  std::string _buffer;
242  };
243 
245 
247  //
248  // CLASS NAME : Loglinestream
249  //
251 
252  public:
254  Loglinestream( const std::string & group_r, LogLevel level_r )
255  : _mybuf( group_r, level_r )
256  , _mystream( &_mybuf )
257  {}
260  { _mystream.flush(); }
261 
262  public:
264  std::ostream & getStream( const char * fil_r, const char * fnc_r, int lne_r )
265  {
266  _mybuf.tagSet( fil_r, fnc_r, lne_r );
267  return _mystream;
268  }
269 
270  private:
272  std::ostream _mystream;
273  };
275 
277  //
278  // CLASS NAME : LogControlImpl
279  //
290  {
291  public:
292  bool isExcessive()
293  { return _excessive; }
294 
295  void excessive( bool onOff_r )
296  { _excessive = onOff_r; }
297 
299  void setLineWriter( const shared_ptr<LogControl::LineWriter> & writer_r )
300  { _lineWriter = writer_r; }
301 
302  shared_ptr<LogControl::LineWriter> getLineWriter() const
303  { return _lineWriter; }
304 
306  void setLineFormater( const shared_ptr<LogControl::LineFormater> & format_r )
307  {
308  if ( format_r )
309  _lineFormater = format_r;
310  else
311  _lineFormater.reset( new LogControl::LineFormater );
312  }
313 
314  void logfile( const Pathname & logfile_r, mode_t mode_r = 0640 )
315  {
316  if ( logfile_r.empty() )
317  setLineWriter( shared_ptr<LogControl::LineWriter>() );
318  else if ( logfile_r == Pathname( "-" ) )
319  setLineWriter( shared_ptr<LogControl::LineWriter>(new log::StderrLineWriter) );
320  else
321  setLineWriter( shared_ptr<LogControl::LineWriter>(new log::FileLineWriter(logfile_r, mode_r)) );
322  }
323 
324  private:
325  std::ostream _no_stream;
327 
328  shared_ptr<LogControl::LineFormater> _lineFormater;
329  shared_ptr<LogControl::LineWriter> _lineWriter;
330 
331  public:
333  std::ostream & getStream( const std::string & group_r,
334  LogLevel level_r,
335  const char * file_r,
336  const char * func_r,
337  const int line_r )
338  {
339  if ( ! _lineWriter )
340  return _no_stream;
341  if ( level_r == E_XXX && !_excessive )
342  return _no_stream;
343 
344  if ( !_streamtable[group_r][level_r] )
345  {
346  _streamtable[group_r][level_r].reset( new Loglinestream( group_r, level_r ) );
347  }
348  std::ostream & ret( _streamtable[group_r][level_r]->getStream( file_r, func_r, line_r ) );
349  if ( !ret )
350  {
351  ret.clear();
352  ret << "---<RESET LOGSTREAM FROM FAILED STATE]" << endl;
353  }
354  return ret;
355  }
356 
358  void putStream( const std::string & group_r,
359  LogLevel level_r,
360  const char * file_r,
361  const char * func_r,
362  int line_r,
363  const std::string & message_r )
364  {
365  if ( _lineWriter )
366  _lineWriter->writeOut( _lineFormater->format( group_r, level_r,
367  file_r, func_r, line_r,
368  message_r ) );
369  }
370 
371  private:
372  typedef shared_ptr<Loglinestream> StreamPtr;
373  typedef std::map<LogLevel,StreamPtr> StreamSet;
374  typedef std::map<std::string,StreamSet> StreamTable;
377 
378  private:
383  : _no_stream( NULL )
384  , _excessive( getenv("ZYPP_FULLLOG") )
385  , _lineFormater( new LogControl::LineFormater )
386  {
387  if ( getenv("ZYPP_LOGFILE") )
388  logfile( getenv("ZYPP_LOGFILE") );
389 
390  if ( getenv("ZYPP_PROFILING") )
391  {
392  shared_ptr<LogControl::LineFormater> formater(new ProfilingFormater);
393  setLineFormater(formater);
394  }
395  }
396 
398  {
399  _lineWriter.reset();
400  }
401 
402  public:
409  static LogControlImpl & instance();
410  };
412 
413  // 'THE' LogControlImpl singleton
415  {
416  static LogControlImpl _instance;
417  return _instance;
418  }
419 
421 
423  inline std::ostream & operator<<( std::ostream & str, const LogControlImpl & obj )
424  {
425  return str << "LogControlImpl";
426  }
427 
429  //
430  // Access from logger::
431  //
433 
434  std::ostream & getStream( const char * group_r,
435  LogLevel level_r,
436  const char * file_r,
437  const char * func_r,
438  const int line_r )
439  {
440  return LogControlImpl::instance().getStream( group_r,
441  level_r,
442  file_r,
443  func_r,
444  line_r );
445  }
446 
448  inline void putStream( const std::string & group_r, LogLevel level_r,
449  const char * file_r, const char * func_r, int line_r,
450  const std::string & buffer_r )
451  {
452  LogControlImpl::instance().putStream( group_r, level_r,
453  file_r, func_r, line_r,
454  buffer_r );
455  }
456 
457  bool isExcessive()
458  { return LogControlImpl::instance().isExcessive(); }
459 
461  } // namespace logger
463 
465  //
466  // CLASS NAME : LogControl
467  // Forward to LogControlImpl singleton.
468  //
470 
471  using logger::LogControlImpl;
472 
473  void LogControl::logfile( const Pathname & logfile_r )
474  { LogControlImpl::instance().logfile( logfile_r ); }
475 
476  void LogControl::logfile( const Pathname & logfile_r, mode_t mode_r )
477  { LogControlImpl::instance().logfile( logfile_r, mode_r ); }
478 
479  shared_ptr<LogControl::LineWriter> LogControl::getLineWriter() const
481 
482  void LogControl::setLineWriter( const shared_ptr<LineWriter> & writer_r )
483  { LogControlImpl::instance().setLineWriter( writer_r ); }
484 
485  void LogControl::setLineFormater( const shared_ptr<LineFormater> & formater_r )
486  { LogControlImpl::instance().setLineFormater( formater_r ); }
487 
489  { LogControlImpl::instance().setLineWriter( shared_ptr<LineWriter>() ); }
490 
492  { LogControlImpl::instance().setLineWriter( shared_ptr<LineWriter>( new log::StderrLineWriter ) ); }
493 
495  //
496  // LogControl::TmpExcessive
497  //
500  { LogControlImpl::instance().excessive( true ); }
502  { LogControlImpl::instance().excessive( false ); }
503 
504  /******************************************************************
505  **
506  ** FUNCTION NAME : operator<<
507  ** FUNCTION TYPE : std::ostream &
508  */
509  std::ostream & operator<<( std::ostream & str, const LogControl & obj )
510  {
511  return str << LogControlImpl::instance();
512  }
513 
515  } // namespace base
518 } // namespace zypp
std::map< LogLevel, StreamPtr > StreamSet
Definition: LogControl.cc:373
Osd & operator<<(Tp &&val)
Definition: Logger.h:48
LogLevel
Definition of log levels.
Definition: Logger.h:135
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:333
static constexpr std::string_view MA
Definition: LogControl.cc:47
Base class for ostream based LineWriter.
Definition: LogControl.h:44
std::ostream & _strlog
Definition: Logger.h:59
void tagSet(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:189
Loglinestream(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:254
static constexpr std::string_view WH
Definition: LogControl.cc:42
const char * c_str() const
String representation.
Definition: Pathname.h:110
String related utilities and Regular expression matching.
std::ostream & _strout
Definition: Logger.h:58
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
Osd(std::ostream &, int=0)
Definition: LogControl.cc:75
void setLineWriter(const shared_ptr< LogControl::LineWriter > &writer_r)
NULL _lineWriter indicates no loggin.
Definition: LogControl.cc:299
void logfile(const Pathname &logfile_r, mode_t mode_r=0640)
Definition: LogControl.cc:314
void logfile(const Pathname &logfile_r)
Set path for the logfile.
Definition: LogControl.cc:473
static LogControl instance()
Singleton access.
Definition: LogControl.h:102
std::ostream & operator<<(std::ostream &str, const LogControlImpl &obj)
Definition: LogControl.cc:423
void setLineWriter(const shared_ptr< LineWriter > &writer_r)
Assign a LineWriter.
Definition: LogControl.cc:482
void logToStdErr()
Log to std::err.
Definition: LogControl.cc:491
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
const char * _fnc
Definition: Logger.h:36
TraceLeave(const TraceLeave &)=delete
const std::string & _buffer
Definition: PluginScript.cc:62
shared_ptr< LogControl::LineWriter > getLineWriter() const
Definition: LogControl.cc:302
const std::string & asString() const
String representation.
Definition: Pathname.h:91
static constexpr std::string_view GR
Definition: LogControl.cc:45
friend std::ostream & operator<<(std::ostream &str, const LogControl &obj)
Definition: LogControl.cc:509
static constexpr std::string_view YE
Definition: LogControl.cc:44
#define USR
Definition: Logger.h:101
virtual int overflow(int ch=EOF)
Definition: LogControl.cc:201
void setLineFormater(const shared_ptr< LogControl::LineFormater > &format_r)
Assert _lineFormater is not NULL.
Definition: LogControl.cc:306
shared_ptr< LogControl::LineFormater > _lineFormater
Definition: LogControl.cc:328
std::ostream & getStream(const char *fil_r, const char *fnc_r, int lne_r)
Definition: LogControl.cc:264
std::map< std::string, StreamSet > StreamTable
Definition: LogControl.cc:374
static constexpr std::string_view RE
Definition: LogControl.cc:46
static unsigned _depth
Definition: Logger.h:34
void logNothing()
Turn off logging.
Definition: LogControl.cc:488
#define L_USR(GROUP)
Definition: Logger.h:110
virtual std::string format(const std::string &, logger::LogLevel, const char *, const char *, int, const std::string &)
Definition: LogControl.cc:139
Maintain logfile related options.
Definition: LogControl.h:96
virtual int writeout(const char *s, std::streamsize n)
Definition: LogControl.cc:211
static constexpr std::string_view OO
Definition: LogControl.cc:41
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:448
shared_ptr< LogControl::LineWriter > _lineWriter
Definition: LogControl.cc:329
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:358
virtual std::streamsize xsputn(const char *s, std::streamsize n)
Definition: LogControl.cc:198
shared_ptr< LineWriter > getLineWriter() const
Get the current LineWriter.
Definition: LogControl.cc:479
static LogControlImpl & instance()
The LogControlImpl singleton.
Definition: LogControl.cc:414
Loglinebuf(const std::string &group_r, LogLevel level_r)
Definition: LogControl.cc:174
Pathname _file
Definition: SystemCheck.cc:34
void setLineFormater(const shared_ptr< LineFormater > &formater_r)
Assign a LineFormater.
Definition: LogControl.cc:485
shared_ptr< void > _outs
Definition: LogControl.h:76
shared_ptr< Loglinestream > StreamPtr
Definition: LogControl.cc:372
const char * _file
Definition: Logger.h:35
Excessive logging.
Definition: Logger.h:136
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
std::string tracestr(char tag_r, unsigned depth_r, const char *file_r, const char *fnc_r, int line_r)
Definition: LogControl.cc:51
static constexpr std::string_view CY
Definition: LogControl.cc:43
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:434
LogControl implementation (Singleton).
Definition: LogControl.cc:289
FileLineWriter(const Pathname &file_r, mode_t mode_r=0)
Definition: LogControl.cc:104
StreamTable _streamtable
one streambuffer per group and level
Definition: LogControl.cc:376