BIND 10 master, updated. db21e8ab55f132828542f1a34642d98bbaf6d8ee [trac899] ChangeLog entry for trac899

BIND 10 source code commits bind10-changes at lists.isc.org
Tue May 31 12:52:25 UTC 2011


The branch, master has been updated
       via  db21e8ab55f132828542f1a34642d98bbaf6d8ee (commit)
       via  31d3f525dc01638aecae460cb4bc2040c9e4df10 (commit)
       via  489ef1ad9701548d0987c45cab34d33d8dcb73fa (commit)
       via  c24dd6f877460227e6eed02d0cca0956366748cb (commit)
       via  dc44fdda4e0705993f44275d22b2daa45d4bae6f (commit)
       via  160519b6e3c5da340011b454e034a188529a4cc8 (commit)
       via  5538d85d751405c573cfc0491b1e663bb7ce19f5 (commit)
       via  862e13c5c852b8ea55c1b53a67803105d473a342 (commit)
       via  ee0e702fa85ebecb95ac89aeba5959b111ba5d57 (commit)
       via  0dcde0e52b99cade8f584751b2d2756c20e78625 (commit)
       via  f1213a3d4df71a4009a3f9a09a9aab002b42ce35 (commit)
       via  50dd99f81efde9267569def411a470e082ac312b (commit)
       via  2273e3e71f5879cdf51f956c19a153f4280d9531 (commit)
       via  c926e1e8bf4eedc6c999c6ad1a1f0fff96783154 (commit)
       via  192aefd97c825f7636e0885eecef9a5834e53d05 (commit)
       via  4fcd0d3125dd7d8441f33c3ebf8b63e5b2093a68 (commit)
      from  e402f8d476894b34d7bce97fbc961123e4775b4f (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 db21e8ab55f132828542f1a34642d98bbaf6d8ee
Author: Stephen Morris <stephen at isc.org>
Date:   Tue May 31 13:47:05 2011 +0100

    [trac899] ChangeLog entry for trac899

commit 31d3f525dc01638aecae460cb4bc2040c9e4df10
Author: Stephen Morris <stephen at isc.org>
Date:   Tue May 31 13:17:35 2011 +0100

    [trac899] Note change of name for include file
    
    Correct src/bin/resolver/main.cc which got changed in master after
    this branch was started.

commit 489ef1ad9701548d0987c45cab34d33d8dcb73fa
Merge: c24dd6f877460227e6eed02d0cca0956366748cb e402f8d476894b34d7bce97fbc961123e4775b4f
Author: Stephen Morris <stephen at isc.org>
Date:   Tue May 31 13:07:23 2011 +0100

    [trac899] Merge branch 'master' into trac899
    
    Conflicts:
    	src/bin/resolver/tests/Makefile.am
    	src/lib/config/tests/Makefile.am
    	src/lib/log/tests/Makefile.am
    	src/lib/resolve/tests/Makefile.am
    	src/lib/server_common/tests/Makefile.am
    	tests/tools/badpacket/tests/Makefile.am

commit c24dd6f877460227e6eed02d0cca0956366748cb
Author: Stephen Morris <stephen at isc.org>
Date:   Tue May 31 12:22:29 2011 +0100

    [trac899] Initialise member variable before running constructor
    
    The FreeBSD compiler complained that the member variable logger_
    could not be constructed because the data type (log4cplus::Logger)
    has no default constructor.  It is therefore initialized to point
    to the log4cplus root logger (the one that is guaranteed to exist),
    even though the LoggerImpl constructor may reset it immediately
    afterwards.

commit dc44fdda4e0705993f44275d22b2daa45d4bae6f
Author: Stephen Morris <stephen at isc.org>
Date:   Wed May 25 15:08:22 2011 +0100

    [trac899] Corrected typo in a comment

commit 160519b6e3c5da340011b454e034a188529a4cc8
Author: Stephen Morris <stephen at isc.org>
Date:   Wed May 25 15:03:51 2011 +0100

    [trac899] Corrected placement of $(LOG4CPLUS_LDFLAGS)
    
    This only needed to be in the Makefile.am for the liblog library,
    not everywhere else!

commit 5538d85d751405c573cfc0491b1e663bb7ce19f5
Author: Stephen Morris <stephen at isc.org>
Date:   Wed May 25 13:21:52 2011 +0100

    [trac899] Changes as a result of review

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |    4 +
 configure.ac                                       |   51 ++++
 src/bin/auth/benchmarks/Makefile.am                |    1 +
 src/bin/resolver/main.cc                           |    4 +-
 src/bin/resolver/tests/Makefile.am                 |    5 +-
 src/lib/asiodns/tests/Makefile.am                  |    2 +-
 src/lib/asiolink/tests/Makefile.am                 |    2 +-
 src/lib/cache/tests/Makefile.am                    |   26 +-
 src/lib/datasrc/tests/Makefile.am                  |    6 +-
 src/lib/log/Makefile.am                            |   17 +-
 src/lib/log/README                                 |   99 ++------
 src/lib/log/compiler/Makefile.am                   |    8 +-
 src/lib/log/debug_levels.h                         |   29 ---
 src/lib/log/log_formatter.h                        |   38 ++-
 src/lib/log/logger.cc                              |   23 +-
 src/lib/log/logger.h                               |   58 +----
 src/lib/log/logger_impl.cc                         |  259 ++++++++++----------
 src/lib/log/logger_impl.h                          |  165 +++++++------
 src/lib/log/{logger_levels.h => logger_level.h}    |   26 ++-
 src/lib/log/logger_level_impl.cc                   |  194 +++++++++++++++
 src/lib/log/logger_level_impl.h                    |  127 ++++++++++
 src/lib/log/logger_support.cc                      |    4 +-
 src/lib/log/tests/Makefile.am                      |   17 +-
 src/lib/log/tests/log_formatter_unittest.cc        |   37 ++--
 src/lib/log/tests/logger_level_impl_unittest.cc    |  171 +++++++++++++
 ...r_name_unittest.cc => logger_level_unittest.cc} |   52 +++--
 src/lib/log/tests/logger_support_test.cc           |    2 +-
 src/lib/log/tests/logger_unittest.cc               |   45 ++--
 src/lib/log/xdebuglevel.cc                         |  146 -----------
 src/lib/log/xdebuglevel.h                          |  162 ------------
 src/lib/nsas/tests/Makefile.am                     |    4 +-
 src/lib/resolve/tests/Makefile.am                  |    6 +-
 tests/tools/badpacket/Makefile.am                  |    2 +-
 tests/tools/badpacket/tests/Makefile.am            |    6 +-
 34 files changed, 980 insertions(+), 818 deletions(-)
 delete mode 100644 src/lib/log/debug_levels.h
 rename src/lib/log/{logger_levels.h => logger_level.h} (68%)
 create mode 100644 src/lib/log/logger_level_impl.cc
 create mode 100644 src/lib/log/logger_level_impl.h
 create mode 100644 src/lib/log/tests/logger_level_impl_unittest.cc
 copy src/lib/log/tests/{root_logger_name_unittest.cc => logger_level_unittest.cc} (52%)
 delete mode 100644 src/lib/log/xdebuglevel.cc
 delete mode 100644 src/lib/log/xdebuglevel.h

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 10db072..e8b05ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+246.    [func]      stephen
+	Implement logging using log4cplus (http://log4cplus.sourceforge.net)
+	(Trac899, git 31d3f525dc01638aecae460cb4bc2040c9e4df10)
+
 245.    [func]      vorner
 	Authoritative server can now sign the answers using TSIG
 	(configured in tsig_keys/keys, list of strings like
diff --git a/configure.ac b/configure.ac
index 93b9304..1ec06c6 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
 #
@@ -901,6 +950,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/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am
index a569147..77d171f 100644
--- a/src/bin/auth/benchmarks/Makefile.am
+++ b/src/bin/auth/benchmarks/Makefile.am
@@ -26,3 +26,4 @@ query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
 query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
 query_bench_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
 query_bench_LDADD += $(SQLITE_LIBS)
+
diff --git a/src/bin/resolver/main.cc b/src/bin/resolver/main.cc
index b0776ea..cb27fae 100644
--- a/src/bin/resolver/main.cc
+++ b/src/bin/resolver/main.cc
@@ -53,7 +53,7 @@
 #include <nsas/nameserver_address_store.h>
 
 #include <log/logger_support.h>
-#include <log/debug_levels.h>
+#include <log/logger_level.h>
 #include "resolver_log.h"
 
 using namespace std;
@@ -127,7 +127,7 @@ main(int argc, char* argv[]) {
     // temporary initLogger() code.  If verbose, we'll use maximum verbosity.
     isc::log::initLogger("b10-resolver",
                          (verbose ? isc::log::DEBUG : isc::log::INFO),
-                         MAX_DEBUG_LEVEL, NULL);
+                         isc::log::MAX_DEBUG_LEVEL, NULL);
 
     // Print the starting message
     string cmdline = argv[0];
diff --git a/src/bin/resolver/tests/Makefile.am b/src/bin/resolver/tests/Makefile.am
index 366fb94..1ec6853 100644
--- a/src/bin/resolver/tests/Makefile.am
+++ b/src/bin/resolver/tests/Makefile.am
@@ -31,8 +31,9 @@ run_unittests_SOURCES += run_unittests.cc
 nodist_run_unittests_SOURCES = ../resolverdef.h ../resolverdef.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+
+run_unittests_LDADD  = $(GTEST_LDADD)
 run_unittests_LDADD += $(SQLITE_LIBS)
 run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libtestutils.la
 run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
diff --git a/src/lib/asiodns/tests/Makefile.am b/src/lib/asiodns/tests/Makefile.am
index 7e05c18..fd9acd8 100644
--- a/src/lib/asiodns/tests/Makefile.am
+++ b/src/lib/asiodns/tests/Makefile.am
@@ -34,7 +34,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
 
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) 
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
diff --git a/src/lib/asiolink/tests/Makefile.am b/src/lib/asiolink/tests/Makefile.am
index af4f679..b0449a2 100644
--- a/src/lib/asiolink/tests/Makefile.am
+++ b/src/lib/asiolink/tests/Makefile.am
@@ -40,7 +40,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) 
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
diff --git a/src/lib/cache/tests/Makefile.am b/src/lib/cache/tests/Makefile.am
index 014ad43..39215d9 100644
--- a/src/lib/cache/tests/Makefile.am
+++ b/src/lib/cache/tests/Makefile.am
@@ -32,20 +32,20 @@ TESTS =
 if HAVE_GTEST
 TESTS += run_unittests
 run_unittests_SOURCES  = run_unittests.cc
