BIND 10 trac899, updated. 192aefd97c825f7636e0885eecef9a5834e53d05 [trac899] Implemented debug levels
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu May 19 19:12:49 UTC 2011
The branch, trac899 has been updated
via 192aefd97c825f7636e0885eecef9a5834e53d05 (commit)
via 4fcd0d3125dd7d8441f33c3ebf8b63e5b2093a68 (commit)
from 0346449357648e45f5b68f792cbf6dc914b16d9c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 192aefd97c825f7636e0885eecef9a5834e53d05
Author: Stephen Morris <stephen at isc.org>
Date: Thu May 19 20:11:53 2011 +0100
[trac899] Implemented debug levels
Debug logging levels implemented as new log4cplus levels. With
this change, most of the tests pass. The ones that fail are caused
by the different form of output.
commit 4fcd0d3125dd7d8441f33c3ebf8b63e5b2093a68
Author: Stephen Morris <stephen at isc.org>
Date: Thu May 19 13:52:58 2011 +0100
[trac899] Basic changes for log4cplus
The code compilers and produces basic output. Still to be done is
1) Add idea of debug levels.
2) Modify tests to copy with new format output.
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 51 ++++++
src/lib/log/Makefile.am | 16 +-
src/lib/log/compiler/Makefile.am | 4 +-
src/lib/log/debug_levels.h | 29 ---
src/lib/log/log_formatter.h | 31 ++--
src/lib/log/logger.cc | 21 +--
src/lib/log/logger.h | 31 +---
src/lib/log/logger_impl.cc | 207 +++++++++--------------
src/lib/log/logger_impl.h | 137 ++++++---------
src/lib/log/{logger_levels.h => logger_level.h} | 26 +++-
src/lib/log/logger_level_impl.cc | 189 +++++++++++++++++++++
src/lib/log/logger_level_impl.h | 127 ++++++++++++++
src/lib/log/tests/Makefile.am | 6 +-
src/lib/log/tests/log_formatter_unittest.cc | 37 ++--
src/lib/log/tests/logger_unittest.cc | 6 +-
src/lib/log/xdebuglevel.cc | 146 ----------------
src/lib/log/xdebuglevel.h | 162 ------------------
17 files changed, 586 insertions(+), 640 deletions(-)
delete mode 100644 src/lib/log/debug_levels.h
rename src/lib/log/{logger_levels.h => logger_level.h} (67%)
create mode 100644 src/lib/log/logger_level_impl.cc
create mode 100644 src/lib/log/logger_level_impl.h
delete mode 100644 src/lib/log/xdebuglevel.cc
delete mode 100644 src/lib/log/xdebuglevel.h
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 999639d..6363b43 100644
--- a/configure.ac
+++ b/configure.ac
@@ -447,6 +447,55 @@ AC_LINK_IFELSE(
CPPFLAGS=$CPPFLAGS_SAVED
LDFLAGS=$LDFLAGS_SAVED
+# Check for log4cplus
+log4cplus_path="yes"
+AC_ARG_WITH([log4cplus],
+ AC_HELP_STRING([--with-log4cplus=PATH],
+ [specify exact directory of log4cplus library and headers]),
+ [log4cplus_path="$withval"])
+if test "${log4cplus_path}" == "no" ; then
+ AC_MSG_ERROR([Need log4cplus])
+elif test "${log4cplus_path}" != "yes" ; then
+ LOG4CPLUS_INCLUDES="-I${log4cplus_path}/include"
+ LOG4CPLUS_LDFLAGS="-L${log4cplus_path}/lib"
+else
+# If not specified, try some common paths.
+ log4cplusdirs="/usr/local /usr/pkg /opt /opt/local"
+ for d in $log4cplusdirs
+ do
+ if test -f $d/include/log4cplus/logger.h; then
+ LOG4CPLUS_INCLUDES="-I$d/include"
+ LOG4CPLUS_LDFLAGS="-L$d/lib"
+ break
+ fi
+ done
+fi
+
+LOG4CPLUS_LDFLAGS="$LOG4CPLUS_LDFLAGS -llog4cplus $MULTITHREADING_FLAG"
+
+AC_SUBST(LOG4CPLUS_LDFLAGS)
+AC_SUBST(LOG4CPLUS_INCLUDES)
+
+CPPFLAGS_SAVED=$CPPFLAGS
+CPPFLAGS="$LOG4CPLUS_INCLUDES $CPPFLAGS"
+LDFLAGS_SAVED="$LDFLAGS"
+LDFLAGS="$LOG4CPLUS_LDFLAGS $LDFLAGS"
+
+AC_CHECK_HEADERS([log4cplus/logger.h],,AC_MSG_ERROR([Missing required header files.]))
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([#include <log4cplus/logger.h>
+ ],
+ [using namespace log4cplus;
+ Logger logger = Logger::getInstance("main");
+ ])],
+ [AC_MSG_RESULT([checking for log4cplus library... yes])],
+ [AC_MSG_RESULT([checking for log4cplus library... no])
+ AC_MSG_ERROR([Needs log4cplus library])]
+)
+
+CPPFLAGS=$CPPFLAGS_SAVED
+LDFLAGS=$LDFLAGS_SAVED
+
#
# Configure Boost header path
#
@@ -902,6 +951,8 @@ dnl includes too
Boost: ${BOOST_INCLUDES}
Botan: ${BOTAN_INCLUDES}
${BOTAN_LDFLAGS}
+ Log4cplus: ${LOG4CPLUS_INCLUDES}
+ ${LOG4CPLUS_LDFLAGS}
SQLite: $SQLITE_CFLAGS
$SQLITE_LIBS
diff --git a/src/lib/log/Makefile.am b/src/lib/log/Makefile.am
index c27b3e4..7555241 100644
--- a/src/lib/log/Makefile.am
+++ b/src/lib/log/Makefile.am
@@ -1,19 +1,21 @@
SUBDIRS = . compiler tests
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
+AM_CPPFLAGS += $(BOOST_INCLUDES) $(LOG4CPLUS_INCLUDES)
CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = liblog.la
-liblog_la_SOURCES =
-liblog_la_SOURCES += debug_levels.h logger_levels.h
+liblog_la_SOURCES = b.cc
+liblog_la_SOURCES += logger_levels.h
liblog_la_SOURCES += dummylog.h dummylog.cc
+liblog_la_SOURCES += log_formatter.h log_formatter.cc
liblog_la_SOURCES += logger.cc logger.h
liblog_la_SOURCES += logger_impl.cc logger_impl.h
+liblog_la_SOURCES += logger_level.h
+liblog_la_SOURCES += logger_level_impl.cc logger_level_impl.h
liblog_la_SOURCES += logger_support.cc logger_support.h
+liblog_la_SOURCES += macros.h
liblog_la_SOURCES += messagedef.cc messagedef.h
liblog_la_SOURCES += message_dictionary.cc message_dictionary.h
liblog_la_SOURCES += message_exception.h
@@ -21,13 +23,11 @@ liblog_la_SOURCES += message_initializer.cc message_initializer.h
liblog_la_SOURCES += message_reader.cc message_reader.h
liblog_la_SOURCES += message_types.h
liblog_la_SOURCES += root_logger_name.cc root_logger_name.h
-liblog_la_SOURCES += log_formatter.h log_formatter.cc
-liblog_la_SOURCES += macros.h
EXTRA_DIST = README
EXTRA_DIST += messagedef.mes
EXTRA_DIST += logger_impl_log4cxx.cc logger_impl_log4cxx.h
-EXTRA_DIST += xdebuglevel.cc xdebuglevel.h
+EXTRA_DIST += logger_impl_simple.cc logger_impl_simple.h
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
diff --git a/src/lib/log/compiler/Makefile.am b/src/lib/log/compiler/Makefile.am
index d51ba05..97c5d30 100644
--- a/src/lib/log/compiler/Makefile.am
+++ b/src/lib/log/compiler/Makefile.am
@@ -1,8 +1,6 @@
SUBDIRS = .
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -17,4 +15,4 @@ noinst_PROGRAMS = message
message_SOURCES = message.cc
message_LDADD = $(top_builddir)/src/lib/log/liblog.la
message_LDADD += $(top_builddir)/src/lib/util/libutil.la
-
+message_LDADD += $(LOG4CPLUS_LDFLAGS)
diff --git a/src/lib/log/debug_levels.h b/src/lib/log/debug_levels.h
deleted file mode 100644
index bb2b524..0000000
--- a/src/lib/log/debug_levels.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __DEBUG_LEVELS_H
-#define __DEBUG_LEVELS_H
-
-/// \brief Defines Debug Levels
-///
-/// Defines the maximum and minimum debug levels and the number of levels.
-/// These are defined using #define as they are referenced in the construction
-/// of variables declared outside execution units. (In this way we avoid the
-/// "static initialization fiasco" problem.)
-
-#define MIN_DEBUG_LEVEL (0)
-#define MAX_DEBUG_LEVEL (99)
-#define NUM_DEBUG_LEVEL (MAX_DEBUG_LEVEL - MIN_DEBUG_LEVEL + 1)
-
-#endif // __DEBUG_LEVELS_H
diff --git a/src/lib/log/log_formatter.h b/src/lib/log/log_formatter.h
index cda1d96..14531bd 100644
--- a/src/lib/log/log_formatter.h
+++ b/src/lib/log/log_formatter.h
@@ -17,6 +17,7 @@
#include <string>
#include <boost/lexical_cast.hpp>
+#include <log/logger_level.h>
namespace isc {
namespace log {
@@ -73,13 +74,18 @@ private:
///
/// If NULL, we are not active and should not produce anything.
mutable Logger* logger_;
- /// \brief Prefix (eg. "ERROR", "DEBUG" or like that)
- const char* prefix_;
+
+ /// \brief Message severity
+ Severity severity_;
+
/// \brief The messages with %1, %2... placeholders
std::string* message_;
+
/// \brief Which will be the next placeholder to replace
unsigned nextPlaceholder_;
+
Formatter& operator =(const Formatter& other);
+
public:
/// \brief Constructor of "active" formatter
///
@@ -89,21 +95,21 @@ public:
///
/// It is not expected to be called by user of logging system directly.
///
- /// \param prefix The severity prefix, like "ERROR" or "DEBUG"
+ /// \param severity The severity of the message (DEBUG, ERROR etc.)
/// \param message The message with placeholders. We take ownership of
/// it and we will modify the string. Must not be NULL unless
/// logger is also NULL, but it's not checked.
/// \param logger The logger where the final output will go, or NULL
/// if no output is wanted.
- Formatter(const char* prefix = NULL, std::string* message = NULL,
+ Formatter(const Severity& severity = NONE, std::string* message = NULL,
Logger* logger = NULL) :
- logger_(logger), prefix_(prefix), message_(message),
- nextPlaceholder_(1)
+ logger_(logger), severity_(severity), message_(message),
+ nextPlaceholder_(0)
{
}
Formatter(const Formatter& other) :
- logger_(other.logger_), prefix_(other.prefix_),
+ logger_(other.logger_), severity_(other.severity_),
message_(other.message_), nextPlaceholder_(other.nextPlaceholder_)
{
other.logger_ = false;
@@ -113,7 +119,7 @@ public:
/// This is the place where output happens if the formatter is active.
~ Formatter() {
if (logger_) {
- logger_->output(prefix_, *message_);
+ logger_->output(severity_, *message_);
delete message_;
}
}
@@ -134,11 +140,10 @@ public:
/// \brief String version of arg.
Formatter& arg(const std::string& arg) {
if (logger_) {
- // FIXME: This logic has a problem. If we had a message like
- // "%1 %2" and called .arg("%2").arg(42), we would get "42 %2".
- // But we consider this to be rare enough not to complicate
- // matters.
- replacePlaceholder(message_, arg, nextPlaceholder_ ++);
+ // Note that if we had a message like "%1 %2" and called
+ // .arg(42).arg("%1"), we would get "42 %1" (i.e. no recursive
+ // replacements). This is a limitation but not a problem.
+ replacePlaceholder(message_, arg, ++nextPlaceholder_ );
}
return (*this);
}
diff --git a/src/lib/log/logger.cc b/src/lib/log/logger.cc
index c340315..553e3c3 100644
--- a/src/lib/log/logger.cc
+++ b/src/lib/log/logger.cc
@@ -112,14 +112,14 @@ Logger::isFatalEnabled() {
// Output methods
void
-Logger::output(const char* sevText, const string& message) {
- getLoggerPtr()->outputRaw(sevText, message);
+Logger::output(const Severity& severity, const std::string& message) {
+ getLoggerPtr()->outputRaw(severity, message);
}
Logger::Formatter
Logger::debug(int dbglevel, const isc::log::MessageID& ident) {
if (isDebugEnabled(dbglevel)) {
- return (Formatter("DEBUG", getLoggerPtr()->lookupMessage(ident),
+ return (Formatter(DEBUG, getLoggerPtr()->lookupMessage(ident),
this));
} else {
return (Formatter());
@@ -129,7 +129,7 @@ Logger::debug(int dbglevel, const isc::log::MessageID& ident) {
Logger::Formatter
Logger::info(const isc::log::MessageID& ident) {
if (isInfoEnabled()) {
- return (Formatter("INFO ", getLoggerPtr()->lookupMessage(ident),
+ return (Formatter(INFO, getLoggerPtr()->lookupMessage(ident),
this));
} else {
return (Formatter());
@@ -139,7 +139,7 @@ Logger::info(const isc::log::MessageID& ident) {
Logger::Formatter
Logger::warn(const isc::log::MessageID& ident) {
if (isWarnEnabled()) {
- return (Formatter("WARN ", getLoggerPtr()->lookupMessage(ident),
+ return (Formatter(WARN, getLoggerPtr()->lookupMessage(ident),
this));
} else {
return (Formatter());
@@ -149,7 +149,7 @@ Logger::warn(const isc::log::MessageID& ident) {
Logger::Formatter
Logger::error(const isc::log::MessageID& ident) {
if (isErrorEnabled()) {
- return (Formatter("ERROR", getLoggerPtr()->lookupMessage(ident),
+ return (Formatter(ERROR, getLoggerPtr()->lookupMessage(ident),
this));
} else {
return (Formatter());
@@ -159,7 +159,7 @@ Logger::error(const isc::log::MessageID& ident) {
Logger::Formatter
Logger::fatal(const isc::log::MessageID& ident) {
if (isFatalEnabled()) {
- return (Formatter("FATAL", getLoggerPtr()->lookupMessage(ident),
+ return (Formatter(FATAL, getLoggerPtr()->lookupMessage(ident),
this));
} else {
return (Formatter());
@@ -170,12 +170,5 @@ bool Logger::operator==(Logger& other) {
return (*getLoggerPtr() == *other.getLoggerPtr());
}
-// Protected methods (used for testing)
-
-void
-Logger::reset() {
- LoggerImpl::reset();
-}
-
} // namespace log
} // namespace isc
diff --git a/src/lib/log/logger.h b/src/lib/log/logger.h
index 6bd8924..a46781f 100644
--- a/src/lib/log/logger.h
+++ b/src/lib/log/logger.h
@@ -18,8 +18,7 @@
#include <cstdlib>
#include <string>
-#include <log/debug_levels.h>
-#include <log/logger_levels.h>
+#include <log/logger_level.h>
#include <log/message_types.h>
#include <log/log_formatter.h>
@@ -95,7 +94,6 @@ public:
/// \return The full name of the logger (including the root name)
virtual std::string getName();
-
/// \brief Set Severity Level for Logger
///
/// Sets the level at which this logger will log messages. If none is set,
@@ -107,14 +105,12 @@ public:
/// outside these limits is silently coerced to the nearest boundary.
virtual void setSeverity(isc::log::Severity severity, int dbglevel = 1);
-
/// \brief Get Severity Level for Logger
///
/// \return The current logging level of this logger. In most cases though,
/// the effective logging level is what is required.
virtual isc::log::Severity getSeverity();
-
/// \brief Get Effective Severity Level for Logger
///
/// \return The effective severity level of the logger. This is the same
@@ -122,14 +118,12 @@ public:
/// is the severity of the parent.
virtual isc::log::Severity getEffectiveSeverity();
-
/// \brief Return DEBUG Level
///
/// \return Current setting of debug level. This is returned regardless of
/// whether the severity is set to debug.
virtual int getDebugLevel();
-
/// \brief Returns if Debug Message Should Be Output
///
/// \param dbglevel Level for which debugging is checked. Debugging is
@@ -137,23 +131,18 @@ public:
/// checked is less than or equal to the debug level set for the logger.
virtual bool isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL);
-
/// \brief Is INFO Enabled?
virtual bool isInfoEnabled();
-
/// \brief Is WARNING Enabled?
virtual bool isWarnEnabled();
-
/// \brief Is ERROR Enabled?
virtual bool isErrorEnabled();
-
/// \brief Is FATAL Enabled?
virtual bool isFatalEnabled();
-
/// \brief Output Debug Message
///
/// \param dbglevel Debug level, ranging between 0 and 99. Higher numbers
@@ -161,25 +150,21 @@ public:
/// \param ident Message identification.
Formatter debug(int dbglevel, const MessageID& ident);
-
/// \brief Output Informational Message
///
/// \param ident Message identification.
Formatter info(const MessageID& ident);
-
/// \brief Output Warning Message
///
/// \param ident Message identification.
Formatter warn(const MessageID& ident);
-
/// \brief Output Error Message
///
/// \param ident Message identification.
Formatter error(const MessageID& ident);
-
/// \brief Output Fatal Message
///
/// \param ident Message identification.
@@ -193,20 +178,16 @@ public:
/// \return true if the logger objects are instances of the same logger.
bool operator==(Logger& other);
-protected:
-
- /// \brief Reset Global Data
- ///
- /// Used for testing, this calls upon the underlying logger implementation
- /// to clear any global data.
- static void reset();
-
private:
friend class isc::log::Formatter<Logger>;
+
/// \brief Raw output function
///
/// This is used by the formatter to output formatted output.
- void output(const char* sevText, const std::string& message);
+ ///
+ /// \param severity Severity of the message being output.
+ /// \param message Text of the message to be output.
+ void output(const Severity& severity, const std::string& message);
/// \brief Copy Constructor
///
diff --git a/src/lib/log/logger_impl.cc b/src/lib/log/logger_impl.cc
index b30f835..ea6f56f 100644
--- a/src/lib/log/logger_impl.cc
+++ b/src/lib/log/logger_impl.cc
@@ -12,17 +12,20 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE
-#include <iostream>
#include <iomanip>
#include <algorithm>
#include <stdarg.h>
#include <stdio.h>
#include <boost/lexical_cast.hpp>
+#include <boost/static_assert.hpp>
+
+#include <log4cplus/configurator.h>
-#include <log/debug_levels.h>
#include <log/root_logger_name.h>
#include <log/logger.h>
+#include <log/logger_level.h>
+#include <log/logger_level_impl.h>
#include <log/logger_impl.h>
#include <log/message_dictionary.h>
#include <log/message_types.h>
@@ -31,26 +34,35 @@
#include <util/strutil.h>
using namespace std;
+using namespace log4cplus;
namespace isc {
namespace log {
// Static initializations
-LoggerImpl::LoggerInfoMap LoggerImpl::logger_info_;
-LoggerImpl::LoggerInfo LoggerImpl::root_logger_info_(isc::log::INFO, 0);
// Constructor
LoggerImpl::LoggerImpl(const std::string& name, bool)
{
+ // Initialize log4cplus if not already done
+ initLog4cplus();
+
// Are we the root logger?
if (name == getRootLoggerName()) {
is_root_ = true;
name_ = name;
+ logger_ = log4cplus::Logger::getRoot();
+
} else {
is_root_ = false;
name_ = getRootLoggerName() + "." + 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.)
@@ -59,162 +71,97 @@ LoggerImpl::~LoggerImpl() {
}
// Set the severity for logging.
-
void
LoggerImpl::setSeverity(isc::log::Severity severity, int dbglevel) {
-
- // Silently coerce the debug level into the valid range of 0 to 99
-
- int debug_level = max(MIN_DEBUG_LEVEL, min(MAX_DEBUG_LEVEL, dbglevel));
- if (is_root_) {
-
- // Can only set severity for the root logger, you can't disable it.
- // Any attempt to do so is silently ignored.
- if (severity != isc::log::DEFAULT) {
- root_logger_info_ = LoggerInfo(severity, debug_level);
- }
-
- } else if (severity == isc::log::DEFAULT) {
-
- // Want to set to default; this means removing the information
- // about this logger from the logger_info_ if it is set.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
- logger_info_.erase(i);
- }
-
- } else {
-
- // Want to set this information
- logger_info_[name_] = LoggerInfo(severity, debug_level);
- }
+ isc::log::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());
+ return level.severity;
+}
- if (is_root_) {
- return (root_logger_info_.severity);
- }
- else {
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
- return ((i->second).severity);
- }
- else {
- return (isc::log::DEFAULT);
- }
- }
+// Return current debug level (only valid if current severity level is DEBUG).
+int
+LoggerImpl::getDebugLevel() {
+ isc::log::Level level =
+ LoggerLevelImpl::convertToBindLevel(logger_.getLogLevel());
+ return level.dbglevel;
}
// Get effective severity. Either the current severity or, if not set, the
// severity of the root level.
-
isc::log::Severity
LoggerImpl::getEffectiveSeverity() {
-
- if (!is_root_ && !logger_info_.empty()) {
-
- // Not root logger and there is at least one item in the info map for a
- // logger.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
-
- // Found, so return the severity.
- return ((i->second).severity);
- }
- }
-
- // Must be the root logger, or this logger is defaulting to the root logger
- // settings.
- return (root_logger_info_.severity);
+ isc::log::Level level =
+ LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+ return level.severity;
}
-// Get the debug level. This returns 0 unless the severity is DEBUG.
-
+// Return effective debug level (only valid if current effective severity level
+// is DEBUG).
int
-LoggerImpl::getDebugLevel() {
-
- if (!is_root_ && !logger_info_.empty()) {
+LoggerImpl::getEffectiveDebugLevel() {
+ isc::log::Level level =
+ LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+ return level.dbglevel;
+}
- // Not root logger and there is something in the map, check if there
- // is a setting for this one.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
- // Found, so return the debug level.
- if ((i->second).severity == isc::log::DEBUG) {
- return ((i->second).dbglevel);
- } else {
- return (0);
- }
- }
- }
+// Output a general message
+string*
+LoggerImpl::lookupMessage(const MessageID& ident) {
+ return (new string(string(ident) + ", " +
+ MessageDictionary::globalDictionary().getText(ident)));
+}
- // Must be the root logger, or this logger is defaulting to the root logger
- // settings.
- if (root_logger_info_.severity == isc::log::DEBUG) {
- return (root_logger_info_.dbglevel);
- } else {
- return (0);
+void
+LoggerImpl::outputRaw(const Severity& severity, const string& message) {
+ switch (severity) {
+ case DEBUG:
+ LOG4CPLUS_DEBUG(logger_, fmt_name_ << message);
+ break;
+
+ case INFO:
+ LOG4CPLUS_INFO(logger_, fmt_name_ << message);
+ break;
+
+ case WARN:
+ LOG4CPLUS_WARN(logger_, fmt_name_ << message);
+ break;
+
+ case ERROR:
+ LOG4CPLUS_ERROR(logger_, fmt_name_ << message);
+ break;
+
+ case FATAL:
+ LOG4CPLUS_FATAL(logger_, fmt_name_ << message);
}
}
-// The code for isXxxEnabled is quite simple and is in the header. The only
-// exception is isDebugEnabled() where we have the complication of the debug
-// levels.
+// One-time initialization of log4cplus
-bool
-LoggerImpl::isDebugEnabled(int dbglevel) {
- if (!is_root_ && !logger_info_.empty()) {
+void
+LoggerImpl::initLog4cplus() {
+ static bool not_initialized = true;
- // Not root logger and there is something in the map, check if there
- // is a setting for this one.
- LoggerInfoMap::iterator i = logger_info_.find(name_);
- if (i != logger_info_.end()) {
+ if (not_initialized) {
+ // Set up basic configurator
+ log4cplus::BasicConfigurator config;
+ config.configure();
- // Found, so return the debug level.
- if ((i->second).severity <= isc::log::DEBUG) {
- return ((i->second).dbglevel >= dbglevel);
- } else {
- return (false); // Nothing lower than debug
- }
- }
- }
+ // Add additional debug levels
+ LoggerLevelImpl::init();
- // Must be the root logger, or this logger is defaulting to the root logger
- // settings.
- if (root_logger_info_.severity <= isc::log::DEBUG) {
- return (root_logger_info_.dbglevel >= dbglevel);
- } else {
- return (false);
+ // All done.
+ not_initialized = false;
}
}
-// Output a general message
-string*
-LoggerImpl::lookupMessage(const MessageID& ident) {
- return (new string(string(ident) + ", " +
- MessageDictionary::globalDictionary().getText(ident)));
-}
-
-void
-LoggerImpl::outputRaw(const char* sevText, const string& message) {
- // Get the time in a struct tm format, and convert to text
- time_t t_time;
- time(&t_time);
- struct tm* tm_time = localtime(&t_time);
-
- char chr_time[32];
- (void) strftime(chr_time, sizeof(chr_time), "%Y-%m-%d %H:%M:%S", tm_time);
-
- // Now output.
- cout << chr_time << " " << sevText << " [" << getName() << "] " <<
- message << endl;
-}
-
} // namespace log
} // namespace isc
diff --git a/src/lib/log/logger_impl.h b/src/lib/log/logger_impl.h
index 187e478..53879f0 100644
--- a/src/lib/log/logger_impl.h
+++ b/src/lib/log/logger_impl.h
@@ -18,15 +18,19 @@
#include <stdarg.h>
#include <time.h>
+#include <iostream>
#include <cstdlib>
#include <string>
#include <map>
#include <utility>
-#include <log/debug_levels.h>
-#include <log/logger.h>
+
+// log4cplus logger header file
+#include <log4cplus/logger.h>
+
+// BIND-10 logger files
+#include <log/logger_level_impl.h>
#include <log/message_types.h>
-#include <log/root_logger_name.h>
namespace isc {
namespace log {
@@ -35,37 +39,24 @@ namespace log {
///
/// The logger uses a "pimpl" idiom for implementation, where the base logger
/// class contains little more than a pointer to the implementation class, and
-/// all actions are carried out by the latter. This class is an implementation
-/// class that just outputs to stdout.
+/// all actions are carried out by the latter.
+///
+/// This particular implementation is based on log4cplus (from sourceforge:
+/// http://log4cplus.sourceforge.net). Particular items of note:
+///
+/// a) BIND 10 loggers have names of the form "root.sublogger". Log4cplus
+/// loggers are always subloggers of a "root" logger. In this implementation,
+/// the name of the logger is checked. If it is the root name (as evidenced
+/// by the setting of the BIND 10 root logger name), the log4cplus root logger
+/// is used. Otherwise the name is used as the name of a logger and a log4cplus
+/// sub-logger created.
+///
+/// b) The idea of debug levels is implemented. Seee logger_level.h and
+/// logger_level_impl.h for more details on this.
class LoggerImpl {
public:
- /// \brief Information About Logger
- ///
- /// Holds a information about a logger, namely its severity and its debug
- /// level. This could be a std::pair, except that it gets confusing when
- /// accessing the LoggerInfoMap: that returns a pair, so we to reference
- /// elements we would use constructs like ((i->first).second);
- struct LoggerInfo {
- isc::log::Severity severity;
- int dbglevel;
-
- LoggerInfo(isc::log::Severity sev = isc::log::INFO,
- int dbg = MIN_DEBUG_LEVEL) : severity(sev), dbglevel(dbg)
- {}
- };
-
-
- /// \brief Information About All Loggers
- ///
- /// Information about all loggers in the system - except the root logger -
- /// is held in a map, linking name of the logger (excluding the root
- /// name component) and its set severity and debug levels. The root
- /// logger information is held separately.
- typedef std::map<std::string, LoggerInfo> LoggerInfoMap;
-
-
/// \brief Constructor
///
/// Creates a logger of the specific name.
@@ -94,16 +85,16 @@ public:
///
/// \param severity Severity level to log
/// \param dbglevel If the severity is DEBUG, this is the debug level.
- /// This can be in the range 1 to 100 and controls the verbosity. A value
+ /// This can be in the range 0 to 99 and controls the verbosity. A value
/// outside these limits is silently coerced to the nearest boundary.
- virtual void setSeverity(isc::log::Severity severity, int dbglevel = 1);
+ virtual void setSeverity(Severity severity, int dbglevel = 1);
/// \brief Get Severity Level for Logger
///
/// \return The current logging level of this logger. In most cases though,
/// the effective logging level is what is required.
- virtual isc::log::Severity getSeverity();
+ virtual Severity getSeverity();
/// \brief Get Effective Severity Level for Logger
@@ -111,67 +102,62 @@ public:
/// \return The effective severity level of the logger. This is the same
/// as getSeverity() if the logger has a severity level set, but otherwise
/// is the severity of the parent.
- virtual isc::log::Severity getEffectiveSeverity();
+ virtual Severity getEffectiveSeverity();
- /// \brief Return DEBUG Level
+ /// \brief Return debug level
///
- /// \return Current setting of debug level. This is returned regardless of
- /// whether the
+ /// \return Current setting of debug level. This will be zero if the
+ /// the current severity level is not DEBUG.
virtual int getDebugLevel();
+ /// \brief Return effective debug level
+ ///
+ /// \return Current setting of effective debug level. This will be zero if
+ /// the current effective severity level is not DEBUG.
+ virtual int getEffectiveDebugLevel();
+
+
/// \brief Returns if Debug Message Should Be Output
///
/// \param dbglevel Level for which debugging is checked. Debugging is
/// enabled only if the logger has DEBUG enabled and if the dbglevel
/// checked is less than or equal to the debug level set for the logger.
- virtual bool
- isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL);
+ virtual bool isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL) {
+ Level level(DEBUG, dbglevel);
+ return logger_.isEnabledFor(LoggerLevelImpl::convertFromBindLevel(level));
+ }
/// \brief Is INFO Enabled?
virtual bool isInfoEnabled() {
- return (isEnabled(isc::log::INFO));
+ return (logger_.isEnabledFor(log4cplus::INFO_LOG_LEVEL));
}
/// \brief Is WARNING Enabled?
virtual bool isWarnEnabled() {
- return (isEnabled(isc::log::WARN));
+ return (logger_.isEnabledFor(log4cplus::WARN_LOG_LEVEL));
}
/// \brief Is ERROR Enabled?
virtual bool isErrorEnabled() {
- return (isEnabled(isc::log::ERROR));
+ return (logger_.isEnabledFor(log4cplus::ERROR_LOG_LEVEL));
}
/// \brief Is FATAL Enabled?
virtual bool isFatalEnabled() {
- return (isEnabled(isc::log::FATAL));
- }
-
-
- /// \brief Common Severity check
- ///
- /// Implements the common severity check. As an optimisation, this checks
- /// to see if any logger-specific levels have been set (a quick check as it
- /// just involves seeing if the collection of logger information is empty).
- /// if not, it returns the information for the root level; if so, it has
- /// to take longer and look up the information in the map holding the
- /// logging details.
- virtual bool isEnabled(isc::log::Severity severity) {
- if (logger_info_.empty()) {
- return (root_logger_info_.severity <= severity);
- }
- else {
- return (getSeverity() <= severity);
- }
+ return (logger_.isEnabledFor(log4cplus::FATAL_LOG_LEVEL));
}
/// \brief Raw output
///
/// Writes the message with time into the log. Used by the Formatter
/// to produce output.
- void outputRaw(const char* sev_text, const std::string& message);
+ ///
+ /// \param severity Severity of the message. (This controls the prefix
+ /// label output with the message text.)
+ /// \param message Text of the message.
+ void outputRaw(const Severity& severity, const std::string& message);
/// \brief Look up message text in dictionary
///
@@ -189,27 +175,18 @@ public:
}
- /// \brief Reset Global Data
- ///
- /// Only used for testing, this clears all the logger information and
- /// resets it back to default values.
- static void reset() {
- root_logger_info_ = LoggerInfo(isc::log::INFO, MIN_DEBUG_LEVEL);
- logger_info_.clear();
- }
-
-
private:
- bool is_root_; ///< true if a root logger
- std::string name_; ///< Name of this logger
- // Split the status of the root logger from this logger. If - is will
- // probably be the usual case - no per-logger setting is enabled, a
- // quick check of logger_info_.empty() will return true and we can quickly
- // return the root logger status without a length lookup in the map.
+ /// \brief Initialize log4cplus
+ ///
+ /// Static method to perform one-time initialization of the log4cplus
+ /// system.
+ static void initLog4cplus();
- static LoggerInfo root_logger_info_; ///< Status of root logger
- static LoggerInfoMap logger_info_; ///< Store of debug levels etc.
+ bool is_root_; ///< Is this BIND 10 root logger?
+ std::string name_; ///< Full name of this logger
+ std::string fmt_name_; ///< Formatted name for output
+ log4cplus::Logger logger_; ///< Underlying log4cplus logger
};
} // namespace log
diff --git a/src/lib/log/logger_level.h b/src/lib/log/logger_level.h
new file mode 100644
index 0000000..eb946bf
--- /dev/null
+++ b/src/lib/log/logger_level.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_LEVEL_H
+#define __LOGGER_LEVEL_H
+
+namespace isc {
+namespace log {
+
+/// \brief Severity Levels
+///
+/// Defines the severity levels for logging. This is shared between the logger
+/// and the implementations classes.
+///
+/// N.B. The order of the levels - DEBUG less than INFO less that WARN etc. is
+/// implicitly assumed in several implementations. They must not be changed.
+
+typedef enum {
+ DEFAULT = 0, // Default to logging level of the parent
+ DEBUG = 1,
+ INFO = 2,
+ WARN = 3,
+ ERROR = 4,
+ FATAL = 5,
+ NONE = 6 // Disable logging
+} Severity;
+
+/// Minimum/maximum debug levels. These are defined wi
+
+const int MIN_DEBUG_LEVEL = 0;
+const int MAX_DEBUG_LEVEL = 99;
+
+/// \brief Log level structure
+///
+/// A simple pair structure that provides suitable names for the members. It
+/// holds a combination of logging severity and debug level.
+struct Level {
+ Severity severity; ///< Logging severity
+ int dbglevel; ///< Debug level
+
+ Level(Severity sev = DEFAULT, int dbg = MIN_DEBUG_LEVEL) :
+ severity(sev), dbglevel(dbg)
+ {}
+
+ // Default assignment and copy constructor is appropriate
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_LEVEL_H
diff --git a/src/lib/log/logger_level_impl.cc b/src/lib/log/logger_level_impl.cc
new file mode 100644
index 0000000..2694776
--- /dev/null
+++ b/src/lib/log/logger_level_impl.cc
@@ -0,0 +1,189 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <algorithm>
+#include <string.h>
+#include <boost/lexical_cast.hpp>
+
+#include <log4cplus/logger.h>
+#include <log/logger_level.h>
+#include <log/logger_level_impl.h>
+
+using namespace log4cplus;
+using namespace std;
+
+namespace isc {
+namespace log {
+
+// Convert BIND 10 level to a log4cplus logging level.
+log4cplus::LogLevel
+LoggerLevelImpl::convertFromBindLevel(const Level& level) {
+
+ // BIND 10 logging levels are small integers so we can do a table lookup
+ static const log4cplus::LogLevel log4cplus_levels[] = {
+ log4cplus::NOT_SET_LOG_LEVEL,
+ log4cplus::DEBUG_LOG_LEVEL,
+ log4cplus::INFO_LOG_LEVEL,
+ log4cplus::WARN_LOG_LEVEL,
+ log4cplus::ERROR_LOG_LEVEL,
+ log4cplus::FATAL_LOG_LEVEL,
+ log4cplus::OFF_LOG_LEVEL
+ };
+
+ // ... with compile-time checks to ensure that table indexes are correct.
+ BOOST_STATIC_ASSERT(static_cast<int>(DEFAULT) == 0);
+ BOOST_STATIC_ASSERT(static_cast<int>(DEBUG) == 1);
+ BOOST_STATIC_ASSERT(static_cast<int>(INFO) == 2);
+ BOOST_STATIC_ASSERT(static_cast<int>(WARN) == 3);
+ BOOST_STATIC_ASSERT(static_cast<int>(ERROR) == 4);
+ BOOST_STATIC_ASSERT(static_cast<int>(FATAL) == 5);
+ BOOST_STATIC_ASSERT(static_cast<int>(NONE) == 6);
+
+ // Do the conversion
+ if (level.severity == DEBUG) {
+
+ // Debug severity, so the log4cplus level returned depends on the
+ // debug level. Silently limit the debug level to the range
+ // MIN_DEBUG_LEVEL to MAX_DEBUG_LEVEL (avoids the hassle of throwing
+ // and catching exceptions and besides, this is for debug information).
+ int limited = std::max(MIN_DEBUG_LEVEL,
+ std::min(level.dbglevel, MAX_DEBUG_LEVEL));
+ LogLevel newlevel = static_cast<int>(DEBUG_LOG_LEVEL -
+ (limited - MIN_DEBUG_LEVEL));
+ return (static_cast<log4cplus::LogLevel>(newlevel));
+
+ } else {
+
+ // Can do a table lookup to speed things up. There is no need to check
+ // that the index is out of range. That the variable is of type
+ // isc::log::Severity ensures that it must be one of the Severity enum
+ // members - conversion of a numeric value to an enum is not permitted.
+ return (log4cplus_levels[level.severity]);
+ }
+}
+
+// Convert log4cplus logging level to BIND 10 debug level. It is up to the
+// caller to validate that the debug level is valid.
+Level
+LoggerLevelImpl::convertToBindLevel(const log4cplus::LogLevel loglevel) {
+
+ // Not easy to do a table lookup as the numerical values of log4cplus levels
+ // are quite high.
+ if (loglevel <= log4cplus::NOT_SET_LOG_LEVEL) {
+ return (Level(DEFAULT));
+
+ } else if (loglevel <= log4cplus::DEBUG_LOG_LEVEL) {
+
+ // Debug severity, so extract the debug level from the numeric value
+ // and coerce to the allowed limits
+ int dbglevel = MIN_DEBUG_LEVEL +
+ static_cast<int>(log4cplus::DEBUG_LOG_LEVEL) -
+ static_cast<int>(loglevel);
+ dbglevel = max(MIN_DEBUG_LEVEL, min(dbglevel, MAX_DEBUG_LEVEL));
+ return (Level(DEBUG, dbglevel));
+
+ } else if (loglevel <= log4cplus::INFO_LOG_LEVEL) {
+ return (Level(INFO));
+
+ } else if (loglevel <= log4cplus::WARN_LOG_LEVEL) {
+ return (Level(WARN));
+
+ } else if (loglevel <= log4cplus::ERROR_LOG_LEVEL) {
+ return (Level(ERROR));
+
+ } else if (loglevel <= log4cplus::FATAL_LOG_LEVEL) {
+ return (Level(FATAL));
+
+ }
+
+ return (Level(NONE));
+}
+
+
+// Convert string to appropriate logging level
+log4cplus::LogLevel
+LoggerLevelImpl::logLevelFromString(const log4cplus::tstring& level) {
+
+ std::string name = level; // Get to known type
+ size_t length = name.size(); // Length of the string
+
+ if (length < 5) {
+
+ // String can't possibly start DEBUG so we don't know what it is.
+ // As per documentation, return NOT_SET level.
+ return (NOT_SET_LOG_LEVEL);
+ }
+ else {
+ if (strncasecmp(name.c_str(), "DEBUG", 5) == 0) {
+
+ // String starts "DEBUG" (or "debug" or any case mixture). The
+ // rest of the string - if any - should be a number.
+ if (length == 5) {
+
+ // It is plain "DEBUG". Take this as level 0.
+ return (DEBUG_LOG_LEVEL);
+ }
+ else {
+
+ // Try converting the remainder to an integer. The "5" is
+ // the length of the string "DEBUG". Note that if the number
+ // is outside the range of debug levels, it is coerced to the
+ // nearest limit. Thus a level of DEBUG509 will end up as
+ // if DEBUG99 has been specified.
+ try {
+ int dbglevel = boost::lexical_cast<int>(name.substr(5));
+ return convertFromBindLevel(Level(DEBUG, dbglevel));
+ }
+ catch (boost::bad_lexical_cast&) {
+ return (NOT_SET_LOG_LEVEL);
+ }
+ }
+ }
+ else {
+
+ // Unknown string - return default.
+ return (NOT_SET_LOG_LEVEL);
+ }
+ }
+}
+
+// Convert logging level to string. If the level is a valid debug level,
+// return the string DEBUG, else return the empty string.
+log4cplus::tstring
+LoggerLevelImpl::logLevelToString(log4cplus::LogLevel level) {
+ Level bindlevel = convertToBindLevel(level);
+ Severity& severity = bindlevel.severity;
+ int& dbglevel = bindlevel.dbglevel;
+
+ if ((severity == DEBUG) &&
+ ((dbglevel >= MIN_DEBUG_LEVEL) && (dbglevel <= MAX_DEBUG_LEVEL))) {
+ return (tstring("DEBUG"));
+ }
+ return (tstring());
+}
+
+// Initialization. Register the conversion functions with the LogLevelManager.
+void
+LoggerLevelImpl::init() {
+
+ // Get the singleton log-level manager.
+ LogLevelManager& manager = getLogLevelManager();
+
+ // Register the conversion functions
+ manager.pushFromStringMethod(LoggerLevelImpl::logLevelFromString);
+ manager.pushToStringMethod(LoggerLevelImpl::logLevelToString);
+}
+
+} // namespace log
+} // namespace isc
diff --git a/src/lib/log/logger_level_impl.h b/src/lib/log/logger_level_impl.h
new file mode 100644
index 0000000..9289a1d
--- /dev/null
+++ b/src/lib/log/logger_level_impl.h
@@ -0,0 +1,127 @@
+// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LOGGER_LEVEL_IMPL_H
+#define __LOGGER_LEVEL_IMPL_H
+
+#include <log4cplus/logger.h>
+#include <log/logger_level.h>
+
+namespace isc {
+namespace log {
+
+/// \brief Implementation aspects of logging levels
+///
+/// This extends the log4cplus level set to allow 100 debug levels.
+///
+/// First some terminology, as the use of the term "level" gets confusing. The
+/// code and comments here use the term "level" in two contexts:
+///
+/// Logging level: The category of messages to log. By default log4cplus
+/// defines the following logging levels: OFF_LOG_LEVEL, FATAL_LOG_LEVEL,
+/// ERROR_LOG_LEVEL, WARN_LOG_LEVEL, INFO_LOG_LEVEL, DEBUG_LOG_LEVEL,
+/// TRACE_LOG_LEVEL, ALL_LOG_LEVEL (which here will be abbreviated OFF, FATAL
+/// etc.). Within the context of BIND-10, OFF, TRACE and ALL are not used
+/// and the idea of DEBUG has been extended, as will be seen below. In
+/// BIND 10 terms, this is known as "severity"; the "logging level" usage will
+/// usually be used when talking about log4cplus aspects of the idea (as
+/// log4cplus uses that teminology).
+///
+/// Debug level: This is a number that ranges from 0 to 99 and is used by the
+/// application to control the detail of debug output. A value of 0 gives the
+/// highest-level debug output; a value of 99 gives the most verbose and most
+/// detailed. Debug messages (or whatever debug level) are only ever output
+/// when the logging level is set to DEBUG. (Note that the numbers 0 and 99
+/// are not hard-coded - they are the constants MIN_DEBUG_LEVEL and
+/// MAX_DEBUG_LEVEL.)
+///
+/// With log4cplus, the various logging levels have a numeric value associated
+/// with them, such that FATAL > ERROR > WARNING etc. This suggests that the
+/// idea of debug levels can be incorporated into the existing logging level
+/// scheme by assigning them appropriate numeric values, i.e.
+///
+/// WARNING > INFO > DEBUG > DEBUG - 1 > DEBUG - 2 > ... > DEBUG - 99
+///
+/// Setting a numeric level of DEBUG enables the basic messages; setting higher
+/// debug levels (corresponding to lower numeric logging levels) will enable
+/// progressively more messages. The lowest debug level (0) is chosen such that
+/// it corresponds to the default level of DEBUG.
+///
+/// This class comprises nothing more than static methods to aid the conversion
+/// of logging levels between log4cplus and BIND 10, and to register those
+/// levels with log4cplus.
+
+class LoggerLevelImpl {
+public:
+
+ /// \brief Convert BIND 10 level to log4cplus logging level
+ ///
+ /// Converts the BIND 10 severity level into a log4cplus logging level.
+ /// If the severity is DEBUG, the current BIND 10 debug level is taken
+ /// into account when doing the conversion.
+ ///
+ /// \param level BIND 10 severity and debug level
+ ///
+ /// \return Equivalent log4cplus logging level.
+ static
+ log4cplus::LogLevel convertFromBindLevel(const isc::log::Level& level);
+
+ /// \brief Convert log4cplus logging level to BIND 10 logging level
+ ///
+ /// Converts the log4cplus log level into a BIND 10 severity level.
+ /// The log4cplus log level may be non-standard in which case it is
+ /// encoding a BIND 10 debug level as well.
+ ///
+ /// \param level log4cplus log level
+ ///
+ /// \return Equivalent BIND 10 severity and debug level
+ static
+ isc::log::Level convertToBindLevel(const log4cplus::LogLevel loglevel);
+
+ /// \brief Convert string to log4cplus logging level
+ ///
+ /// BIND 10 extends the set of logging levels in log4cplus with a group
+ /// of debug levels. These are given names DEBUG0 through DEBUG99 (with
+ /// DEBUG0 being equivalent to DEBUG, the standard log level. If the name
+ /// is DEBUGn but n lies outside the range of debug levels, debug level
+ /// specifies is coerced to the nearest valid value. If the string is just
+ /// not recognised, a NOT_SET_LOG_LEVEL is returned.
+ ///
+ /// \param level String representing the logging level.
+ ///
+ /// \return Corresponding log4cplus log level
+ static
+ log4cplus::LogLevel logLevelFromString(const log4cplus::tstring& level);
+
+ /// \brief Convert log level to string
+ ///
+ /// If the log level is one of the extended debug levels, the string DEBUG
+ /// is returned, otherwise the empty string.
+ ///
+ /// \param level Extended logging level
+ ///
+ /// \return Equivalent string.
+ static log4cplus::tstring logLevelToString(log4cplus::LogLevel level);
+
+ /// \brief Initialize extended logging levels
+ ///
+ /// This must be called once, after log4cplus has been initialized. It
+ /// registers the level/string converter functions.
+ static void init();
+};
+
+} // namespace log
+} // namespace isc
+
+#endif // __LOGGER_LEVEL_IMPL_H
diff --git a/src/lib/log/logger_levels.h b/src/lib/log/logger_levels.h
deleted file mode 100644
index 2f123e8..0000000
--- a/src/lib/log/logger_levels.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __LOGGER_LEVELS_H
-#define __LOGGER_LEVELS_H
-
-namespace isc {
-namespace log {
-
-/// \brief Severity Levels
-///
-/// Defines the severity levels for logging. This is shared between the logger
-/// and the implementations classes.
-///
-/// N.B. The order of the levels - DEBUG less than INFO less that WARN etc. is
-/// implicitly assumed in several implementations. They must not be changed.
-
-typedef enum {
- DEFAULT = 0, // Default to logging level of the parent
- DEBUG = 1,
- INFO = 2,
- WARN = 3,
- ERROR = 4,
- FATAL = 5,
- NONE = 6 // Disable logging
-} Severity;
-
-} // namespace log
-} // namespace isc
-
-#endif // __LOGGER_LEVELS_H
diff --git a/src/lib/log/tests/Makefile.am b/src/lib/log/tests/Makefile.am
index 46065e8..1d67ecb 100644
--- a/src/lib/log/tests/Makefile.am
+++ b/src/lib/log/tests/Makefile.am
@@ -2,8 +2,6 @@ SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
@@ -25,7 +23,7 @@ run_unittests_SOURCES += run_unittests.cc
run_unittests_SOURCES += log_formatter_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
@@ -35,7 +33,7 @@ endif
TESTS += logger_support_test
logger_support_test_SOURCES = logger_support_test.cc
logger_support_test_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-logger_support_test_LDFLAGS = $(AM_LDFLAGS)
+logger_support_test_LDFLAGS = $(AM_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
logger_support_test_LDADD = $(top_builddir)/src/lib/log/liblog.la
logger_support_test_LDADD += $(top_builddir)/src/lib/util/libutil.la
diff --git a/src/lib/log/tests/log_formatter_unittest.cc b/src/lib/log/tests/log_formatter_unittest.cc
index b67831a..b91665d 100644
--- a/src/lib/log/tests/log_formatter_unittest.cc
+++ b/src/lib/log/tests/log_formatter_unittest.cc
@@ -14,6 +14,7 @@
#include <gtest/gtest.h>
#include <log/log_formatter.h>
+#include <log/logger_level.h>
#include <vector>
#include <string>
@@ -24,11 +25,11 @@ namespace {
class FormatterTest : public ::testing::Test {
protected:
- typedef pair<const char*, string> Output;
+ typedef pair<isc::log::Severity, string> Output;
typedef isc::log::Formatter<FormatterTest> Formatter;
vector<Output> outputs;
public:
- void output(const char* prefix, const string& message) {
+ void output(const isc::log::Severity& prefix, const string& message) {
outputs.push_back(Output(prefix, message));
}
// Just shortcut for new string
@@ -46,9 +47,9 @@ TEST_F(FormatterTest, inactive) {
// Create an active formatter and check it produces output. Does no arg
// substitution yet
TEST_F(FormatterTest, active) {
- Formatter("TEST", s("Text of message"), this);
+ Formatter(isc::log::INFO, s("Text of message"), this);
ASSERT_EQ(1, outputs.size());
- EXPECT_STREQ("TEST", outputs[0].first);
+ EXPECT_EQ(isc::log::INFO, outputs[0].first);
EXPECT_EQ("Text of message", outputs[0].second);
}
@@ -62,53 +63,53 @@ TEST_F(FormatterTest, inactiveArg) {
TEST_F(FormatterTest, stringArg) {
{
SCOPED_TRACE("C++ string");
- Formatter("TEST", s("Hello %1"), this).arg(string("World"));
+ Formatter(isc::log::INFO, s("Hello %1"), this).arg(string("World"));
ASSERT_EQ(1, outputs.size());
- EXPECT_STREQ("TEST", outputs[0].first);
+ EXPECT_EQ(isc::log::INFO, outputs[0].first);
EXPECT_EQ("Hello World", outputs[0].second);
}
{
SCOPED_TRACE("C++ string");
- Formatter("TEST", s("Hello %1"), this).arg(string("Internet"));
+ Formatter(isc::log::INFO, s("Hello %1"), this).arg(string("Internet"));
ASSERT_EQ(2, outputs.size());
- EXPECT_STREQ("TEST", outputs[1].first);
+ EXPECT_EQ(isc::log::INFO, outputs[1].first);
EXPECT_EQ("Hello Internet", outputs[1].second);
}
}
// Can convert to string
TEST_F(FormatterTest, intArg) {
- Formatter("TEST", s("The answer is %1"), this).arg(42);
+ Formatter(isc::log::INFO, s("The answer is %1"), this).arg(42);
ASSERT_EQ(1, outputs.size());
- EXPECT_STREQ("TEST", outputs[0].first);
+ EXPECT_EQ(isc::log::INFO, outputs[0].first);
EXPECT_EQ("The answer is 42", outputs[0].second);
}
// Can use multiple arguments at different places
TEST_F(FormatterTest, multiArg) {
- Formatter("TEST", s("The %2 are %1"), this).arg("switched").
+ Formatter(isc::log::INFO, s("The %2 are %1"), this).arg("switched").
arg("arguments");
ASSERT_EQ(1, outputs.size());
- EXPECT_STREQ("TEST", outputs[0].first);
+ EXPECT_EQ(isc::log::INFO, outputs[0].first);
EXPECT_EQ("The arguments are switched", outputs[0].second);
}
// Can survive and complains if placeholder is missing
TEST_F(FormatterTest, missingPlace) {
- EXPECT_NO_THROW(Formatter("TEST", s("Missing the first %2"), this).
+ EXPECT_NO_THROW(Formatter(isc::log::INFO, s("Missing the first %2"), this).
arg("missing").arg("argument"));
ASSERT_EQ(1, outputs.size());
- EXPECT_STREQ("TEST", outputs[0].first);
+ EXPECT_EQ(isc::log::INFO, outputs[0].first);
EXPECT_EQ("Missing the first argument "
"@@Missing placeholder %1 for 'missing'@@", outputs[0].second);
}
// Can replace multiple placeholders
TEST_F(FormatterTest, multiPlaceholder) {
- Formatter("TEST", s("The %1 is the %1"), this).
+ Formatter(isc::log::INFO, s("The %1 is the %1"), this).
arg("first rule of tautology club");
ASSERT_EQ(1, outputs.size());
- EXPECT_STREQ("TEST", outputs[0].first);
+ EXPECT_EQ(isc::log::INFO, outputs[0].first);
EXPECT_EQ("The first rule of tautology club is "
"the first rule of tautology club", outputs[0].second);
}
@@ -116,9 +117,9 @@ TEST_F(FormatterTest, multiPlaceholder) {
// Test we can cope with replacement containing the placeholder
TEST_F(FormatterTest, noRecurse) {
// If we recurse, this will probably eat all the memory and crash
- Formatter("TEST", s("%1"), this).arg("%1 %1");
+ Formatter(isc::log::INFO, s("%1"), this).arg("%1 %1");
ASSERT_EQ(1, outputs.size());
- EXPECT_STREQ("TEST", outputs[0].first);
+ EXPECT_EQ(isc::log::INFO, outputs[0].first);
EXPECT_EQ("%1 %1", outputs[0].second);
}
diff --git a/src/lib/log/tests/logger_unittest.cc b/src/lib/log/tests/logger_unittest.cc
index 4eff622..fddac14 100644
--- a/src/lib/log/tests/logger_unittest.cc
+++ b/src/lib/log/tests/logger_unittest.cc
@@ -37,10 +37,7 @@ class TestLogger : public Logger {
public:
/// \brief constructor
TestLogger(const string& name) : Logger(name, true)
- {}
-
- static void reset() {
- Logger::reset();
+ {
}
};
@@ -55,7 +52,6 @@ protected:
}
~LoggerTest() {
- TestLogger::reset();
}
};
diff --git a/src/lib/log/xdebuglevel.cc b/src/lib/log/xdebuglevel.cc
deleted file mode 100644
index c17a515..0000000
--- a/src/lib/log/xdebuglevel.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <cassert>
-#include <algorithm>
-#include <syslog.h>
-#include <string.h>
-#include <boost/lexical_cast.hpp>
-
-#include <xdebuglevel.h>
-#include <debug_levels.h>
-#include <log4cxx/helpers/stringhelper.h>
-
-using namespace log4cxx;
-using namespace log4cxx::helpers;
-
-// Storage for the logging level objects corresponding to each debug level
-
-bool XDebugLevel::dbglevels_unset_ = true;
-LevelPtr XDebugLevel::dbglevels_[NUM_DEBUG_LEVEL];
-
-// Register the class
-
-IMPLEMENT_LOG4CXX_LEVEL(XDebugLevel)
-
-
-// Create Extended Debug Level Objects
-
-LevelPtr
-XDebugLevel::getExtendedDebug(int level) {
-
- // Initialize the logging levels corresponding to the possible range of
- // debug if we have not already done so
- if (dbglevels_unset_) {
-
- // Asserting that the minimum debug level is zero - so corresponds
- // to DEBUG_INT - means that the lowest level is set to main DEBUG
- // level. This means that the existing logging level object can be
- // used.
- assert(MIN_DEBUG_LEVEL == 0);
- dbglevels_[0] = Level::getDebug();
-
- // Create the logging level objects for the rest of the debug levels.
- // They are given names of the form DEBUG<debug level> (e.g. DEBUG42).
- // They will all correspond to a syslog level of DEBUG.
- for (int i = 1; i < NUM_DEBUG_LEVEL; ++i) {
- std::string name = std::string("DEBUG") +
- boost::lexical_cast<std::string>(i);
- dbglevels_[i] = new XDebugLevel(
- (XDebugLevel::XDEBUG_MIN_LEVEL_INT - i),
- LOG4CXX_STR(name.c_str()), LOG_DEBUG);
- }
- dbglevels_unset_ = false;
- }
-
- // Now get the logging level object asked for. Coerce the debug level to
- // lie in the acceptable range.
- int actual = std::max(MIN_DEBUG_LEVEL, std::min(MAX_DEBUG_LEVEL, level));
-
- // ... and return a pointer to the appropriate logging level object
- return (dbglevels_[actual - MIN_DEBUG_LEVEL]);
-}
-
-// Convert an integer (an absolute logging level number, not a debug level) to a
-// logging level object. If it lies outside the valid range, an object
-// corresponding to the minimum debug value is returned.
-
-LevelPtr
-XDebugLevel::toLevel(int val) {
- return (toLevel(val, getExtendedDebug(MIN_DEBUG_LEVEL)));
-}
-
-LevelPtr
-XDebugLevel::toLevel(int val, const LevelPtr& defaultLevel) {
-
- // Note the reversal of the notion of MIN and MAX - see the header file for
- // details.
- if ((val >= XDEBUG_MAX_LEVEL_INT) && (val <= XDEBUG_MIN_LEVEL_INT)) {
- return (getExtendedDebug(XDEBUG_MIN_LEVEL_INT - val));
- }
- else {
- return (defaultLevel);
- }
-}
-
-// Convert string passed to a logging level or return default level.
-
-LevelPtr
-XDebugLevel::toLevelLS(const LogString& sArg) {
- return (toLevelLS(sArg, getExtendedDebug(0)));
-}
-
-LevelPtr
-XDebugLevel::toLevelLS(const LogString& sArg, const LevelPtr& defaultLevel) {
- std::string name = sArg; // Get to known type
- size_t length = name.size(); // Length of the string
-
- if (length < 5) {
-
- // String can't possibly start DEBUG so we don't know what it is.
- return (defaultLevel);
- }
- else {
- if (strncasecmp(name.c_str(), "DEBUG", 5) == 0) {
-
- // String starts "DEBUG" (or "debug" or any case mixture). The
- // rest of the string -if any - should be a number.
- if (length == 5) {
-
- // It is plain "DEBUG". Take this as level 0.
- return (getExtendedDebug(0));
- }
- else {
-
- // Try converting the remainder to an integer. The "5" is
- // the length of the string "DEBUG". Note that if the number
- // is outside the rangeof debug levels, it is coerced to the
- // nearest limit. Thus a level of DEBUG509 will end up as
- // if DEBUG99 has been specified.
- try {
- int level = boost::lexical_cast<int>(name.substr(5));
- return (getExtendedDebug(level));
- }
- catch ((boost::bad_lexical_cast&) ){
- return (defaultLevel);
- }
- }
- }
- else {
-
- // Unknown string - return default.
- return (defaultLevel);
- }
- }
-}
diff --git a/src/lib/log/xdebuglevel.h b/src/lib/log/xdebuglevel.h
deleted file mode 100644
index e580b77..0000000
--- a/src/lib/log/xdebuglevel.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef __XDEBUGLEVEL_H
-#define __XDEBUGLEVEL_H
-
-#include <syslog.h>
-#include <log4cxx/level.h>
-
-#include <debug_levels.h>
-
-namespace log4cxx {
-
-/// \brief Debug Extension to Level Class
-///
-/// Based on the example given in the log4cxx distribution, this extends the
-/// log4cxx Level class to allow 100 debug levels.
-///
-/// First some terminology, as the use of the term "level" gets confusing. The
-/// code and comments here use the term "level" in two contexts:
-///
-/// Logging level: The category of messages to log. By default log4cxx defines
-/// the following logging levels: OFF, FATAL, ERROR, WARNING, INFO, DEBUG,
-/// TRACE, ALL. Within the context of BIND-10, OFF, TRACE and ALL are not used
-/// and the idea of DEBUG has been extended, as will be seen below.
-///
-/// Debug level: This is a number that ranges from 0 to 99 and is used by the
-/// application to control the detail of debug output. A value of 0 gives the
-/// highest-level debug output; a value of 99 gives the most verbose and most
-/// detailed. Debug messages (or whatever debug level) are only ever output
-/// when the logging level is set to DEBUG.
-///
-///
-/// With log4cxx, the various logging levels have a numeric value associated
-/// with them, such that FATAL > ERROR > WARNING etc. This suggests that the
-/// idea of debug levels can be incorporated into the existing logging level
-/// scheme by assigning them appropriate numeric values, i.e.
-///
-/// WARNING > INFO > DEBUG(0) > DEBUG(2) > ... > DEBUG(99)
-///
-/// Setting a numeric level of DEBUG enables the basic messages; setting lower
-/// numeric levels will enable progressively more messages. The lowest debug
-/// level (0) is chosen such that setting the general DEBUG logging level will
-/// automatically select that debug level.
-///
-/// This sub-class is needed because the log4cxx::Level class does not allow
-/// the setting of the numeric value of the current level to something other
-/// than the values enumerated in the class. It creates a set of log4cxx
-/// logging levels to correspond to the various debug levels. These levels have
-/// names in the range DEBUG1 to DEBUG99 (the existing Level DEBUG is used for
-/// a debug level of 0), although they are not used in BIND-10: instead the
-/// BIND-10 Logger class treats the logging levels and debug levels separately
-/// and combines them to choose the underlying log4cxx logging level.
-
-
-/// \brief Debug-Extended Level
-
-class XDebugLevel : public Level {
- DECLARE_LOG4CXX_LEVEL(XDebugLevel)
-
- /// Array of pointers to logging level objects, one for each debug level.
- /// The pointer corresponding to a debug level of 0 points to the DEBUG
- /// logging level object.
- static LevelPtr dbglevels_[NUM_DEBUG_LEVEL];
- static bool dbglevels_unset_;
-
-public:
-
- // Minimum and maximum debug levels. Note that XDEBUG_MIN_LEVEL_INT is the
- // number corresponding to the minimum debug level - and is actually larger
- // that XDEBUG_MAX_LEVEL_INT, the number corresponding to the maximum debug
- // level.
- enum {
- XDEBUG_MIN_LEVEL_INT = Level::DEBUG_INT - MIN_DEBUG_LEVEL,
- XDEBUG_MAX_LEVEL_INT = Level::DEBUG_INT - MAX_DEBUG_LEVEL
- };
-
- /// \brief Constructor
- ///
- /// \param level Numeric value of the logging level.
- /// \param name Name given to this logging level.
- /// \param syslogEquivalent The category to be used by syslog when it logs
- /// an event associated with the specified logging level.
- XDebugLevel(int level, const LogString& name, int syslogEquivalent) :
- Level(level, name, syslogEquivalent)
- {}
-
- /// \brief Create Logging Level Object
- ///
- /// Creates a logging level object corresponding to one of the debug levels.
- ///
- /// \param dbglevel The debug level, which ranges from MIN_DEBUG_LEVEL to
- /// MAX_DEBUG_LEVEL. It is coerced to that range if it lies outside it.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr getExtendedDebug(int dbglevel);
-
- /// \brief Convert Integer to a Logging Level
- ///
- /// Returns a logging level object corresponding to the given value (which
- /// is an absolute value of a logging level - it is not a debug level).
- /// If the number is invalid, an object of logging level DEBUG (the
- /// minimum debug logging level) is returned.
- ///
- /// \param val Number to convert to a logging level. This is an absolute
- /// logging level number, not a debug level.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevel(int val);
-
- /// \brief Convert Integer to a Level
- ///
- /// Returns a logging level object corresponding to the given value (which
- /// is an absolute value of a logging level - it is not a debug level).
- /// If the number is invalid, the given default is returned.
- ///
- /// \param val Number to convert to a logging level. This is an absolute
- /// logging level number, not a debug level.
- /// \param defaultLevel Logging level to return if value is not recognised.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevel(int val, const LevelPtr& defaultLevel);
-
- /// \brief Convert String to Logging Level
- ///
- /// Returns a logging level object corresponding to the given name. If the
- /// name is invalid, an object of logging level DEBUG (the minimum debug
- /// logging level) is returned.
- ///
- /// \param sArg Name of the logging level.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevelLS(const LogString& sArg);
-
- /// \brief Convert String to Logging Level
- ///
- /// Returns a logging level object corresponding to the given name. If the
- /// name is invalid, the given default is returned.
- ///
- /// \param sArg name of the level.
- /// \param defaultLevel Logging level to return if name doesn't exist.
- ///
- /// \return Pointer to the desired logging level object.
- static LevelPtr toLevelLS(const LogString& sArg,
- const LevelPtr& defaultLevel);
-};
-
-} // namespace log4cxx
-
-
-#endif // __XDEBUGLEVEL_H
More information about the bind10-changes
mailing list