ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Logger.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Logger.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 // STL include(s)
11 #include <ctime>
12 #include <functional>
13 #include <iomanip>
14 #include <iostream>
15 #include <memory>
16 #include <sstream>
17 #include <string>
18 #include <thread>
19 
20 // clang-format off
25 // <tt>std::unique_ptr<const Acts::Logger></tt>
43 #define ACTS_LOCAL_LOGGER(log_object) \
44  struct __local_acts_logger \
45  { \
46  __local_acts_logger(std::unique_ptr<const ::Acts::Logger> logger): \
47  m_logger(std::move(logger)) \
48  {} \
49  \
50  const ::Acts::Logger& operator()() const \
51  { \
52  return *m_logger; \
53  } \
54  \
55  std::unique_ptr<const ::Acts::Logger> m_logger; \
56  }; \
57  __local_acts_logger logger(log_object);
58 
69 #define ACTS_VERBOSE(x) \
70  if (logger().doPrint(Acts::Logging::VERBOSE)) \
71  logger().log(Acts::Logging::VERBOSE) << x;
72 
83 #define ACTS_DEBUG(x) \
84  if (logger().doPrint(Acts::Logging::DEBUG)) \
85  logger().log(Acts::Logging::DEBUG) << x;
86 
97 #define ACTS_INFO(x) \
98  if (logger().doPrint(Acts::Logging::INFO)) \
99  logger().log(Acts::Logging::INFO) << x;
100 
111 #define ACTS_WARNING(x) \
112  if (logger().doPrint(Acts::Logging::WARNING)) \
113  logger().log(Acts::Logging::WARNING) << x;
114 
125 #define ACTS_ERROR(x) \
126  if (logger().doPrint(Acts::Logging::ERROR)) \
127  logger().log(Acts::Logging::ERROR) << x;
128 
139 #define ACTS_FATAL(x) \
140  if (logger().doPrint(Acts::Logging::FATAL)) \
141  logger().log(Acts::Logging::FATAL) << x;
142 // clang-format on
143 
144 namespace Acts {
145 
148 namespace Logging {
153 enum Level {
154  VERBOSE = 0,
160 };
161 
167  public:
169  virtual ~OutputPrintPolicy() = default;
170 
175  virtual void flush(const Level& lvl, const std::ostringstream& input) = 0;
176 };
177 
183  public:
185  virtual ~OutputFilterPolicy() = default;
186 
193  virtual bool doPrint(const Level& lvl) const = 0;
194 };
195 
201 class OutStream final {
203  using OutputFunc = std::function<void(const std::ostringstream&)>;
204 
205  public:
210  explicit OutStream(OutputFunc output)
211  : m_stream(), m_outputFunctor(std::move(output)) {}
212 
218  m_stream << copy.m_stream.str();
219  }
220 
226 
232  template <typename T>
233  OutStream& operator<<(T&& input) {
234  m_stream << std::forward<T>(input);
235  return *this;
236  }
237 
243  template <typename T>
245  f(m_stream);
246  return *this;
247  }
248 
249  private:
251  std::ostringstream m_stream;
252 
255 };
256 
262  public:
266  explicit DefaultFilterPolicy(const Level& lvl) : m_level(lvl) {}
267 
269  ~DefaultFilterPolicy() override = default;
270 
276  bool doPrint(const Level& lvl) const override { return m_level <= lvl; }
277 
278  private:
281 };
282 
289  public:
294  explicit OutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee)
295  : m_wrappee(std::move(wrappee)) {}
296 
304  void flush(const Level& lvl, const std::ostringstream& input) override {
305  m_wrappee->flush(lvl, input);
306  }
307 
308  private:
310  std::unique_ptr<OutputPrintPolicy> m_wrappee;
311 };
312 
316 class NamedOutputDecorator final : public OutputDecorator {
317  public:
323  NamedOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee,
324  const std::string& name, unsigned int maxWidth = 15)
325  : OutputDecorator(std::move(wrappee)),
326  m_name(name),
327  m_maxWidth(maxWidth) {}
328 
336  void flush(const Level& lvl, const std::ostringstream& input) override {
337  std::ostringstream os;
338  os << std::left << std::setw(m_maxWidth) << m_name.substr(0, m_maxWidth - 3)
339  << input.str();
340  OutputDecorator::flush(lvl, os);
341  }
342 
343  private:
345  std::string m_name;
346 
348  unsigned int m_maxWidth;
349 };
350 
354 class TimedOutputDecorator final : public OutputDecorator {
355  public:
360  TimedOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee,
361  const std::string& format = "%X")
362  : OutputDecorator(std::move(wrappee)), m_format(format) {}
363 
371  void flush(const Level& lvl, const std::ostringstream& input) override {
372  std::ostringstream os;
373  os << std::left << std::setw(12) << now() << input.str();
374  OutputDecorator::flush(lvl, os);
375  }
376 
377  private:
381  std::string now() const {
382  char buffer[20];
383  time_t t;
384  std::time(&t);
385  std::strftime(buffer, sizeof(buffer), m_format.c_str(), localtime(&t));
386  return buffer;
387  }
388 
390  std::string m_format;
391 };
392 
397  public:
401  explicit ThreadOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee)
402  : OutputDecorator(std::move(wrappee)) {}
403 
411  void flush(const Level& lvl, const std::ostringstream& input) override {
412  std::ostringstream os;
413  os << std::left << std::setw(20) << std::this_thread::get_id()
414  << input.str();
415  OutputDecorator::flush(lvl, os);
416  }
417 };
418 
422 class LevelOutputDecorator final : public OutputDecorator {
423  public:
427  explicit LevelOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee)
428  : OutputDecorator(std::move(wrappee)) {}
429 
437  void flush(const Level& lvl, const std::ostringstream& input) override {
438  std::ostringstream os;
439  os << std::left << std::setw(10) << toString(lvl) << input.str();
440  OutputDecorator::flush(lvl, os);
441  }
442 
443  private:
449  std::string toString(const Level& lvl) const {
450  static const char* const buffer[] = {"VERBOSE", "DEBUG", "INFO",
451  "WARNING", "ERROR", "FATAL"};
452  return buffer[lvl];
453  }
454 };
455 
460 class DefaultPrintPolicy final : public OutputPrintPolicy {
461  public:
467  explicit DefaultPrintPolicy(std::ostream* out = &std::cout) : m_out(out) {}
468 
473  void flush(const Level& /*lvl*/, const std::ostringstream& input) final {
474  (*m_out) << input.str() << std::endl;
475  }
476 
477  private:
479  std::ostream* m_out;
480 };
481 } // namespace Logging
482 
489 class Logger {
490  public:
495  Logger(std::unique_ptr<Logging::OutputPrintPolicy> pPrint,
496  std::unique_ptr<Logging::OutputFilterPolicy> pFilter)
497  : m_printPolicy(std::move(pPrint)), m_filterPolicy(std::move(pFilter)) {}
498 
504  bool doPrint(const Logging::Level& lvl) const {
505  return m_filterPolicy->doPrint(lvl);
506  }
507 
520  m_printPolicy.get(), lvl,
521  std::placeholders::_1));
522  }
523 
524  private:
526  std::unique_ptr<Logging::OutputPrintPolicy> m_printPolicy;
527 
529  std::unique_ptr<Logging::OutputFilterPolicy> m_filterPolicy;
530 };
531 
545 std::unique_ptr<const Logger> getDefaultLogger(
546  const std::string& name, const Logging::Level& lvl,
547  std::ostream* log_stream = &std::cout);
548 
549 } // namespace Acts