-run_unittests_SOURCES  += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
-run_unittests_SOURCES  += rrset_entry_unittest.cc
-run_unittests_SOURCES  += rrset_cache_unittest.cc
-run_unittests_SOURCES  += message_cache_unittest.cc
-run_unittests_SOURCES  += message_entry_unittest.cc
-run_unittests_SOURCES  += local_zone_data_unittest.cc
-run_unittests_SOURCES  += resolver_cache_unittest.cc
-run_unittests_SOURCES  += negative_cache_unittest.cc
-run_unittests_SOURCES  += cache_test_messagefromfile.h
-run_unittests_SOURCES  += cache_test_sectioncount.h
+run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
+run_unittests_SOURCES += rrset_entry_unittest.cc
+run_unittests_SOURCES += rrset_cache_unittest.cc
+run_unittests_SOURCES += message_cache_unittest.cc
+run_unittests_SOURCES += message_entry_unittest.cc
+run_unittests_SOURCES += local_zone_data_unittest.cc
+run_unittests_SOURCES += resolver_cache_unittest.cc
+run_unittests_SOURCES += negative_cache_unittest.cc
+run_unittests_SOURCES += cache_test_messagefromfile.h
+run_unittests_SOURCES += cache_test_sectioncount.h
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDFLAGS  = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDADD    = $(GTEST_LDADD)
 
 # NOTE: we may have to clean up this hack later (see the note in configure.ac)
 if NEED_LIBBOOST_THREAD
@@ -62,7 +62,7 @@ endif
 
 noinst_PROGRAMS = $(TESTS)
 
-EXTRA_DIST = testdata/message_cname_referral.wire
+EXTRA_DIST  = testdata/message_cname_referral.wire
 EXTRA_DIST += testdata/message_example_com_soa.wire
 EXTRA_DIST += testdata/message_fromWire1
 EXTRA_DIST += testdata/message_fromWire2
diff --git a/src/lib/datasrc/tests/Makefile.am b/src/lib/datasrc/tests/Makefile.am
index 471d802..fbcf9c9 100644
--- a/src/lib/datasrc/tests/Makefile.am
+++ b/src/lib/datasrc/tests/Makefile.am
@@ -28,9 +28,11 @@ run_unittests_SOURCES += rbtree_unittest.cc
 run_unittests_SOURCES += zonetable_unittest.cc
 run_unittests_SOURCES += memory_datasrc_unittest.cc
 run_unittests_SOURCES += logger_unittest.cc
+
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+
+run_unittests_LDADD  = $(GTEST_LDADD)
 run_unittests_LDADD += $(SQLITE_LIBS)
 run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
 run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
