logger_impl.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE
  14. #include <iostream>
  15. #include <iomanip>
  16. #include <algorithm>
  17. #include <stdarg.h>
  18. #include <stdio.h>
  19. #include <boost/lexical_cast.hpp>
  20. #include <boost/static_assert.hpp>
  21. #include <log4cplus/configurator.h>
  22. #include <log/logger.h>
  23. #include <log/logger_impl.h>
  24. #include <log/logger_level.h>
  25. #include <log/logger_level_impl.h>
  26. #include <log/logger_name.h>
  27. #include <log/message_dictionary.h>
  28. #include <log/message_types.h>
  29. #include <util/strutil.h>
  30. #include <util/interprocess_sync_file.h>
  31. // Note: as log4cplus and the BIND 10 logger have many concepts in common, and
  32. // thus many similar names, to disambiguate types we don't "use" the log4cplus
  33. // namespace: instead, all log4cplus types are explicitly qualified.
  34. using namespace std;
  35. using namespace isc::util;
  36. namespace isc {
  37. namespace log {
  38. // Constructor. The setting of logger_ must be done when the variable is
  39. // constructed (instead of being left to the body of the function); at least
  40. // one compiler requires that all member variables be constructed before the
  41. // constructor is run, but log4cplus::Logger (the type of logger_) has no
  42. // default constructor.
  43. LoggerImpl::LoggerImpl(const string& name) :
  44. name_(expandLoggerName(name)),
  45. logger_(log4cplus::Logger::getInstance(name_)),
  46. sync_(new InterprocessSyncFile("logger"))
  47. {
  48. }
  49. // Destructor. (Here because of virtual declaration.)
  50. LoggerImpl::~LoggerImpl() {
  51. delete sync_;
  52. }
  53. // Set the severity for logging.
  54. void
  55. LoggerImpl::setSeverity(isc::log::Severity severity, int dbglevel) {
  56. Level level(severity, dbglevel);
  57. logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level));
  58. }
  59. // Return severity level
  60. isc::log::Severity
  61. LoggerImpl::getSeverity() {
  62. Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
  63. return level.severity;
  64. }
  65. // Return current debug level (only valid if current severity level is DEBUG).
  66. int
  67. LoggerImpl::getDebugLevel() {
  68. Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
  69. return level.dbglevel;
  70. }
  71. // Get effective severity. Either the current severity or, if not set, the
  72. // severity of the root level.
  73. isc::log::Severity
  74. LoggerImpl::getEffectiveSeverity() {
  75. Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
  76. return level.severity;
  77. }
  78. // Return effective debug level (only valid if current effective severity level
  79. // is DEBUG).
  80. int
  81. LoggerImpl::getEffectiveDebugLevel() {
  82. Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
  83. return level.dbglevel;
  84. }
  85. // Output a general message
  86. string*
  87. LoggerImpl::lookupMessage(const MessageID& ident) {
  88. return (new string(string(ident) + " " +
  89. MessageDictionary::globalDictionary().getText(ident)));
  90. }
  91. // Replace the interprocess synchronization object
  92. void
  93. LoggerImpl::setInterprocessSync(isc::util::InterprocessSync* sync) {
  94. if (sync == NULL) {
  95. isc_throw(BadInterprocessSync,
  96. "NULL was passed to setInterprocessSync()");
  97. }
  98. delete sync_;
  99. sync_ = sync;
  100. }
  101. void
  102. LoggerImpl::outputRaw(const Severity& severity, const string& message) {
  103. // Use an interprocess sync locker for mutual exclusion from other
  104. // processes to avoid log messages getting interspersed.
  105. InterprocessSyncLocker locker(*sync_);
  106. if (!locker.lock()) {
  107. LOG4CPLUS_ERROR(logger_, "Unable to lock logger lockfile");
  108. }
  109. switch (severity) {
  110. case DEBUG:
  111. LOG4CPLUS_DEBUG(logger_, message);
  112. break;
  113. case INFO:
  114. LOG4CPLUS_INFO(logger_, message);
  115. break;
  116. case WARN:
  117. LOG4CPLUS_WARN(logger_, message);
  118. break;
  119. case ERROR:
  120. LOG4CPLUS_ERROR(logger_, message);
  121. break;
  122. case FATAL:
  123. LOG4CPLUS_FATAL(logger_, message);
  124. }
  125. if (!locker.unlock()) {
  126. LOG4CPLUS_ERROR(logger_, "Unable to unlock logger lockfile");
  127. }
  128. }
  129. } // namespace log
  130. } // namespace isc