LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
MessageLogger.h
Go to the documentation of this file.
1 #ifndef messagefacility_MessageLogger_MessageLogger_h
2 #define messagefacility_MessageLogger_MessageLogger_h
3 // vim: set sw=2 expandtab :
4 
7 
8 #include <memory>
9 #include <ostream>
10 #include <string>
11 #include <type_traits>
12 #include <utility>
13 
14 namespace fhicl {
15 
16  class ParameterSet;
17 
18 } // namespace fhicl
19 
20 namespace mf {
21 
22  // Start and stop the system.
23  // The system is still usable if StartMessageFacility has not been called, but
24  // it logs only to cerr and does not process any configuration options.
26  std::string const& applicationName = "");
27  void EndMessageFacility();
28 
29  // Will return true if StartMessageFacility has been called, and
30  // EndMessageFacility has not yet been called.
32 
33  // Log a message.
34  void LogErrorObj(ErrorObj*);
35 
36  // Log collected statistics to configured statistics destinations.
37  void LogStatistics();
38 
39  // OBSOLETE. Does nothing.
40  void FlushMessageLog();
41 
42  // These four set the system-wide values, but they can still be
43  // overridden on a per-message basis.
44  void SetApplicationName(std::string const&);
45  void SetHostName(std::string const&);
46  void SetHostAddr(std::string const&);
47  void SetPid(long);
48 
49  // These four set the system-wide values, but they can still be
50  // overridden on a per-message basis.
51  std::string const& GetApplicationName();
52  std::string const& GetHostName();
53  std::string const& GetHostAddr();
54  long GetPid();
55 
56  // What is printed in the message header as the iteration (either
57  // run/subrun/event number or phase), thread-local. Note: Obsolete! Remove
58  // when user code migrated.
59  void SetContextIteration(std::string const&);
60 
61  // What is printed in the message header as the iteration (either
62  // run/subrun/event number or phase), thread-local.
63  void SetIteration(std::string const&);
64 
65  // What is printed in the message header as the iteration (either
66  // run/subrun/event number or phase), thread-local.
67  std::string const& GetIteration();
68 
69  // What is printed in the message header as the module name, thread-local.
70  // Note: Obsolete! Remove when user code migrated.
71  void SetContextSinglet(std::string const&);
72 
73  // What is printed in the message header as the module name, thread-local.
74  void SetModuleName(std::string const&);
75 
76  // What is printed in the message header as the module name, thread-local.
77  std::string const& GetModuleName();
78 
79  // Obsolete! Delete these when user code migrated.
80  bool isDebugEnabled();
81  bool isInfoEnabled();
82  bool isWarningEnabled();
83 
84  class NeverLogger_ {
85  public:
86 
87  // Dedicated function for char const* to avoid unnecessary
88  // template instantiations of char const[]. Will take precedence
89  // over the template version.
90  decltype(auto) operator<<(char const*)
91  {
92  return std::forward<NeverLogger_>(*this);
93  }
94 
95  template <class T>
96  decltype(auto) operator<<(T const&)
97  {
98  return std::forward<NeverLogger_>(*this);
99  }
100 
101  decltype(auto)
102  operator<<(std::ostream& (*)(std::ostream&))
103  {
104  return std::forward<NeverLogger_>(*this);
105  }
106  decltype(auto)
107  operator<<(std::ios_base& (*)(std::ios_base&))
108  {
109  return std::forward<NeverLogger_>(*this);
110  }
111  };
112 
113  template <ELseverityLevel::ELsev_ SEV, bool VERBATIM>
114  class MaybeLogger_ {
115 
116  public:
117  MaybeLogger_(MaybeLogger_ const&) = delete;
118  MaybeLogger_& operator=(MaybeLogger_ const&) = delete;
119  MaybeLogger_& operator=(MaybeLogger_&&) = delete;
120 
122  {
123  if (msg_ == nullptr) {
124  return;
125  }
126  try {
127  msg_->setModule(GetModuleName());
128  msg_->setIteration(GetIteration());
129  LogErrorObj(msg_.release());
130  }
131  catch (...) {
132  // FIXME: We should never ignore errors!
133  }
134  }
135 
136  MaybeLogger_() : msg_{} {}
137 
138  MaybeLogger_(MaybeLogger_&& rhs) noexcept : msg_{std::move(rhs.msg_)} {}
139 
140  MaybeLogger_(std::string const& category,
141  std::string const& file = "",
142  int line_number = 0)
143  : msg_{}
144  {
145  // Verbatim messages have the full file path, otherwise just the basename.
146  std::string filename{file};
147  if (!VERBATIM) {
148  auto const lastSlash = file.find_last_of('/');
149  if ((lastSlash != std::string::npos) &&
150  (lastSlash != (file.size() - 1))) {
151  filename = file.substr(lastSlash + 1, file.size() - lastSlash - 1);
152  }
153  }
154  msg_ = std::move(std::make_unique<ErrorObj>(
155  SEV, category, VERBATIM, filename, line_number));
156  }
157 
158  // Dedicated function for char const* to avoid unnecessary
159  // template instantiations of char const[]. Will take precedence
160  // over the template version.
161  decltype(auto) operator<<(char const* s)
162  {
163  if (msg_) {
164  (*msg_) << s;
165  }
166  return std::forward<MaybeLogger_>(*this);
167  }
168 
169  template <class T>
170  decltype(auto)
171  operator<<(T const& t)
172  {
173  if (msg_) {
174  (*msg_) << t;
175  }
176  return std::forward<MaybeLogger_>(*this);
177  }
178 
179  decltype(auto)
180  operator<<(std::ostream& (*f)(std::ostream&))
181  {
182  if (msg_) {
183  (*msg_) << f;
184  }
185  return std::forward<MaybeLogger_>(*this);
186  }
187 
188  decltype(auto)
189  operator<<(std::ios_base& (*f)(std::ios_base&))
190  {
191  if (msg_) {
192  (*msg_) << f;
193  }
194  return std::forward<MaybeLogger_>(*this);
195  }
196 
197  private:
198  std::unique_ptr<ErrorObj> msg_{};
199  };
200 
201  //
202  // Usage: LogXXX("category") << stuff. See also LOG_XXX macros, below.
203  //
204  // Statements follow pattern:
205  // using LogXXX = MaybeLogger_<severity-level, verbatim>;
206  //
207  // Verbatim: "No-frills" formatting.
208  //
209 
210  // Non-verbatim messages, standard decorations.
216 
217  // Verbatim messages, no decorations at all.
223 
224 } // namespace mf
225 
226 // Non-verbatim messages, standard decorations.
227 // Note: LOG_DEBUG is below.
228 #define LOG_INFO(category) mf::LogInfo(category, __FILE__, __LINE__)
229 #define LOG_WARNING(category) mf::LogWarning(category, __FILE__, __LINE__)
230 #define LOG_ERROR(category) mf::LogError(category, __FILE__, __LINE__)
231 #define LOG_SYSTEM(category) mf::LogSystem(category, __FILE__, __LINE__)
232 
233 // Verbatim messages, no decorations at all.
234 // Note: LOG_TRACE is below.
235 #define LOG_VERBATIM(category) mf::LogVerbatim(category, __FILE__, __LINE__)
236 #define LOG_PRINT(category) mf::LogPrint(category, __FILE__, __LINE__)
237 #define LOG_PROBLEM(category) mf::LogProblem(category, __FILE__, __LINE__)
238 #define LOG_ABSOLUTE(category) mf::LogAbsolute(category, __FILE__, __LINE__)
239 
240 #undef EDM_MESSAGELOGGER_SUPPRESS_LOGDEBUG
241 
242 // Suppress LOG_DEBUG/TRACE if NDEBUG or ML_NDEBUG are set,
243 // except see below for ML_DEBUG which takes precendence.
244 #if defined(NDEBUG) || defined(ML_NDEBUG)
245 #define EDM_MESSAGELOGGER_SUPPRESS_LOGDEBUG
246 #endif // NDEBUG || ML_NDEBUG
247 
248 // If ML_DEBUG is defined, LOG_DEBUG/TRACE are active unconditionally,
249 // no matter what NDEBUG or ML_NDEBUG say.
250 #ifdef ML_DEBUG
251 #undef EDM_MESSAGELOGGER_SUPPRESS_LOGDEBUG
252 #endif // ML_DEBUG
253 
254 #ifdef EDM_MESSAGELOGGER_SUPPRESS_LOGDEBUG
255 
256 #define LOG_DEBUG(id) \
257  mf::NeverLogger_ {}
258 #define LOG_TRACE(id) \
259  mf::NeverLogger_ {}
260 
261 #else // EDM_MESSAGELOGGER_SUPPRESS_LOGDEBUG
262 
263 #define LOG_DEBUG(id) \
264  mf::LogDebug { id, __FILE__, __LINE__ }
265 #define LOG_TRACE(id) \
266  mf::LogTrace { id, __FILE__, __LINE__ }
267 
268 #endif // EDM_MESSAGELOGGER_SUPPRESS_LOGDEBUG
269 
270 #undef EDM_MESSAGELOGGER_SUPPRESS_LOGDEBUG
271 
272 #endif /* messagefacility_MessageLogger_MessageLogger_h */
273 
274 // Local Variables:
275 // mode: c++
276 // End:
MaybeLogger_(std::string const &category, std::string const &file="", int line_number=0)
Float_t s
Definition: plot.C:23
void SetIteration(string const &val)
void SetHostAddr(string const &hostaddr)
void EndMessageFacility()
MaybeLogger_(MaybeLogger_ &&rhs) noexcept
string const & GetModuleName()
STL namespace.
void FlushMessageLog()
void SetContextIteration(string const &val)
TFile f
Definition: plotHisto.C:6
bool isMessageProcessingSetUp()
void StartMessageFacility(fhicl::ParameterSet const &pset, string const &applicationName)
bool isWarningEnabled()
void SetPid(long pid)
bool isInfoEnabled()
parameter set interface
bool isDebugEnabled()
void LogStatistics()
void SetHostName(string const &hostname)
string const & GetHostName()
string const & GetIteration()
TFile * file
void SetContextSinglet(string const &val)
void LogErrorObj(ErrorObj *msg)
void SetModuleName(string const &val)
void SetApplicationName(string const &applicationName)
string const & GetApplicationName()
string const & GetHostAddr()
long GetPid()