Logo ROOT   6.14/05
Reference Guide
TLogger.hxx
Go to the documentation of this file.
1 /// \file ROOT/TLogger.h
2 /// \ingroup Base ROOT7
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2015-03-29
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6 /// is welcome!
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #ifndef ROOT7_TLog
17 #define ROOT7_TLog
18 
19 #include <array>
20 #include <memory>
21 #include <sstream>
22 #include "ROOT/RStringView.hxx"
23 #include <vector>
24 
25 namespace ROOT {
26 namespace Experimental {
27 
28 /**
29  Kinds of diagnostics.
30  */
31 enum class ELogLevel {
32  kDebug, ///< Debug information; only useful for developers
33  kInfo, ///< Informational messages; used for instance for tracing
34  kWarning, ///< Warnings about likely unexpected behavior
35  kError,
36  kFatal
37 };
38 
39 class TLogEntry;
40 
41 /**
42  Abstract TLogHandler base class. ROOT logs everything from info to error
43  to entities of this class.
44  */
45 class TLogHandler {
46 public:
47  virtual ~TLogHandler();
48  /// Emit a log entry.
49  /// \param entry - the TLogEntry to be emitted.
50  /// \returns false if further emission of this Log should be suppressed.
51  ///
52  /// \note This function is called concurrently; log emission must be locked
53  /// if needed. (The default log handler using ROOT's DefaultErrorHandler is locked.)
54  virtual bool Emit(const TLogEntry &entry) = 0;
55 };
56 
57 
58 /**
59  A TLogHandler that multiplexes diagnostics to different client `TLogHandler`s.
60  `TLogHandler::Get()` returns the process's (static) log manager.
61  */
62 
63 class TLogManager: public TLogHandler {
64 private:
65  std::vector<std::unique_ptr<TLogHandler>> fHandlers;
66 
67  long long fNumWarnings{0};
68  long long fNumErrors{0};
69 
70  /// Initialize taking a TLogHandlerDefault.
71  TLogManager(std::unique_ptr<TLogHandler> &&lh) { fHandlers.emplace_back(std::move(lh)); }
72 
73 public:
74  static TLogManager &Get();
75 
76  /// Add a TLogHandler in the front - to be called before all others.
77  void PushFront(std::unique_ptr<TLogHandler> handler) { fHandlers.insert(fHandlers.begin(), std::move(handler)); }
78 
79  /// Add a TLogHandler in the back - to be called after all others.
80  void PushBack(std::unique_ptr<TLogHandler> handler) { fHandlers.emplace_back(std::move(handler)); }
81 
82  // Emit a `TLogEntry` to the TLogHandlers.
83  // Returns false if further emission of this Log should be suppressed.
84  bool Emit(const TLogEntry &entry) override
85  {
86  for (auto &&handler: fHandlers)
87  if (!handler->Emit(entry))
88  return false;
89  return true;
90  }
91 
92  /// Returns the current number of warnings seen by this log manager.
93  long long GetNumWarnings() const { return fNumWarnings; }
94 
95  /// Returns the current number of errors seen by this log manager.
96  long long GetNumErrors() const { return fNumErrors; }
97 };
98 
99 /**
100  Object to count the number of warnings and errors emitted by a section of code,
101  after construction of this type.
102  */
104 private:
105  /// The number of the TLogManager's emitted warnings at construction time of *this.
106  long long fInitialWarnings{TLogManager::Get().GetNumWarnings()};
107  /// The number of the TLogManager's emitted errors at construction time.
108  long long fInitialErrors{TLogManager::Get().GetNumErrors()};
109 
110 public:
111  /// Get the number of warnings that the TLogManager has emitted since construction of *this.
112  long long GetAccumulatedWarnings() const { return TLogManager::Get().GetNumWarnings() - fInitialWarnings; }
113 
114  /// Get the number of errors that the TLogManager has emitted since construction of *this.
115  long long GetAccumulatedErrors() const { return TLogManager::Get().GetNumErrors() - fInitialErrors; }
116 
117  /// Whether the TLogManager has emitted a warnings since construction time of *this.
118  bool HasWarningOccurred() const { return GetAccumulatedWarnings(); }
119 
120  /// Whether the TLogManager has emitted an error since construction time of *this.
121  bool HasErrorOccurred() const { return GetAccumulatedErrors(); }
122 
123  /// Whether the TLogManager has emitted an error or a warning since construction time of *this.
124  bool HasErrorOrWarningOccurred() const { return HasWarningOccurred() || HasErrorOccurred(); }
125 };
126 
127 /**
128  A diagnostic, emitted by the TLogManager upon destruction of the TLogEntry.
129  One can construct a TLogEntry through the utility preprocessor macros R__ERROR_HERE, R__WARNING_HERE etc
130  like this:
131  R__INFO_HERE("CodeGroupForInstanceLibrary") << "All we know is " << 42;
132  This will automatically capture the current class and function name, the file and line number.
133  */
134 
135 class TLogEntry: public std::ostringstream {
136 public:
137  std::string fGroup;
138  std::string fFile;
139  std::string fFuncName;
140  int fLine = 0;
142 
143 public:
144  TLogEntry() = default;
145  TLogEntry(ELogLevel level, std::string_view group): fGroup(group), fLevel(level) {}
147  : fGroup(group), fFile(filename), fFuncName(funcname), fLine(line), fLevel(level)
148  {}
149 
150  TLogEntry &SetFile(const std::string &file)
151  {
152  fFile = file;
153  return *this;
154  }
155  TLogEntry &SetFunction(const std::string &func)
156  {
157  fFuncName = func;
158  return *this;
159  }
161  {
162  fLine = line;
163  return *this;
164  }
165 
167 };
168 
169 } // namespace Experimental
170 } // namespace ROOT
171 
172 #if defined(_MSC_VER)
173 #define R__LOG_PRETTY_FUNCTION __FUNCSIG__
174 #else
175 #define R__LOG_PRETTY_FUNCTION __PRETTY_FUNCTION__
176 #endif
177 
178 #define R__LOG_HERE(LEVEL, GROUP) \
179  ROOT::Experimental::TLogEntry(LEVEL, GROUP).SetFile(__FILE__).SetLine(__LINE__).SetFunction(R__LOG_PRETTY_FUNCTION)
180 
181 #define R__FATAL_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kFatal, GROUP)
182 #define R__ERROR_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kError, GROUP)
183 #define R__WARNING_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kWarning, GROUP)
184 #define R__INFO_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kInfo, GROUP)
185 #define R__DEBUG_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kDebug, GROUP)
186 
187 #endif
TLogEntry & SetLine(int line)
Definition: TLogger.hxx:160
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
TLogEntry(ELogLevel level, std::string_view group)
Definition: TLogger.hxx:145
TLine * line
void PushBack(std::unique_ptr< TLogHandler > handler)
Add a TLogHandler in the back - to be called after all others.
Definition: TLogger.hxx:80
long long GetNumWarnings() const
Returns the current number of warnings seen by this log manager.
Definition: TLogger.hxx:93
long long GetAccumulatedWarnings() const
Get the number of warnings that the TLogManager has emitted since construction of *this...
Definition: TLogger.hxx:112
void PushFront(std::unique_ptr< TLogHandler > handler)
Add a TLogHandler in the front - to be called before all others.
Definition: TLogger.hxx:77
TLogEntry(ELogLevel level, std::string_view group, std::string_view filename, int line, std::string_view funcname)
Definition: TLogger.hxx:146
bool Emit(const TLogEntry &entry) override
Emit a log entry.
Definition: TLogger.hxx:84
TLogEntry & SetFile(const std::string &file)
Definition: TLogger.hxx:150
TLogManager(std::unique_ptr< TLogHandler > &&lh)
Initialize taking a TLogHandlerDefault.
Definition: TLogger.hxx:71
bool HasErrorOrWarningOccurred() const
Whether the TLogManager has emitted an error or a warning since construction time of *this...
Definition: TLogger.hxx:124
Informational messages; used for instance for tracing.
A TLogHandler that multiplexes diagnostics to different client TLogHandlers.
Definition: TLogger.hxx:63
A diagnostic, emitted by the TLogManager upon destruction of the TLogEntry.
Definition: TLogger.hxx:135
static TLogManager & Get()
Definition: TLogger.cxx:54
std::vector< std::unique_ptr< TLogHandler > > fHandlers
Definition: TLogger.hxx:65
Warnings about likely unexpected behavior.
Object to count the number of warnings and errors emitted by a section of code, after construction of...
Definition: TLogger.hxx:103
Abstract TLogHandler base class.
Definition: TLogger.hxx:45
long long GetAccumulatedErrors() const
Get the number of errors that the TLogManager has emitted since construction of *this.
Definition: TLogger.hxx:115
basic_string_view< char > string_view
Definition: RStringView.hxx:35
bool HasErrorOccurred() const
Whether the TLogManager has emitted an error since construction time of *this.
Definition: TLogger.hxx:121
Definition: file.py:1
TLogEntry & SetFunction(const std::string &func)
Definition: TLogger.hxx:155
Debug information; only useful for developers.
ELogLevel
Kinds of diagnostics.
Definition: TLogger.hxx:31
long long GetNumErrors() const
Returns the current number of errors seen by this log manager.
Definition: TLogger.hxx:96
bool HasWarningOccurred() const
Whether the TLogManager has emitted a warnings since construction time of *this.
Definition: TLogger.hxx:118