diff --git a/src/lib/log/Makefile.am b/src/lib/log/Makefile.am
index c27b3e4..cdc0642 100644
--- a/src/lib/log/Makefile.am
+++ b/src/lib/log/Makefile.am
@@ -2,18 +2,20 @@ 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
 
 CLEANFILES = *.gcno *.gcda
 
 lib_LTLIBRARIES = liblog.la
 liblog_la_SOURCES  =
-liblog_la_SOURCES += debug_levels.h 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.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,9 @@ 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
 
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
@@ -39,5 +37,6 @@ if USE_CLANGPP
 # Same for clang++, but we need to turn off -Werror completely.
 liblog_la_CXXFLAGS += -Wno-error
 endif
-liblog_la_CPPFLAGS = $(AM_CPPFLAGS)
-liblog_la_LIBADD = $(top_builddir)/src/lib/util/libutil.la
+liblog_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+liblog_la_LDFLAGS  = $(LOG4CPLUS_LDFLAGS)
+liblog_la_LIBADD   = $(top_builddir)/src/lib/util/libutil.la
diff --git a/src/lib/log/README b/src/lib/log/README
index 529eefc..6b4cf11 100644
--- a/src/lib/log/README
+++ b/src/lib/log/README
@@ -117,7 +117,7 @@ Points to note:
 * Lines starting $ are directives.  At present, two directives are recognised:
 
   * $PREFIX, which has one optional argument: the string used to prefix symbols.
-    If absent, there is no prefix to the symbols. (Prefixes are explained below.)
+    If absent, there is no prefix to the symbols (prefixes are explained below).
 
   * $NAMESPACE, which has one argument: the namespace in which the symbols are
     created.  In the absence of a $NAMESPACE directive, symbols will be put in
@@ -135,7 +135,7 @@ Points to note:
   * The replacement tokens are the strings "%1", "%2" etc.  When a message
     is logged, these are replaced with the arguments passed to the logging
     call: %1 refers to the first argument, %2 to the second etc.  Within the
-    message text, the placeholders can appear in any order, and placeholders
+    message text, the placeholders can appear in any order and placeholders
     can be repeated.
      
 * Remaining lines indicate an explanation for the preceding message.  These
@@ -215,33 +215,9 @@ To use the current version of the logging:
 
 1. Build message header file and source file as describe above.
 
-2. In the main module of the program, declare an instance of the
-   RootLoggerName class to define the name of the program's root logger, e.g.
-
-       #include <log/root_logger_name.h>
-
-       isc::log::RootLoggerName("b10-auth");
-
-   This can be declared inside or outside an execution unit.
-
-2. In the code that needs to do logging, declare a logger with a given name,
-   e.g.
-
-       #include <log/logger.h>
-            :
-       isc::log::Logger logger("myname");   // "myname" can be anything
-
-   The above example assumes declaration outside a function.  If declaring
-   non-statically within a function, declare it as:
-
-       isc::log::Logger logger("myname", true);
-
-   (The argument is required to support a possible future implementation of
-   logging.  Currently it has no effect.)
-
-3. The main program unit should include a call to isc::log::initLogger()
+2. The main program unit should include a call to isc::log::initLogger()
    (defined in logger_support.h) to set the logging severity, debug log level,
-   and external message file.
+   and external message file:
 
    a) The logging severity is one of the enum defined in logger.h, i.e.
 
@@ -262,56 +238,43 @@ To use the current version of the logging:
       directive of a particular type will be ignored; multiple directives will
       cause the read of the file to fail with an error.)
 
-4. Issue logging calls using methods on logger, e.g.
+   The settings remain in effect until the logging configuration is read, and
+   so provide the default logging during program initialization.
 
-       logger.error(DPS_NSTIMEOUT).arg("isc.org");
+3. Issue logging calls using supplied macros in "log/macros.h", e.g.
 
-   (where, in the example above we might have defined the symbol in the message
+       LOG_ERROR(logger, DPS_NSTIMEOUT).arg("isc.org");
+
+   (The macros are more efficient that calls to the methods on the logger class:
+   they avoid the overhead of evaluating the parameters to arg() if the
+   settings are such that the message is not going to be output.)
+
+   Note: in the example above we might have defined the symbol in the message
    file with something along the lines of:
 
        $PREFIX DPS_
            :
        NSTIMEOUT  queries to all nameservers for %1 have timed out
 
-   At present, the only logging is to the console.
-
-
-Efficiency Considerations
--------------------------
-A common pattern in logging is a debug call of the form:
-
-   logger.debug(dbglevel, MSGID).arg(expensive_call()).arg(...
-
-... where "expensive_call()" is a function call to obtain logging information
-that may be computationally intensive.  Although the cost may be justified
-when debugging is enabled, the cost is still incurred even if debugging is
-disabled and the debug() method returns without outputting anything.  (The
-same may be true of other logging levels, although there are likely to be
-fewer calls to logger.info(), logger.error() etc. throughout the code and
-they are less likely to be disabled.)
-
-For this reason, a set of macros is provided and are called using the
-construct:
-
-   LOG_DEBUG(logger, dbglevel, MSGID).arg(expensive_call()).arg(...
-   LOG_INFO(logger, MSGID).arg(expensive_call()...)
-
-If these are used, the arguments passed to the arg() method are not evaluated
-if the relevant logging level is disabled.
-
-
 Severity Guidelines
 ===================
 When using logging, the question arises, what severity should a message be
 logged at?  The following is a suggestion - as always, the decision must be
 made in the context of which the message is logged.
 
+One thing that should always be borne in mind is whether the logging could
+be used as a vector for a DOS attack.  For example, if a warning message is
+logged every time an invalid packet is received, an attacker could simply send
+large numbers of invalid packets.  (Of course, warnings could be disabled (or
+just warnings for that that particular logger), but nevertheless the message
+is an attack vector.)
+
 FATAL
 -----
-The program has encountered an error that is so severe that it cannot
-continue (or there is no point in continuing).  When a fatal error has been
-logged, the program will usually exit immediately (via a call to abort()) or
-shortly afterwards, after dumping some diagnostic information.
+The program has encountered an error that is so severe that it cannot continue
+(or there is no point in continuing).  When a fatal error has been logged,
+the program will usually exit immediately (or shortly afterwards) after
+dumping some diagnostic information.
 
 ERROR
 -----
@@ -342,7 +305,7 @@ are distributed between the levels is up to the developer.  So if debugging
 the NSAS (for example), a level 0 message might record the creation of a new
 zone, a level 10 recording a timeout when trying to get a nameserver address,
 but a level 50 would record every query for an address. (And we might add
-level 51 to record every update of the RTT.)
+level 70 to record every update of the RTT.)
 
 Note that like severities, levels are cumulative; so if level 25 is set as the
 debug level, all debug levels from 0 to 25 will be output.  In fact, it is
@@ -397,13 +360,3 @@ is only one piece of code that does this functionality.
 Outstanding Issues
 ==================
 * Ability to configure system according to configuration database.
-
-
-log4cxx Issues
-==============
-Some experimental code to utilise log4cxx as an underlying implementation
-is present in the source code directory although it is not currently used.
-The files are:
-
-   logger_impl_log4cxx.{cc,h}
-   xdebuglevel.{cc,h}
diff --git a/src/lib/log/compiler/Makefile.am b/src/lib/log/compiler/Makefile.am
index d51ba05..1f47ba9 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)
@@ -14,7 +12,7 @@ endif
 CLEANFILES = *.gcno *.gcda
 
 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_SOURCES = message.cc
+message_LDADD   = $(top_builddir)/src/lib/log/liblog.la
+message_LDADD  += $(top_builddir)/src/lib/util/libutil.la
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..3833a4b 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,17 @@ 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 this method does a replacement and returns the
+            // modified string. If there are multiple invocations of arg() (e.g.
+            // logger.info(msgid).arg(xxx).arg(yyy)...), each invocation
+            // operates on the string returned by the previous one. This
+            // sequential operation means that if we had a message like "%1 %2",
+            // and called .arg("%2").arg(42), we would get "42 42"; the first
+            // call replaces the %1" with "%2" and the second replaces all
+            // occurrences of "%2" with 42. (Conversely, the sequence
+            // .arg(42).arg("%1") would return "42 %1" - there are no recursive
+            // replacements).
+            replacePlaceholder(message_, arg, ++nextPlaceholder_ );
         }
         return (*this);
     }
