logger_manager_impl.cc 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 <algorithm>
  15. #include <iostream>
  16. #include <log4cplus/logger.h>
  17. #include <log4cplus/configurator.h>
  18. #include <log4cplus/consoleappender.h>
  19. #include <log4cplus/fileappender.h>
  20. #include <log4cplus/syslogappender.h>
  21. #include "log/logger.h"
  22. #include "log/logger_level_impl.h"
  23. #include "log/logger_manager.h"
  24. #include "log/logger_manager_impl.h"
  25. #include "log/logger_name.h"
  26. #include "log/logger_specification.h"
  27. #include "log/messagedef.h"
  28. using namespace std;
  29. namespace isc {
  30. namespace log {
  31. // Reset hierarchy of loggers back to default settings. This removes all
  32. // appenders from loggers, sets their severity to NOT_SET (so that events are
  33. // passed back to the parent) and resets the root logger to logging
  34. // informational messages. (This last is not a log4cplus default, so we have to
  35. // explicitly reset the logging severity.)
  36. void
  37. LoggerManagerImpl::processInit() {
  38. log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
  39. initRootLogger();
  40. }
  41. // Process logging specification. Set up the common states then dispatch to
  42. // add output specifications.
  43. void
  44. LoggerManagerImpl::processSpecification(const LoggerSpecification& spec) {
  45. log4cplus::Logger logger = log4cplus::Logger::getInstance(
  46. expandLoggerName(spec.getName()));
  47. // Set severity level according to specification entry.
  48. logger.setLogLevel(LoggerLevelImpl::convertFromBindLevel(
  49. Level(spec.getSeverity(), spec.getDbglevel())));
  50. // Set the additive flag.
  51. logger.setAdditivity(spec.getAdditive());
  52. // Output options given?
  53. if (spec.optionCount() > 0) {
  54. // Yes, so replace all appenders for this logger.
  55. logger.removeAllAppenders();
  56. // Now process output specifications.
  57. for (LoggerSpecification::const_iterator i = spec.begin();
  58. i != spec.end(); ++i) {
  59. switch (i->destination) {
  60. case OutputOption::DEST_CONSOLE:
  61. createConsoleAppender(logger, *i);
  62. break;
  63. case OutputOption::DEST_FILE:
  64. createFileAppender(logger, *i);
  65. break;
  66. case OutputOption::DEST_SYSLOG:
  67. createSysLogAppender(logger, *i);
  68. break;
  69. default:
  70. // Not a valid destination. As we are in the middle of updating
  71. // logging destinations, we could be in the situation where
  72. // there are no valid appenders. For this reason, throw an
  73. // exception.
  74. isc_throw(UnknownLoggingDestination,
  75. "Unknown logging destination, code = " <<
  76. i->destination);
  77. }
  78. }
  79. }
  80. }
  81. // Console appender - log to either stdout or stderr.
  82. void
  83. LoggerManagerImpl::createConsoleAppender(log4cplus::Logger& logger,
  84. const OutputOption& opt)
  85. {
  86. log4cplus::SharedAppenderPtr console(
  87. new log4cplus::ConsoleAppender(
  88. (opt.stream == OutputOption::STR_STDERR), opt.flush));
  89. setConsoleAppenderLayout(console);
  90. logger.addAppender(console);
  91. }
  92. // File appender. Depending on whether a maximum size is given, either
  93. // a standard file appender or a rolling file appender will be created.
  94. void
  95. LoggerManagerImpl::createFileAppender(log4cplus::Logger& logger,
  96. const OutputOption& opt)
  97. {
  98. LOG4CPLUS_OPEN_MODE_TYPE mode =
  99. LOG4CPLUS_FSTREAM_NAMESPACE::ios::app; // Append to existing file
  100. log4cplus::SharedAppenderPtr fileapp;
  101. if (opt.maxsize == 0) {
  102. fileapp = log4cplus::SharedAppenderPtr(new log4cplus::FileAppender(
  103. opt.filename, mode, opt.flush));
  104. } else {
  105. fileapp = log4cplus::SharedAppenderPtr(
  106. new log4cplus::RollingFileAppender(opt.filename, opt.maxsize,
  107. opt.maxver, opt.flush));
  108. }
  109. // use the same console layout for the files.
  110. setConsoleAppenderLayout(fileapp);
  111. logger.addAppender(fileapp);
  112. }
  113. // SysLog appender.
  114. void
  115. LoggerManagerImpl::createSysLogAppender(log4cplus::Logger& logger,
  116. const OutputOption& opt)
  117. {
  118. log4cplus::SharedAppenderPtr syslogapp(
  119. new log4cplus::SysLogAppender(opt.facility));
  120. setSysLogAppenderLayout(syslogapp);
  121. logger.addAppender(syslogapp);
  122. }
  123. // One-time initialization of the log4cplus system
  124. void
  125. LoggerManagerImpl::init(isc::log::Severity severity, int dbglevel) {
  126. // Set up basic configurator. This attaches a ConsoleAppender to the
  127. // root logger with suitable output. This is used until we we have
  128. // actually read the logging configuration, in which case the output
  129. // may well be changed.
  130. log4cplus::BasicConfigurator config;
  131. config.configure();
  132. // Add the additional debug levels
  133. LoggerLevelImpl::init();
  134. reset();
  135. }
  136. // Reset logging to default configuration. This closes all appenders
  137. // and resets the root logger to output INFO messages to the console.
  138. // It is principally used in testing.
  139. void
  140. LoggerManagerImpl::reset() {
  141. // Initialize the root logger
  142. initRootLogger();
  143. }
  144. // Initialize the root logger
  145. void LoggerManagerImpl::initRootLogger(isc::log::Severity severity,
  146. int dbglevel)
  147. {
  148. log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
  149. // Set the log4cplus root to not output anything - effectively we are
  150. // ignoring it.
  151. log4cplus::Logger::getRoot().setLogLevel(log4cplus::OFF_LOG_LEVEL);
  152. // Set the level for the BIND 10 root logger to the given severity and
  153. // debug level.
  154. log4cplus::Logger b10root = log4cplus::Logger::getInstance(
  155. getRootLoggerName());
  156. b10root.setLogLevel(LoggerLevelImpl::convertFromBindLevel(
  157. Level(severity, dbglevel)));
  158. // Set the BIND 10 root to use a console logger.
  159. OutputOption opt;
  160. createConsoleAppender(b10root, opt);
  161. }
  162. // Set the the "console" layout for the given appenders. This layout includes
  163. // a date/time and the name of the logger.
  164. void LoggerManagerImpl::setConsoleAppenderLayout(
  165. log4cplus::SharedAppenderPtr& appender)
  166. {
  167. // Create the pattern we want for the output - local time.
  168. string pattern = "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c] %m\n";
  169. // Finally the text of the message
  170. auto_ptr<log4cplus::Layout> layout(new log4cplus::PatternLayout(pattern));
  171. appender->setLayout(layout);
  172. }
  173. // Set the the "syslog" layout for the given appenders. This is the same
  174. // as the console, but without the timestamp (which is expected to be
  175. // set by syslogd).
  176. void LoggerManagerImpl::setSysLogAppenderLayout(
  177. log4cplus::SharedAppenderPtr& appender)
  178. {
  179. // Create the pattern we want for the output - local time.
  180. string pattern = "%-5p [%c] %m\n";
  181. // Finally the text of the message
  182. auto_ptr<log4cplus::Layout> layout(new log4cplus::PatternLayout(pattern));
  183. appender->setLayout(layout);
  184. }
  185. } // namespace log
  186. } // namespace isc