Browse Source

[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.
Stephen Morris 14 years ago
parent
commit
192aefd97c

+ 7 - 5
src/lib/log/Makefile.am

@@ -6,12 +6,16 @@ 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
@@ -19,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)

+ 0 - 29
src/lib/log/debug_levels.h

@@ -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

+ 1 - 1
src/lib/log/log_formatter.h

@@ -17,7 +17,7 @@
 
 #include <string>
 #include <boost/lexical_cast.hpp>
-#include <log/logger_levels.h>
+#include <log/logger_level.h>
 
 namespace isc {
 namespace log {

+ 1 - 8
src/lib/log/logger.cc

@@ -112,7 +112,7 @@ Logger::isFatalEnabled() {
 // Output methods
 
 void
-Logger::output(const Severity& severity, const string& message) {
+Logger::output(const Severity& severity, const std::string& message) {
     getLoggerPtr()->outputRaw(severity, message);
 }
 
@@ -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

+ 1 - 10
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>
 
@@ -179,14 +178,6 @@ 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>;
 

+ 41 - 99
src/lib/log/logger_impl.cc

@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE
 
-#include <iostream>
 #include <iomanip>
 #include <algorithm>
 
@@ -23,10 +22,10 @@
 
 #include <log4cplus/configurator.h>
 
-#include <log/debug_levels.h>
 #include <log/root_logger_name.h>
 #include <log/logger.h>
-#include <log/logger_levels.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>
@@ -35,6 +34,7 @@
 #include <util/strutil.h>
 
 using namespace std;
+using namespace log4cplus;
 
 namespace isc {
 namespace log {
@@ -45,21 +45,24 @@ namespace log {
 // 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_);
     }
-    fmt_name_ = std::string("[") + name_ + std::string("] ");
 
-    // Initialize log4cplus if not already done
-    initLog4cplus();
-
-    // Return existing instance of logger, creating it if it does not exist.
-    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.)
@@ -68,49 +71,44 @@ LoggerImpl::~LoggerImpl() {
 }
 
 // Set the severity for logging.
-// TODO IGNORE DEBUG LEVEL FOR NOW
-
 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));
-    logger_.setLogLevel(convertFromBindSeverity(severity));
+LoggerImpl::setSeverity(isc::log::Severity severity, int dbglevel) {
+    isc::log::Level level(severity, dbglevel);
+    logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level));
 }
 
 // Return severity level
-
 isc::log::Severity
 LoggerImpl::getSeverity() {
-    return convertToBindSeverity(logger_.getLogLevel());
+    isc::log::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());
+    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() {
-    return convertToBindSeverity(logger_.getChainedLogLevel());
+    isc::log::Level level = 
+        LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+    return level.severity;
 }
 
-
-// Get the debug level.  This returns 0 unless the severity is DEBUG.
-// TODO: DEBUG LEVEL IGNORED FOR NOW
-
+// Return effective debug level (only valid if current effective severity level
+// is DEBUG).
 int
-LoggerImpl::getDebugLevel() {
-    return (0);
-}
-
-// 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.
-// TODO: DEBUG LEVEL IGNORED FOR NOW
-
-bool
-LoggerImpl::isDebugEnabled(int dbglevel) {
-    return logger_.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL);
+LoggerImpl::getEffectiveDebugLevel() {
+    isc::log::Level level =
+        LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+    return level.dbglevel;
 }
 
 
@@ -145,68 +143,6 @@ LoggerImpl::outputRaw(const Severity& severity, const string& message) {
     }
 }
 