diff --git a/src/lib/log/logger.cc b/src/lib/log/logger.cc
index c340315..fdca964 100644
--- a/src/lib/log/logger.cc
+++ b/src/lib/log/logger.cc
@@ -31,7 +31,7 @@ namespace log {
 // Initialize Logger implementation.  Does not check whether the implementation
 // has already been initialized - that was done by the caller (getLoggerPtr()).
 void Logger::initLoggerImpl() {
-    loggerptr_ = new LoggerImpl(name_, infunc_);
+    loggerptr_ = new LoggerImpl(name_);
 }
 
 // Destructor.
@@ -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,18 +159,21 @@ 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());
     }
 }
 
-bool Logger::operator==(Logger& other) {
+// Comparison (testing only)
+
+bool
+Logger::operator==(Logger& other) {
     return (*getLoggerPtr() == *other.getLoggerPtr());
 }
 
-// Protected methods (used for testing)
+// Reset (used in testing only).  This is a static method.
 
 void
 Logger::reset() {
diff --git a/src/lib/log/logger.h b/src/lib/log/logger.h
index 6bd8924..94c6c94 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>
 
@@ -56,32 +55,7 @@ public:
     /// \param name Name of the logger.  If the name is that of the root name,
     /// this creates an instance of the root logger; otherwise it creates a
     /// child of the root logger.
-    ///
-    /// \param infunc This argument is present to get round a bug in some
-    /// implementations of the logging system.  If the logger is declared in
-    /// a function (such that it will be deleted when the function exits,
-    /// before the program ends), set this true.  If declared outside a
-    /// function (such that it gets deleted during program rundown), set false
-    /// (the default).\n
-    /// \n
-    /// The problems encountered was that during program rundown, one logging
-    /// implementation (log4cxx) threw a MutexException (this is described in
-    /// https://issues.apache.org/jira/browse/LOGCXX-322).  As this only occurs
-    /// during program rundown, the issue is not serious - it just looks bad to
-    /// have the program crash instead of shut down cleanly.\n
-    /// \n
-    /// If log4cxx is chosen as the implementation, this flag controls the
-    /// deletion of the underlying log4cxx data structures when the logger is
-    /// deleted.  Setting it false for externally-declared loggers inhibits
-    /// their deletion; so at program exit the memory is not reclaimed during
-    /// program rundown, only when the process is selected.  Setting it true
-    /// for loggers that will be deleted in the normal running of the program
-    /// enables their deletion - which causes no issues as the problem only
-    /// manifests itself during program rundown.
-    /// \n
-    /// The flag has no effect on non-log4cxx implementations.
-    Logger(const std::string& name, bool infunc = false) :
-        loggerptr_(NULL), name_(name), infunc_(infunc)
+    Logger(const std::string& name) : loggerptr_(NULL), name_(name)
     {}
 
     /// \brief Destructor
@@ -95,7 +69,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 +80,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 +93,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 +106,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 +125,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.
@@ -188,25 +148,26 @@ public:
     /// \brief Equality
     ///
     /// Check if two instances of this logger refer to the same stream.
-    /// (This method is principally for testing.)
     ///
     /// \return true if the logger objects are instances of the same logger.
     bool operator==(Logger& other);
 
 protected:
-
-    /// \brief Reset Global Data
+    /// \brief Clear logging hierachy
     ///
-    /// Used for testing, this calls upon the underlying logger implementation
-    /// to clear any global data.
+    /// This is for test use only, hence is protected.
     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
     ///
@@ -245,7 +206,6 @@ private:
 
     LoggerImpl*     loggerptr_;     ///< Pointer to the underlying logger
     std::string     name_;          ///< Copy of the logger name
-    bool            infunc_;        ///< Copy of the infunc argument
 };
 
 } // namespace log
diff --git a/src/lib/log/logger_impl.cc b/src/lib/log/logger_impl.cc
index b30f835..46a3a13 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>
@@ -30,26 +33,33 @@
 
 #include <util/strutil.h>
 
+// Note: as log4cplus and th3e BIND 10 logger have many concepts in common, and
+// thus many similar names, to disambiguate types we don't "use" the log4cplus
+// namespace: instead, all log4cplus types are explicitly qualified.
+
 using namespace std;
 
 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)
+// Constructor.  Although it may be immediately reset, logger_ is initialized to
+// the log4cplus root logger; at least one compiler requires that all member
+// variables be constructed before the constructor is run, but log4cplus::Logger
+// (the type of logger_) has no default constructor.
+LoggerImpl::LoggerImpl(const string& name) :
+    logger_(log4cplus::Logger::getRoot())
 {
+    // Initialize log4cplus if not already done
+    initLog4cplus();
+
     // Are we the root logger?
     if (name == getRootLoggerName()) {
-        is_root_ = true;
         name_ = name;
+        // logger_ already set to log4cplus root logger at this point
+
     } else {
-        is_root_ = false;
         name_ = getRootLoggerName() + "." + name;
+        logger_ = log4cplus::Logger::getInstance(name);
     }
 }
 
@@ -59,162 +69,149 @@ 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);
-    }
+    Level level(severity, dbglevel);
+    logger_.setLogLevel(LoggerLevelImpl::convertFromBindLevel(level));
 }
 
 // Return severity level
