|
@@ -33,17 +33,17 @@
|
|
|
|
|
|
#include <util/strutil.h>
|
|
|
|
|
|
+// Note: as log4cplus and th3e BIND 10 logger have many concepts in common, and
|
|
|
+// thus many similar names, to disambiguate types we don't "use" the log4cplus
|
|
|
+// namespace: instead, all log4cplus types are explicitly qualified.
|
|
|
+
|
|
|
using namespace std;
|
|
|
-using namespace log4cplus;
|
|
|
|
|
|
namespace isc {
|
|
|
namespace log {
|
|
|
|
|
|
-// Static initializations
|
|
|
-
|
|
|
-
|
|
|
// Constructor
|
|
|
-LoggerImpl::LoggerImpl(const std::string& name)
|
|
|
+LoggerImpl::LoggerImpl(const string& name)
|
|
|
{
|
|
|
// Initialize log4cplus if not already done
|
|
|
initLog4cplus();
|
|
@@ -55,12 +55,8 @@ LoggerImpl::LoggerImpl(const std::string& name)
|
|
|
|
|
|
} else {
|
|
|
name_ = getRootLoggerName() + "." + name;
|
|
|
- logger_ = log4cplus::Logger::getInstance(name_);
|
|
|
+ logger_ = log4cplus::Logger::getInstance(name);
|
|
|
}
|
|
|
-
|
|
|
- // Create a formatted name for use in messages (speeds up formatting if
|
|
|
- // we do it now.)
|
|
|
- fmt_name_ = std::string("[") + name_ + std::string("] ");
|
|
|
}
|
|
|
|
|
|
// Destructor. (Here because of virtual declaration.)
|
|
@@ -71,23 +67,21 @@ LoggerImpl::~LoggerImpl() {
|
|
|
// Set the severity for logging.
|
|
|
void
|
|
|
LoggerImpl::setSeverity(isc::log::Severity severity, int dbglevel) {
|
|
|
- isc::log::Level level(severity, dbglevel);
|
|
|
+ Level level(severity, dbglevel);
|
|
|
logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level));
|
|
|
}
|
|
|
|
|
|
// Return severity level
|
|
|
isc::log::Severity
|
|
|
LoggerImpl::getSeverity() {
|
|
|
- isc::log::Level level =
|
|
|
- LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
|
|
|
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
|
|
|
return level.severity;
|
|
|
}
|
|
|
|
|
|
// Return current debug level (only valid if current severity level is DEBUG).
|
|
|
int
|
|
|
LoggerImpl::getDebugLevel() {
|
|
|
- isc::log::Level level =
|
|
|
- LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
|
|
|
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
|
|
|
return level.dbglevel;
|
|
|
}
|
|
|
|
|
@@ -95,8 +89,7 @@ LoggerImpl::getDebugLevel() {
|
|
|
// severity of the root level.
|
|
|
isc::log::Severity
|
|
|
LoggerImpl::getEffectiveSeverity() {
|
|
|
- isc::log::Level level =
|
|
|
- LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
|
|
|
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
|
|
|
return level.severity;
|
|
|
}
|
|
|
|
|
@@ -104,8 +97,7 @@ LoggerImpl::getEffectiveSeverity() {
|
|
|
// is DEBUG).
|
|
|
int
|
|
|
LoggerImpl::getEffectiveDebugLevel() {
|
|
|
- isc::log::Level level =
|
|
|
- LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
|
|
|
+ Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
|
|
|
return level.dbglevel;
|
|
|
}
|
|
|
|
|
@@ -121,45 +113,101 @@ void
|
|
|
LoggerImpl::outputRaw(const Severity& severity, const string& message) {
|
|
|
switch (severity) {
|
|
|
case DEBUG:
|
|
|
- LOG4CPLUS_DEBUG(logger_, fmt_name_ << message);
|
|
|
+ LOG4CPLUS_DEBUG(logger_, message);
|
|
|
break;
|
|
|
|
|
|
case INFO:
|
|
|
- LOG4CPLUS_INFO(logger_, fmt_name_ << message);
|
|
|
+ LOG4CPLUS_INFO(logger_, message);
|
|
|
break;
|
|
|
|
|
|
case WARN:
|
|
|
- LOG4CPLUS_WARN(logger_, fmt_name_ << message);
|
|
|
+ LOG4CPLUS_WARN(logger_, message);
|
|
|
break;
|
|
|
|
|
|
case ERROR:
|
|
|
- LOG4CPLUS_ERROR(logger_, fmt_name_ << message);
|
|
|
+ LOG4CPLUS_ERROR(logger_, message);
|
|
|
break;
|
|
|
|
|
|
case FATAL:
|
|
|
- LOG4CPLUS_FATAL(logger_, fmt_name_ << message);
|
|
|
+ LOG4CPLUS_FATAL(logger_, message);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// One-time initialization of log4cplus
|
|
|
+// Initialization. This is one initialization for all loggers, so requires
|
|
|
+// a singleton to hold the initialization flag. The flag is held within a
|
|
|
+// static method to ensure that it is created (and initialized) when needed.
|
|
|
+// This avoids a static initialization fiasco.
|
|
|
|
|
|
+bool&
|
|
|
+LoggerImpl::initialized() {
|
|
|
+ static bool initialized = false;
|
|
|
+ return (initialized);
|
|
|
+}
|
|
|
|
|
|
void
|
|
|
LoggerImpl::initLog4cplus() {
|
|
|
- static bool not_initialized = true;
|
|
|
|
|
|
- if (not_initialized) {
|
|
|
- // Set up basic configurator
|
|
|
+ if (! initialized()) {
|
|
|
+
|
|
|
+ // Set up basic configurator. This attaches a ConsoleAppender to the
|
|
|
+ // root logger with suitable output. This is used until we we have
|
|
|
+ // actually read the logging configuration, in which case the output
|
|
|
+ // may well be changed.
|
|
|
log4cplus::BasicConfigurator config;
|
|
|
config.configure();
|
|
|
+ setRootAppenderLayout();
|
|
|
|
|
|
// Add additional debug levels
|
|
|
LoggerLevelImpl::init();
|
|
|
|
|
|
// All done.
|
|
|
- not_initialized = false;
|
|
|
+ initialized() = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void LoggerImpl::setRootAppenderLayout() {
|
|
|
+
|
|
|
+ // Create the pattern we want for the output - local time.
|
|
|
+ string pattern = "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [";
|
|
|
+ pattern += getRootLoggerName() + string(".%c] %m\n");
|
|
|
+
|
|
|
+ // Retrieve the appenders on the root instance and set the layout to
|
|
|
+ // use that pattern.
|
|
|
+ log4cplus::SharedAppenderPtrList list =
|
|
|
+ log4cplus::Logger::getRoot().getAllAppenders();
|
|
|
+
|
|
|
+ for (log4cplus::SharedAppenderPtrList::iterator i = list.begin();
|
|
|
+ i != list.end(); ++i) {
|
|
|
+ auto_ptr<log4cplus::Layout> layout(
|
|
|
+ new log4cplus::PatternLayout(pattern));
|
|
|
+ (*i)->setLayout(layout);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// Reset. Just reset logger hierarchy to default settings (don't remove the
|
|
|
+// loggers - this appears awkward); this is effectively the same as removing
|
|
|
+// them.
|
|
|
+void
|
|
|
+LoggerImpl::reset() {
|
|
|
+ log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
|
|
|
+ initialized() = false;
|
|
|
+
|
|
|
+ // N.B. The documentation is not clear, but it does not appear that the
|
|
|
+ // methods used to format the new logging levels are removed from the
|
|
|
+ // log4cxx LogLevelManager class - indeed, there appears to be no way
|
|
|
+ // to do this. This would seem to suggest that a re-initialization may
|
|
|
+ // well add another instance of the toString/fromString to the manager's
|
|
|
+ // list of methods.
|
|
|
+ //
|
|
|
+ // We could get round this by making setting the LogManager a truly
|
|
|
+ // one-shot process. However, apart from taking up memory there is little
|
|
|
+ // overhead if multiple instances are added. The manager walks the list and
|
|
|
+ // uses the first method that processes the argument, so multiple methods
|
|
|
+ // doing the same think will not affect functionality. Besides, this
|
|
|
+ // reset() method is only used in testing and not in the distributed
|
|
|
+ // software.
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
} // namespace log
|
|
|
} // namespace isc
|