-// Convert levels - from BIND 10 level to log4cplus level.
-// Namespaces explicitly used to clarify what level we are talking about
-log4cplus::LogLevel
-LoggerImpl::convertFromBindSeverity(const isc::log::Severity& inlevel) {
-
-    // BIND 10 logging levels are small integers so we can do a table lookup
-    static const log4cplus::LogLevel level[] = {
-        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>(isc::log::DEFAULT) == 0);
-    BOOST_STATIC_ASSERT(static_cast<int>(isc::log::DEBUG) == 1);
-    BOOST_STATIC_ASSERT(static_cast<int>(isc::log::INFO) == 2);
-    BOOST_STATIC_ASSERT(static_cast<int>(isc::log::WARN) == 3);
-    BOOST_STATIC_ASSERT(static_cast<int>(isc::log::ERROR) == 4);
-    BOOST_STATIC_ASSERT(static_cast<int>(isc::log::FATAL) == 5);
-    BOOST_STATIC_ASSERT(static_cast<int>(isc::log::NONE) == 6);
-
-    // No need to check that the iundex is out of range.  Setting the type of
-    // the argument to 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 (level[inlevel]);
-}
-
-// Convert levels - from log4plus level to BIND 10 level
-// Namespaces explicitly used to clarify what level we are talking about
-isc::log::Severity
-LoggerImpl::convertToBindSeverity(const log4cplus::LogLevel& inlevel) {
-
-    // Not easy to do a table lookup as the numerical values of log4cplus levels
-    // are quite high.
-    switch (inlevel) {
-        case log4cplus::NOT_SET_LOG_LEVEL:
-            return (isc::log::DEFAULT);
-
-        case log4cplus::DEBUG_LOG_LEVEL:
-            return (isc::log::DEBUG);
-
-        case log4cplus::INFO_LOG_LEVEL:
-            return (isc::log::INFO);
-
-        case log4cplus::WARN_LOG_LEVEL:
-            return (isc::log::WARN);
-
-        case log4cplus::ERROR_LOG_LEVEL:
-            return (isc::log::ERROR);
-
-        case log4cplus::FATAL_LOG_LEVEL:
-            return (isc::log::FATAL);
-    }
-
-    return (isc::log::NONE);
-}
-
 // One-time initialization of log4cplus
 
 
@@ -215,8 +151,14 @@ LoggerImpl::initLog4cplus() {
     static bool not_initialized = true;
 
     if (not_initialized) {
+        // Set up basic configurator
         log4cplus::BasicConfigurator config;
         config.configure();
+
+        // Add additional debug levels
+        LoggerLevelImpl::init();
+
+        // All done.
         not_initialized = false;
     }
 }

+ 35 - 70
src/lib/log/logger_impl.h

@@ -18,6 +18,7 @@
 #include <stdarg.h>
 #include <time.h>
 
+#include <iostream>
 #include <cstdlib>
 #include <string>
 #include <map>
@@ -28,10 +29,8 @@
 #include <log4cplus/logger.h>
 
 // BIND-10 logger files
-#include <log/debug_levels.h>
-#include <log/logger.h>
+#include <log/logger_level_impl.h>
 #include <log/message_types.h>
-#include <log/root_logger_name.h>
 
 namespace isc {
 namespace log {
@@ -40,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.
@@ -99,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
@@ -116,23 +102,32 @@ 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() {
@@ -180,36 +175,7 @@ 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:
-    /// \brief Convert Log Levels
-    ///
-    /// Converts a BIND 10 log level to a log4cplus log level.
-    ///
-    /// \param inlevel BIND 10 log level.
-    ///
-    /// \return Log4cplus log level.
-    log4cplus::LogLevel convertFromBindSeverity(
-        const isc::log::Severity& inlevel);
-
-    /// \brief Convert Log Levels
-    ///
-    /// Converts a log4cplus log level to a BIND 10 log level.
-    ///
-    /// \param inlevel log4cplus log level.
-    ///
-    /// \return BIND 10 log level.
-    isc::log::Severity convertToBindSeverity(
-        const log4cplus::LogLevel& inlevel);
 
     /// \brief Initialize log4cplus
     ///
@@ -219,9 +185,8 @@ private:
 
     bool                is_root_;           ///< Is this BIND 10 root logger?
     std::string         name_;              ///< Full name of this logger
-    std::string         fmt_name_;          ///< Formatted name
+    std::string         fmt_name_;          ///< Formatted name for output
     log4cplus::Logger   logger_;            ///< Underlying log4cplus logger
-
 };
 
 } // namespace log

+ 23 - 3
src/lib/log/logger_levels.h

@@ -12,8 +12,8 @@
 // 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
+#ifndef __LOGGER_LEVEL_H
+#define __LOGGER_LEVEL_H
 
 namespace isc {
 namespace log {
@@ -36,7 +36,27 @@ typedef enum {
     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_LEVELS_H
+#endif // __LOGGER_LEVEL_H

+ 189 - 0
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

+ 127 - 0
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

+ 1 - 1
src/lib/log/tests/log_formatter_unittest.cc

@@ -14,7 +14,7 @@
 
 #include <gtest/gtest.h>
 #include <log/log_formatter.h>
-#include <log/logger_levels.h>
+#include <log/logger_level.h>
 
 #include <vector>
 #include <string>

+ 1 - 5
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();
     }
 };
 

+ 0 - 146
src/lib/log/xdebuglevel.cc

@@ -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);
-        }
-    }
-}

+ 0 - 162
src/lib/log/xdebuglevel.h

@@ -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