-
 isc::log::Severity
 LoggerImpl::getSeverity() {
+    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() {
+    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() {
+    Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+    return level.severity;
+}
 
-    if (!is_root_ && !logger_info_.empty()) {
+// Return effective debug level (only valid if current effective severity level
+// is DEBUG).
+int
+LoggerImpl::getEffectiveDebugLevel() {
+    Level level = LoggerLevelImpl::convertToBindLevel(logger_.getChainedLogLevel());
+    return level.dbglevel;
+}
 
-        // 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);
-        }
-    }
+// 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.
-    return (root_logger_info_.severity);
+void
+LoggerImpl::outputRaw(const Severity& severity, const string& message) {
+    switch (severity) {
+        case DEBUG:
+            LOG4CPLUS_DEBUG(logger_, message);
+            break;
+
+        case INFO:
+            LOG4CPLUS_INFO(logger_, message);
+            break;
+
+        case WARN:
+            LOG4CPLUS_WARN(logger_, message);
+            break;
+
+        case ERROR:
+            LOG4CPLUS_ERROR(logger_, message);
+            break;
+
+        case FATAL:
+            LOG4CPLUS_FATAL(logger_, message);
+    }
 }
 
-// Get the debug level.  This returns 0 unless the severity is DEBUG.
+// Initialization.  This is one initialization for all loggers, so requires
+// a singleton to hold the initialization flag.  The flag is held within a
+// static method to ensure that it is created (and initialized) when needed.
+// This avoids a static initialization fiasco.
 
-int
-LoggerImpl::getDebugLevel() {
+bool&
+LoggerImpl::initialized() {
+    static bool initialized = false;
+    return (initialized);
+}
 
-    if (!is_root_ && !logger_info_.empty()) {
+void
+LoggerImpl::initLog4cplus() {
 
-        // 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 (! initialized()) {
 
-            // Found, so return the debug level.
-            if ((i->second).severity == isc::log::DEBUG) {
-                return ((i->second).dbglevel);
-            } else {
-                return (0);
-            }
-        }
-    }
+        // Set up basic configurator.  This attaches a ConsoleAppender to the
+        // root logger with suitable output.  This is used until we we have
+        // actually read the logging configuration, in which case the output
+        // may well be changed.
+        log4cplus::BasicConfigurator config;
+        config.configure();
+        setRootAppenderLayout();
 
-    // 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);
+        // Add additional debug levels
+        LoggerLevelImpl::init();
+
+        // All done.
+        initialized() = true;
     }
 }
 
-// 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.
-
-bool
-LoggerImpl::isDebugEnabled(int dbglevel) {
+void LoggerImpl::setRootAppenderLayout() {
 
-    if (!is_root_ && !logger_info_.empty()) {
+    // Create the pattern we want for the output - local time.
+    string pattern = "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [";
+    pattern += getRootLoggerName() + string(".%c] %m\n");
 
-        // 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()) {
+    // Retrieve the appenders on the root instance and set the layout to
+    // use that pattern.
+    log4cplus::SharedAppenderPtrList list =
+        log4cplus::Logger::getRoot().getAllAppenders();
 
-            // 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
-            }
-        }
-    }
-
-    // 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);
+    for (log4cplus::SharedAppenderPtrList::iterator i = list.begin();
+         i != list.end(); ++i) {
+        auto_ptr<log4cplus::Layout> layout(
+            new log4cplus::PatternLayout(pattern));
+        (*i)->setLayout(layout);
     }
 }
 
-// Output a general message
-string*
-LoggerImpl::lookupMessage(const MessageID& ident) {
-    return (new string(string(ident) + ", " +
-                       MessageDictionary::globalDictionary().getText(ident)));
-}
-
+// Reset.  Just reset logger hierarchy to default settings (don't remove the
+// loggers - this appears awkward); this is effectively the same as removing
+// them.
 void
-LoggerImpl::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;
+LoggerImpl::reset() {
+    log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
+    initialized() = false;
+
+    // N.B.  The documentation is not clear, but it does not appear that the
+    // methods used to format the new logging levels are removed from the
+    // log4cxx LogLevelManager class - indeed, there appears to be no way
+    // to do this.  This would seem to suggest that a re-initialization may
+    // well add another instance of the toString/fromString to the manager's
+    // list of methods.
+    //
+    // We could get round this by making setting the LogManager a truly
+    // one-shot process.  However, apart from taking up memory there is little
+    // overhead if multiple instances are added.  The manager walks the list and
+    // uses the first method that processes the argument, so multiple methods
+    // doing the same think will not affect functionality.  Besides, this
+    // reset() method is only used in testing and not in the distributed
+    // software.
 }
 
+
 } // namespace log
 } // namespace isc
diff --git a/src/lib/log/logger_impl.h b/src/lib/log/logger_impl.h
index 187e478..f655c55 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,46 +39,43 @@ 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 "program.sublogger".  In other
+/// words, each of the loggers is a sub-logger of the main program logger.
+/// In log4cplus, there is a root logger (called "root" according to the
+/// documentation, but actually unnamed) and all loggers created are subloggers
+/// if it.
+///
+/// In this implementation, the name of the logger is checked.  If it is the
+/// name of the program (as set in the call to isc::log::setRootLoggerName),
+/// the log4cplus root logger is used.  Otherwise the name passed is used as
+/// the name of a logger when a log4cplus logger is created.
+///
+/// To clarify: if the program is "b10auth" (and that is used to set the BIND 10
+/// root logger name via a call to isc::log::setRootLoggerName()), the BIND 10
+/// logger "b10auth" corresponds to the log4cplus root logger instance (returned
+/// by a call to log4cplus::Logger::getRoot()).  The BIND 10 sub-logger "cache"
+/// corresponds to the log4cplus logger "cache", created by a call to
+/// log4cplus::Logger::getInstance("cache").  The distinction is, however,
+/// invisible to users as the logger reported in messages is always
+/// "programm.sublogger".
+///
+/// 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.
     ///
     /// \param name Name of the logger.
-    ///
-    /// \param exit_delete This argument is present to get round a bug in
-    /// the log4cxx implementation.  It is unused here.
-    LoggerImpl(const std::string& name, bool);
+    LoggerImpl(const std::string& name);
 
 
     /// \brief Destructor
@@ -94,16 +95,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 +112,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
     ///
@@ -188,28 +184,33 @@ public:
         return (name_ == other.name_);
     }
 
-
-    /// \brief Reset Global Data
+    /// \brief Reset logging
     ///
-    /// 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();
-    }
+    /// Resets (clears) the log4cplus logging, requiring that an initialization
+    /// call be performed again.
+    static void reset();
 
 
 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 initialization of the log4cplus system.
