LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Log.h
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2013-2014 LSST Corporation.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <http://www.lsstcorp.org/LegalNotices/>.
21  */
22 
32 #ifndef LSST_LOG_LOG_H
33 #define LSST_LOG_LOG_H
34 
35 
36 // System headers
37 #include <functional>
38 #include <sstream>
39 #include <stdarg.h>
40 #include <string>
41 
42 // Third-party headers
43 #include <log4cxx/logger.h>
44 #include <boost/format.hpp>
45 
52 #define LOG_CONFIG(filename) lsst::log::Log::configure(filename)
53 
66 #define LOG_CONFIG_PROP(string) lsst::log::Log::configure_prop(string)
67 
75 #define LOG_GET(logger) lsst::log::Log::getLogger(logger)
76 
85 #define LOG_GET_CHILD(logger, suffix) lsst::log::Log::getLogger(logger).getChild(suffix)
86 
97 #define LOG_MDC(key, value) lsst::log::Log::MDC(key, value)
98 
105 #define LOG_MDC_REMOVE(key) lsst::log::Log::MDCRemove(key)
106 
115 // These two macros generate unique variable name using __COUNTER__ built-in
116 // macro. Two levels of calls is needed to use __COUNTER__ macro value instead
117 // of the macro name in concatenation.
118 #define LOG_CONCAT_IMPL(a, b) a ## b
119 #define LOG_CONCAT_IMPL2(a, b) LOG_CONCAT_IMPL(a, b)
120 #define LOG_MDC_SCOPE(key, value) lsst::log::LogMDCScope LOG_CONCAT_IMPL2(_log_mdc_scope_, __COUNTER__)(key, value);
121 
142 #define LOG_MDC_INIT(func) lsst::log::Log::MDCRegisterInit(std::function<void()>(func))
143 
151 #define LOG_SET_LVL(logger, level) \
152  lsst::log::Log::getLogger(logger).setLevel(level)
153 
162 #define LOG_GET_LVL(logger) \
163  lsst::log::Log::getLogger(logger).getLevel()
164 
173 #define LOG_GETEFF_LVL(logger) \
174  lsst::log::Log::getLogger(logger).getEffectiveLevel()
175 
185 #define LOG_CHECK_LVL(logger, level) \
186  lsst::log::Log::getLogger(logger).isEnabledFor(level)
187 
194 #define LOG_CHECK_TRACE() \
195  LOG4CXX_UNLIKELY(lsst::log::Log::getDefaultLogger().isTraceEnabled())
196 
203 #define LOG_CHECK_DEBUG() \
204  LOG4CXX_UNLIKELY(lsst::log::Log::getDefaultLogger().isDebugEnabled())
205 
212 #define LOG_CHECK_INFO() \
213  lsst::log::Log::getDefaultLogger().isInfoEnabled()
214 
221 #define LOG_CHECK_WARN() \
222  lsst::log::Log::getDefaultLogger().isWarnEnabled()
223 
230 #define LOG_CHECK_ERROR() \
231  lsst::log::Log::getDefaultLogger().isErrorEnabled()
232 
239 #define LOG_CHECK_FATAL() \
240  lsst::log::Log::getDefaultLogger().isFatalEnabled()
241 
251 #define LOG(logger, level, message...) \
252  do { \
253  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
254  if (log.isEnabledFor(level)) { \
255  log.log(log4cxx::Level::toLevel(level), LOG4CXX_LOCATION, message); } \
256  } while (false)
257 
266 #define LOG_TRACE(message...) \
267  do { \
268  lsst::log::Log log; \
269  if (LOG4CXX_UNLIKELY(log.isTraceEnabled())) { \
270  log.log(log4cxx::Level::getTrace(), LOG4CXX_LOCATION, message); } \
271  } while (false)
272 
281 #define LOG_DEBUG(message...) \
282  do { \
283  lsst::log::Log log; \
284  if (LOG4CXX_UNLIKELY(log.isDebugEnabled())) { \
285  log.log(log4cxx::Level::getDebug(), LOG4CXX_LOCATION, message); } \
286  } while (false)
287 
296 #define LOG_INFO(message...) \
297  do { \
298  lsst::log::Log log; \
299  if (log.isInfoEnabled()) { \
300  log.log(log4cxx::Level::getInfo(), LOG4CXX_LOCATION, message); } \
301  } while (false)
302 
311 #define LOG_WARN(message...) \
312  do { \
313  lsst::log::Log log; \
314  if (log.isWarnEnabled()) { \
315  log.log(log4cxx::Level::getWarn(), LOG4CXX_LOCATION, message); } \
316  } while (false)
317 
326 #define LOG_ERROR(message...) \
327  do { \
328  lsst::log::Log log; \
329  if (log.isErrorEnabled()) { \
330  log.log(log4cxx::Level::getError(), LOG4CXX_LOCATION, message); } \
331  } while (false)
332 
341 #define LOG_FATAL(message...) \
342  do { \
343  lsst::log::Log log; \
344  if (log.isFatalEnabled()) { \
345  log.log(log4cxx::Level::getFatal(), LOG4CXX_LOCATION, message); } \
346  } while (false)
347 
348 
349 // small internal utility macro, not for regular clients
350 #define LOG_MESSAGE_VIA_STREAM_(logger, level, message) \
351  std::ostringstream stream_; \
352  stream_ << message; \
353  logger.logMsg(level, LOG4CXX_LOCATION, stream_.str())
354 
369 #define LOGS(logger, level, message) \
370  do { \
371  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
372  if (log.isEnabledFor(level)) { \
373  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::toLevel(level), message); \
374  } \
375  } while (false)
376 
388 #define LOGS_TRACE(message) \
389  do { \
390  lsst::log::Log log; \
391  if (LOG4CXX_UNLIKELY(log.isTraceEnabled())) { \
392  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getTrace(), message); \
393  } \
394  } while (false)
395 
407 #define LOGS_DEBUG(message) \
408  do { \
409  lsst::log::Log log; \
410  if (LOG4CXX_UNLIKELY(log.isDebugEnabled())) { \
411  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getDebug(), message); \
412  } \
413  } while (false)
414 
426 #define LOGS_INFO(message) \
427  do { \
428  lsst::log::Log log; \
429  if (log.isInfoEnabled()) { \
430  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getInfo(), message); \
431  } \
432  } while (false)
433 
445 #define LOGS_WARN(message) \
446  do { \
447  lsst::log::Log log; \
448  if (log.isWarnEnabled()) { \
449  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getWarn(), message); \
450  } \
451  } while (false)
452 
464 #define LOGS_ERROR(message) \
465  do { \
466  lsst::log::Log log; \
467  if (log.isErrorEnabled()) { \
468  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getError(), message); \
469  } \
470  } while (false)
471 
483 #define LOGS_FATAL(message) \
484  do { \
485  lsst::log::Log log; \
486  if (log.isFatalEnabled()) { \
487  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getFatal(), message); \
488  } \
489  } while (false)
490 
499 #define LOGL_TRACE(logger, message...) \
500  do { \
501  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
502  if (LOG4CXX_UNLIKELY(log.isTraceEnabled())) { \
503  log.log(log4cxx::Level::getTrace(), LOG4CXX_LOCATION, message);\
504  } \
505  } while (false)
506 
515 #define LOGL_DEBUG(logger, message...) \
516  do { \
517  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
518  if (LOG4CXX_UNLIKELY(log.isDebugEnabled())) { \
519  log.log(log4cxx::Level::getDebug(), LOG4CXX_LOCATION, message); \
520  } \
521  } while (false)
522 
531 #define LOGL_INFO(logger, message...) \
532  do { \
533  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
534  if (log.isInfoEnabled()) { \
535  log.log(log4cxx::Level::getInfo(), LOG4CXX_LOCATION, message); \
536  } \
537  } while (false)
538 
547 #define LOGL_WARN(logger, message...) \
548  do { \
549  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
550  if (log.isWarnEnabled()) { \
551  log.log(log4cxx::Level::getWarn(), LOG4CXX_LOCATION, message); \
552  } \
553  } while (false)
554 
563 #define LOGL_ERROR(logger, message...) \
564  do { \
565  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
566  if (log.isErrorEnabled()) { \
567  log.log(log4cxx::Level::getError(), LOG4CXX_LOCATION, message); \
568  } \
569  } while (false)
570 
579 #define LOGL_FATAL(logger, message...) \
580  do { \
581  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
582  if (log.isFatalEnabled()) { \
583  log.log(log4cxx::Level::getFatal(), LOG4CXX_LOCATION, message); \
584  } \
585  } while (false)
586 
599 #define LOGLS_TRACE(logger, message) \
600  do { \
601  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
602  if (LOG4CXX_UNLIKELY(log.isTraceEnabled())) { \
603  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getTrace(), message); \
604  } \
605  } while (false)
606 
619 #define LOGLS_DEBUG(logger, message) \
620  do { \
621  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
622  if (LOG4CXX_UNLIKELY(log.isDebugEnabled())) { \
623  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getDebug(), message); \
624  } \
625  } while (false)
626 
639 #define LOGLS_INFO(logger, message) \
640  do { \
641  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
642  if (log.isInfoEnabled()) { \
643  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getInfo(), message); \
644  } \
645  } while (false)
646 
659 #define LOGLS_WARN(logger, message) \
660  do { \
661  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
662  if (log.isWarnEnabled()) { \
663  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getWarn(), message); \
664  } \
665  } while (false)
666 
679 #define LOGLS_ERROR(logger, message) \
680  do { \
681  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
682  if (log.isErrorEnabled()) { \
683  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getError(), message); \
684  } \
685  } while (false)
686 
699 #define LOGLS_FATAL(logger, message) \
700  do { \
701  lsst::log::Log log(lsst::log::Log::getLogger(logger)); \
702  if (log.isFatalEnabled()) { \
703  LOG_MESSAGE_VIA_STREAM_(log, log4cxx::Level::getFatal(), message); \
704  } \
705  } while (false)
706 
707 #define LOG_LVL_TRACE static_cast<int>(log4cxx::Level::TRACE_INT)
708 #define LOG_LVL_DEBUG static_cast<int>(log4cxx::Level::DEBUG_INT)
709 #define LOG_LVL_INFO static_cast<int>(log4cxx::Level::INFO_INT)
710 #define LOG_LVL_WARN static_cast<int>(log4cxx::Level::WARN_INT)
711 #define LOG_LVL_ERROR static_cast<int>(log4cxx::Level::ERROR_INT)
712 #define LOG_LVL_FATAL static_cast<int>(log4cxx::Level::FATAL_INT)
713 
714 #define LOG_LOGGER lsst::log::Log
715 
716 namespace lsst {
717 namespace log {
718 
724 class Log {
725 public:
726 
727  /***
728  * Default constructor creates an instance of root logger.
729  */
730  Log() : _logger(_defaultLogger()) { }
731 
735  bool isDebugEnabled() const { return _logger->isDebugEnabled(); }
739  bool isErrorEnabled() const { return _logger->isErrorEnabled(); }
743  bool isFatalEnabled() const { return _logger->isFatalEnabled(); }
747  bool isInfoEnabled() const { return _logger->isInfoEnabled(); }
751  bool isTraceEnabled() const { return _logger->isTraceEnabled(); }
755  bool isWarnEnabled() const { return _logger->isWarnEnabled(); }
756 
757  std::string getName() const;
758  void setLevel(int level);
759  int getLevel() const;
760  int getEffectiveLevel() const;
761  bool isEnabledFor(int level) const;
762 
763  Log getChild(std::string const& suffix) const;
764 
766  static Log getDefaultLogger() { return Log(); }
767 
768  static void configure();
769  static void configure(std::string const& filename);
770  static void configure_prop(std::string const& properties);
771 
772  static Log getLogger(Log const& logger) { return logger; }
773  static Log getLogger(std::string const& loggername);
774 
775  static std::string MDC(std::string const& key, std::string const& value);
776  static void MDCRemove(std::string const& key);
777  static int MDCRegisterInit(std::function<void()> function);
778 
779  void log(log4cxx::LevelPtr level,
780  log4cxx::spi::LocationInfo const& location,
781  char const* fmt, ...);
782  void logMsg(log4cxx::LevelPtr level,
783  log4cxx::spi::LocationInfo const& location,
784  std::string const& msg);
785 
786 private:
787 
794  static log4cxx::LoggerPtr const& _defaultLogger();
795 
802  Log(log4cxx::LoggerPtr const& logger) : Log() { _logger = logger; }
803 
804  log4cxx::LoggerPtr _logger;
805 };
806 
807 class LogMDCScope {
808 public:
809 
814  LogMDCScope(std::string const& key, std::string const& value)
815  : _key(key)
816  {
817  _oldValue = Log::MDC(key, value);
818  }
819 
820  // no copy allowed
821  LogMDCScope(LogMDCScope const&) = delete;
822  LogMDCScope& operator=(LogMDCScope const&) = delete;
823 
825  _key = other._key;
826  _oldValue = other._oldValue;
827  other._key.clear();
828  }
829 
831  if (not _key.empty()) {
832  if (_oldValue.empty()) {
833  Log::MDCRemove(_key);
834  } else {
835  Log::MDC(_key, _oldValue);
836  }
837  }
838  _key = other._key;
839  _oldValue = other._oldValue;
840  other._key.clear();
841  return *this;
842  }
843 
848  if (not _key.empty()) {
849  if (_oldValue.empty()) {
850  Log::MDCRemove(_key);
851  } else {
852  Log::MDC(_key, _oldValue);
853  }
854  }
855  }
856 
857 private:
858  std::string _key;
859  std::string _oldValue;
860 };
861 
869 unsigned lwpID();
870 
871 }} // namespace lsst::log
872 
873 #endif // LSST_LOG_LOG_H
This static class includes a variety of methods for interacting with the the logging module.
Definition: Log.h:724
bool isErrorEnabled() const
Check whether the logger is enabled for the ERROR Level.
Definition: Log.h:739
static Log getDefaultLogger()
Return default logger instance, same as default constructor.
Definition: Log.h:766
static Log getLogger(Log const &logger)
Definition: Log.h:772
static void MDCRemove(std::string const &key)
Remove the value associated with KEY within the MDC.
Definition: Log.cc:288
int getLevel() const
Retrieve the logging threshold.
Definition: Log.cc:318
bool isEnabledFor(int level) const
Return whether the logging threshold of the logger is less than or equal to LEVEL.
Definition: Log.cc:345
void logMsg(log4cxx::LevelPtr level, log4cxx::spi::LocationInfo const &location, std::string const &msg)
Method used by LOGS_INFO and similar macros to process a log message.
Definition: Log.cc:400
bool isTraceEnabled() const
Check whether the logger is enabled for the TRACE Level.
Definition: Log.h:751
Log getChild(std::string const &suffix) const
Return a logger which is a descendant to this logger.
Definition: Log.cc:366
static void configure_prop(std::string const &properties)
Configures log4cxx using a string containing the list of properties, equivalent to configuring from a...
Definition: Log.cc:220
bool isInfoEnabled() const
Check whether the logger is enabled for the INFO Level.
Definition: Log.h:747
void setLevel(int level)
Set the logging threshold to LEVEL.
Definition: Log.cc:311
bool isWarnEnabled() const
Check whether the logger is enabled for the WARN Level.
Definition: Log.h:755
bool isDebugEnabled() const
Check whether the logger is enabled for the DEBUG Level.
Definition: Log.h:735
bool isFatalEnabled() const
Check whether the logger is enabled for the FATAL Level.
Definition: Log.h:743
static void configure()
Explicitly configures log4cxx and initializes logging system.
Definition: Log.cc:177
static std::string MDC(std::string const &key, std::string const &value)
Places a KEY/VALUE pair in the Mapped Diagnostic Context (MDC) for the current thread.
Definition: Log.cc:274
static int MDCRegisterInit(std::function< void()> function)
Definition: Log.cc:292
void log(log4cxx::LevelPtr level, log4cxx::spi::LocationInfo const &location, char const *fmt,...)
Method used by LOG_INFO and similar macros to process a log message with variable arguments along wit...
Definition: Log.cc:386
std::string getName() const
Get the logger name associated with the Log object.
Definition: Log.cc:240
int getEffectiveLevel() const
Retrieve the effective logging threshold.
Definition: Log.cc:330
LogMDCScope & operator=(LogMDCScope &&other)
Definition: Log.h:830
LogMDCScope & operator=(LogMDCScope const &)=delete
LogMDCScope(LogMDCScope const &)=delete
LogMDCScope(std::string const &key, std::string const &value)
Constructor adds KEY/VALUE pair to current thread MDC.
Definition: Log.h:814
~LogMDCScope()
Destructor restores old key value in MDC.
Definition: Log.h:847
LogMDCScope(LogMDCScope &&other)
Definition: Log.h:824
T clear(T... args)
T empty(T... args)
unsigned lwpID()
Function which returns LWP ID on platforms which support it.
Definition: Log.cc:425
A base class for image defects.