+    static void initLog4cplus();
+
+    /// \brief Initialization Flag
+    ///
+    /// Static method to access an initialization flag.  Doing it this
+    /// way means that there is no static initialization fiasco.
+    static bool& initialized();
+
+    /// \brief Set layout pattern
+    ///
+    /// Sets the layout for root logger appender(s)
+    static void setRootAppenderLayout();
 
-    static LoggerInfo       root_logger_info_;  ///< Status of root logger
-    static LoggerInfoMap    logger_info_;       ///< Store of debug levels etc.
+    std::string         name_;              ///< Full name of this logger
+    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..673fd87
--- /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.
+
+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..7c98977
--- /dev/null
+++ b/src/lib/log/logger_level_impl.cc
@@ -0,0 +1,194 @@
+// 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 <iostream>
+#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.
+        // If outside the limits, change the severity to the level above or below.
+        int dbglevel = MIN_DEBUG_LEVEL +
+                       static_cast<int>(log4cplus::DEBUG_LOG_LEVEL) -
+                       static_cast<int>(loglevel);
+        if (dbglevel > MAX_DEBUG_LEVEL) {
+            return (Level(DEFAULT));
+        } else if (dbglevel < MIN_DEBUG_LEVEL) {
+            return (Level(INFO));
+        }
+        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/logger_support.cc b/src/lib/log/logger_support.cc
index e17c47d..701cfef 100644
--- a/src/lib/log/logger_support.cc
+++ b/src/lib/log/logger_support.cc
@@ -107,7 +107,7 @@ initLogger(const string& root, isc::log::Severity severity, int dbglevel,
     // debug level.  This is the logger that has the name of the application.
     // All other loggers created in this application will be its children.
     setRootLoggerName(root);
-    Logger root_logger(isc::log::getRootLoggerName(), true);
+    Logger root_logger(isc::log::getRootLoggerName());
 
     // Set the severity associated with it.  If no other logger has a severity,
     // this will be the default.
@@ -149,7 +149,7 @@ void initLogger() {
     // B10_LOGGER_SEVERITY, and can be one of "DEBUG", "INFO", "WARN", "ERROR"
     // of "FATAL".  Note that the string must be in upper case with no leading
     // of trailing blanks.
-    isc::log::Severity severity = isc::log::DEFAULT;
+    isc::log::Severity severity = isc::log::DEBUG;
     const char* sev_char = getenv("B10_LOGGER_SEVERITY");
     if (sev_char) {
         string sev_string(sev_char);
diff --git a/src/lib/log/tests/Makefile.am b/src/lib/log/tests/Makefile.am
index ac4b82a..9a02795 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
@@ -17,6 +15,8 @@ if HAVE_GTEST
 TESTS += run_unittests
 run_unittests_SOURCES  = root_logger_name_unittest.cc
 run_unittests_SOURCES += logger_unittest.cc
+run_unittests_SOURCES += logger_level_unittest.cc
+run_unittests_SOURCES += logger_level_impl_unittest.cc
 run_unittests_SOURCES += message_dictionary_unittest.cc
 run_unittests_SOURCES += message_reader_unittest.cc
 run_unittests_SOURCES += message_initializer_unittest.cc
@@ -24,8 +24,8 @@ run_unittests_SOURCES += message_initializer_unittest_2.cc
 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_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
+run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
 
 run_unittests_LDADD  = $(GTEST_LDADD)
 run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
@@ -33,11 +33,10 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.
 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_LDADD  = $(top_builddir)/src/lib/log/liblog.la
-logger_support_test_LDADD += $(top_builddir)/src/lib/util/libutil.la
+logger_support_test_SOURCES  = logger_support_test.cc
+logger_support_test_CPPFLAGS = $(AM_CPPFLAGS)
+logger_support_test_LDFLAGS  = $(AM_LDFLAGS)
+logger_support_test_LDADD    = $(top_builddir)/src/lib/log/liblog.la
 
 noinst_PROGRAMS = $(TESTS)
 
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_level_impl_unittest.cc b/src/lib/log/tests/logger_level_impl_unittest.cc
new file mode 100644
index 0000000..0ded7f9
--- /dev/null
+++ b/src/lib/log/tests/logger_level_impl_unittest.cc
@@ -0,0 +1,171 @@
+// 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 <iostream>
+#include <string>
+
+#include <gtest/gtest.h>
+#include <boost/static_assert.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <log/logger_level_impl.h>
+#include <log4cplus/logger.h>
+
+using namespace isc::log;
+using namespace std;
+
+class LoggerLevelImplTest : public ::testing::Test {
+protected:
+    LoggerLevelImplTest()
+    {}
+
+    ~LoggerLevelImplTest()
+    {}
+};
+
+
+// Checks that the log4cplus and BIND 10 levels convert correctly
+TEST_F(LoggerLevelImplTest, DefaultConversionFromBind) {
+    log4cplus::LogLevel fatal =
+        LoggerLevelImpl::convertFromBindLevel(Level(FATAL));
+    EXPECT_EQ(log4cplus::FATAL_LOG_LEVEL, fatal);
+
+    log4cplus::LogLevel error =
+        LoggerLevelImpl::convertFromBindLevel(Level(ERROR));
+    EXPECT_EQ(log4cplus::ERROR_LOG_LEVEL, error);
+
+    log4cplus::LogLevel warn =
+        LoggerLevelImpl::convertFromBindLevel(Level(WARN));
+    EXPECT_EQ(log4cplus::WARN_LOG_LEVEL, warn);
+
+    log4cplus::LogLevel info =
+        LoggerLevelImpl::convertFromBindLevel(Level(INFO));
+    EXPECT_EQ(log4cplus::INFO_LOG_LEVEL, info);
+
+    log4cplus::LogLevel debug =
+        LoggerLevelImpl::convertFromBindLevel(Level(DEBUG));
+    EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL, debug);
+}
+
+// Checks that the debug severity and level converts correctly
+TEST_F(LoggerLevelImplTest, DebugConversionFromBind) {
+    log4cplus::LogLevel debug0 =
+        LoggerLevelImpl::convertFromBindLevel(Level(DEBUG, 0));
+    EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL - 0, debug0);
+
+    log4cplus::LogLevel debug1 =
+        LoggerLevelImpl::convertFromBindLevel(Level(DEBUG, 1));
+    EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL - 1, debug1);
+
+    log4cplus::LogLevel debug99 =
+        LoggerLevelImpl::convertFromBindLevel(Level(DEBUG, 99));
+    EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL - 99, debug99);
+
+    // Out of range should be coerced to the nearest boundary
+    log4cplus::LogLevel debug_1 =
+        LoggerLevelImpl::convertFromBindLevel(Level(DEBUG, MIN_DEBUG_LEVEL - 1));
+    EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL, debug_1);
+
+    log4cplus::LogLevel debug100 =
+        LoggerLevelImpl::convertFromBindLevel(Level(DEBUG, MAX_DEBUG_LEVEL + 1));
+    EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL - MAX_DEBUG_LEVEL, debug100);
+}
+
+// Do the checks the other way
+static void
+test_convert_to(const char* trace, isc::log::Severity severity, int dbglevel,
+                log4cplus::LogLevel level)
+{
+    SCOPED_TRACE(trace);
+    Level test = LoggerLevelImpl::convertToBindLevel(level);
+    EXPECT_EQ(severity, test.severity);
+    EXPECT_EQ(dbglevel, test.dbglevel);
+}
+
+TEST_F(LoggerLevelImplTest, ConversionToBind) {
+    test_convert_to("FATAL", FATAL, MIN_DEBUG_LEVEL, log4cplus::FATAL_LOG_LEVEL);
+    test_convert_to("ERROR", ERROR, MIN_DEBUG_LEVEL, log4cplus::ERROR_LOG_LEVEL);
+    test_convert_to("WARN",  WARN , MIN_DEBUG_LEVEL, log4cplus::WARN_LOG_LEVEL);
+    test_convert_to("INFO",  INFO , MIN_DEBUG_LEVEL, log4cplus::INFO_LOG_LEVEL);
+    test_convert_to("DEBUG",  DEBUG, MIN_DEBUG_LEVEL, log4cplus::DEBUG_LOG_LEVEL);
+
+    test_convert_to("DEBUG0",  DEBUG, MIN_DEBUG_LEVEL + 0,
+            (log4cplus::DEBUG_LOG_LEVEL));
+    test_convert_to("DEBUG1",  DEBUG, MIN_DEBUG_LEVEL + 1,
+            (log4cplus::DEBUG_LOG_LEVEL - 1));
+    test_convert_to("DEBUG2",  DEBUG, MIN_DEBUG_LEVEL + 2,
+            (log4cplus::DEBUG_LOG_LEVEL - 2));
+    test_convert_to("DEBUG99",  DEBUG, MIN_DEBUG_LEVEL + 99,
+            (log4cplus::DEBUG_LOG_LEVEL - 99));
+
+    // ... and some invalid valid values
+    test_convert_to("DEBUG-1",  INFO, MIN_DEBUG_LEVEL,
+            (log4cplus::DEBUG_LOG_LEVEL + 1));
+    BOOST_STATIC_ASSERT(MAX_DEBUG_LEVEL == 99);
+    test_convert_to("DEBUG+100",  DEFAULT, 0,
+            (log4cplus::DEBUG_LOG_LEVEL - MAX_DEBUG_LEVEL - 1));
+}
+
+// Check that we can convert from a string to the new log4cplus levels
+TEST_F(LoggerLevelImplTest, FromString) {
+
+    // Test all valid values
+    for (int i = MIN_DEBUG_LEVEL; i <= MAX_DEBUG_LEVEL; ++i) {
+        std::string token = string("DEBUG") + boost::lexical_cast<std::string>(i);
+        EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL - i,
+                  LoggerLevelImpl::logLevelFromString(token));
+    }
+
+    // ... in lowercase too
+    for (int i = MIN_DEBUG_LEVEL; i <= MAX_DEBUG_LEVEL; ++i) {
+        std::string token = string("debug") + boost::lexical_cast<std::string>(i);
+        EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL - i,
+                  LoggerLevelImpl::logLevelFromString(token));
+    }
+
+    // A few below the minimum
+    for (int i = MIN_DEBUG_LEVEL - 5; i < MIN_DEBUG_LEVEL; ++i) {
+        std::string token = string("DEBUG") + boost::lexical_cast<std::string>(i);
+        EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL, LoggerLevelImpl::logLevelFromString(token));
+    }
+
+    // ... and above the maximum
+    for (int i = MAX_DEBUG_LEVEL + 1; i < MAX_DEBUG_LEVEL + 5; ++i) {
+        std::string token = string("DEBUG") + boost::lexical_cast<std::string>(i);
+        EXPECT_EQ(log4cplus::DEBUG_LOG_LEVEL - MAX_DEBUG_LEVEL,
+                  LoggerLevelImpl::logLevelFromString(token));
+    }
+
+    // Invalid strings.
+    EXPECT_EQ(log4cplus::NOT_SET_LOG_LEVEL,
+              LoggerLevelImpl::logLevelFromString("DEBU"));
+    EXPECT_EQ(log4cplus::NOT_SET_LOG_LEVEL,
+              LoggerLevelImpl::logLevelFromString("unrecognised"));
+}
+
+// ... and check the conversion back again.  All levels should convert to "DEBUG".
+TEST_F(LoggerLevelImplTest, ToString) {
+
+    for (int i = MIN_DEBUG_LEVEL; i <= MAX_DEBUG_LEVEL; ++i) {
+        EXPECT_EQ(std::string("DEBUG"),
+                  LoggerLevelImpl::logLevelToString(log4cplus::DEBUG_LOG_LEVEL - i));
+    }
+
+    // ... and that out of range stuff returns an empty string.
+    EXPECT_EQ(std::string(),
+              LoggerLevelImpl::logLevelToString(log4cplus::DEBUG_LOG_LEVEL + 1));
+    EXPECT_EQ(std::string(),
+              LoggerLevelImpl::logLevelToString(
+                               log4cplus::DEBUG_LOG_LEVEL - MAX_DEBUG_LEVEL - 100));
+}
diff --git a/src/lib/log/tests/logger_level_unittest.cc b/src/lib/log/tests/logger_level_unittest.cc
new file mode 100644
index 0000000..aa8809f
--- /dev/null
+++ b/src/lib/log/tests/logger_level_unittest.cc
@@ -0,0 +1,56 @@
+// 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 <iostream>
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include <log/root_logger_name.h>
+#include <log/logger.h>
+#include <log/messagedef.h>
+
+using namespace isc;
+using namespace isc::log;
+using namespace std;
+
+class LoggerLevelTest : public ::testing::Test {
+protected:
+    LoggerLevelTest()
+    {}
+
+    ~LoggerLevelTest()
+    {}
+};
+
+
+// Checks that the logger is named correctly.
+
+TEST_F(LoggerLevelTest, Creation) {
+
+    // Default
+    isc::log::Level level1;
+    EXPECT_EQ(isc::log::DEFAULT, level1.severity);
+    EXPECT_EQ(isc::log::MIN_DEBUG_LEVEL, level1.dbglevel);
+
+    // Single argument constructor.
+    isc::log::Level level2(isc::log::FATAL);
+    EXPECT_EQ(isc::log::FATAL, level2.severity);
+    EXPECT_EQ(isc::log::MIN_DEBUG_LEVEL, level2.dbglevel);
+
+    // Two-argument constructor
+    isc::log::Level level3(isc::log::DEBUG, 42);
+    EXPECT_EQ(isc::log::DEBUG, level3.severity);
+    EXPECT_EQ(42, level3.dbglevel);
+}
diff --git a/src/lib/log/tests/logger_support_test.cc b/src/lib/log/tests/logger_support_test.cc
index 0a2338b..ab3b00e 100644
--- a/src/lib/log/tests/logger_support_test.cc
+++ b/src/lib/log/tests/logger_support_test.cc
@@ -52,7 +52,7 @@ int main(int argc, char** argv) {
     int                 dbglevel = -1;              // Logger debug level
     const char*         localfile = NULL;           // Local message file
     int                 option;                     // For getopt() processing
-    Logger              logger_dlm("dlm", true);    // Another example logger
+    Logger              logger_dlm("dlm");          // Another example logger
 
     // Parse options
     while ((option = getopt(argc, argv, "s:d:")) != -1) {
diff --git a/src/lib/log/tests/logger_unittest.cc b/src/lib/log/tests/logger_unittest.cc
index 4eff622..6a680ef 100644
--- a/src/lib/log/tests/logger_unittest.cc
+++ b/src/lib/log/tests/logger_unittest.cc
@@ -25,37 +25,34 @@ using namespace isc;
 using namespace isc::log;
 using namespace std;
 
-namespace isc {
-namespace log {
-
-/// \brief Test Logger
+/// \brief Derived logger
 ///
-/// This logger is a subclass of the logger class under test, but makes
-/// protected methods public (for testing)
+/// Only exists to make the protected static methods in Logger public for
+/// test purposes.
 
-class TestLogger : public Logger {
+class DerivedLogger : public isc::log::Logger {
 public:
-    /// \brief constructor
-    TestLogger(const string& name) : Logger(name, true)
+    DerivedLogger(std::string name) : isc::log::Logger(name)
     {}
 
     static void reset() {
-        Logger::reset();
+        isc::log::Logger::reset();
     }
 };
 
-} // namespace log
-} // namespace isc
 
+/// \brief Logger Test
+///
+/// As the logger is only a shell around the implementation, this tests also
+/// checks the logger implementation class as well.
 
 class LoggerTest : public ::testing::Test {
-protected:
+public:
     LoggerTest()
+    {}
+    ~LoggerTest()
     {
-    }
-
-    ~LoggerTest() {
-        TestLogger::reset();
+        DerivedLogger::reset();
     }
 };
 
@@ -85,14 +82,14 @@ TEST_F(LoggerTest, GetLogger) {
     const string name2 = "beta";
 
     // Instantiate two loggers that should be the same
-    TestLogger logger1(name1);
-    TestLogger logger2(name1);
+    Logger logger1(name1);
+    Logger logger2(name1);
     // And check they equal
     EXPECT_TRUE(logger1 == logger2);
 
     // Instantiate another logger with another name and check that it
     // is different to the previously instantiated ones.
-    TestLogger logger3(name2);
+    Logger logger3(name2);
     EXPECT_FALSE(logger1 == logger3);
 }
 
@@ -102,7 +99,7 @@ TEST_F(LoggerTest, Severity) {
 
     // Create a logger
     setRootLoggerName("test3");
-    TestLogger logger("alpha");
+    Logger logger("alpha");
 
     // Now check the levels
     logger.setSeverity(isc::log::NONE);
@@ -133,7 +130,7 @@ TEST_F(LoggerTest, DebugLevels) {
 
     // Create a logger
     setRootLoggerName("test4");
-    TestLogger logger("alpha");
+    Logger logger("alpha");
 
     // Debug level should be 0 if not at debug severity
     logger.setSeverity(isc::log::NONE, 20);
@@ -179,8 +176,8 @@ TEST_F(LoggerTest, SeverityInheritance) {
     // relationship if the loggers are named <parent> and <parent>.<child>.
 
     setRootLoggerName("test5");
-    TestLogger parent("alpha");
-    TestLogger child("alpha.beta");
+    Logger parent("alpha");
+    Logger child("alpha.beta");
 
     // By default, newly created loggers should have a level of DEFAULT
     // (i.e. default to parent)
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
diff --git a/src/lib/nsas/tests/Makefile.am b/src/lib/nsas/tests/Makefile.am
index 38c6d93..420e897 100644
--- a/src/lib/nsas/tests/Makefile.am
+++ b/src/lib/nsas/tests/Makefile.am
@@ -43,8 +43,8 @@ run_unittests_SOURCES += zone_entry_unittest.cc
 run_unittests_SOURCES += fetchable_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+run_unittests_LDADD    = $(GTEST_LDADD)
 
 # NOTE: we may have to clean up this hack later (see the note in configure.ac)
 if NEED_LIBBOOST_THREAD
diff --git a/src/lib/resolve/tests/Makefile.am b/src/lib/resolve/tests/Makefile.am
index 3cb0e3e..ee311a6 100644
--- a/src/lib/resolve/tests/Makefile.am
+++ b/src/lib/resolve/tests/Makefile.am
@@ -11,9 +11,11 @@ CLEANFILES = *.gcno *.gcda
 TESTS =
 if HAVE_GTEST
 TESTS += run_unittests
+
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-run_unittests_SOURCES = run_unittests.cc
+run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+
+run_unittests_SOURCES  = run_unittests.cc
 run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.h
 run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
 run_unittests_SOURCES += resolve_unittest.cc
diff --git a/tests/tools/badpacket/Makefile.am b/tests/tools/badpacket/Makefile.am
index 7df7077..fcba404 100644
--- a/tests/tools/badpacket/Makefile.am
+++ b/tests/tools/badpacket/Makefile.am
@@ -29,5 +29,5 @@ badpacket_LDADD  = $(top_builddir)/src/lib/asiodns/libasiodns.la
 badpacket_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
 badpacket_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
 badpacket_LDADD += $(top_builddir)/src/lib/log/liblog.la
+badpacket_LDADD += $(top_builddir)/src/lib/util/libutil.la
 badpacket_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-
diff --git a/tests/tools/badpacket/tests/Makefile.am b/tests/tools/badpacket/tests/Makefile.am
index 6d0d4e1..2daa664 100644
--- a/tests/tools/badpacket/tests/Makefile.am
+++ b/tests/tools/badpacket/tests/Makefile.am
@@ -21,11 +21,11 @@ run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/command_options.c
 run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/option_info.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
 
 run_unittests_LDADD  = $(GTEST_LDADD)
-run_unittests_LDFLAGS += $(top_builddir)/src/lib/exceptions/libexceptions.la
-run_unittests_LDFLAGS += $(top_builddir)/src/lib/util/libutil.la
+run_unittests_LDADD += $(top_builddir)/src/lib/util/libutil.la
+run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 endif
 




More information about the bind10-changes mailing list