Browse Source

[3427] Changes after review:
- Kea ARM updated
- shell tests for Kea4,Kea6 and D2 are now passing
- kea.conf updated with logging info
- Various improvements in Daemon and LogConfigParser
- DEFAULT_SYSLOG_NAME removed
- Copyright years fixed
- Couple additional tests written

Tomek Mrugalski 11 years ago
parent
commit
d26a494520

+ 26 - 8
doc/guide/logging.xml

@@ -55,13 +55,14 @@
           <title>name (string)</title>
           <title>name (string)</title>
 
 
           <para>
           <para>
-          Each logger in the system has a name, the name being that
-          of the component using it to log messages. For instance,
-          if you want to configure logging for the Dhcp4 module,
-          you add an entry for a logger named <quote>Dhcp4</quote>. This
-          configuration will then be used by the loggers in the
-          Dhcp4 module, and all the libraries used by it.
-              </para>
+            Each logger in the system has a name, the name being that
+            of the component using it to log messages. For instance,
+            if you want to configure logging for the Dhcp4 module,
+            you add an entry for a logger named <quote>Dhcp4</quote>. This
+            configuration will then be used by the loggers in the
+            Dhcp4 module, and all the libraries used by it (unless
+            a library defines its own logger).
+          </para>
 
 
 <!-- TODO: later we will have a way to know names of all modules
 <!-- TODO: later we will have a way to know names of all modules
 
 
@@ -78,7 +79,6 @@ Right now you can only see what their names are if they are running
           has the full name of <quote>Dhcp4.dhcpsrv</quote>. If
           has the full name of <quote>Dhcp4.dhcpsrv</quote>. If
           there is no entry in Logging for a particular library,
           there is no entry in Logging for a particular library,
           it will use the configuration given for the module.
           it will use the configuration given for the module.
-
         </para>
         </para>
 
 
        <para>
        <para>
@@ -138,6 +138,24 @@ Right now you can only see what their names are if they are running
 
 
         </para>
         </para>
 
 
+        <para>
+          Currently defined loggers are:
+        </para>
+        <itemizedlist>
+          <listitem>
+            <simpara>kea.dhcp4</simpara>
+          </listitem>
+          <listitem>
+            <simpara>kea.dhcp6</simpara>
+          </listitem>
+          <listitem>
+            <simpara>kea-dhcp-ddns.dhcpddns</simpara>
+          </listitem>
+          <listitem>
+            <simpara>kea.dhcpsrv</simpara>
+          </listitem>
+        </itemizedlist>
+
         </section>
         </section>
 
 
         <section>
         <section>

+ 3 - 15
src/bin/d2/d_controller.cc

@@ -224,21 +224,9 @@ DControllerBase::configFromFile() {
         // Temporary storage for logging configuration
         // Temporary storage for logging configuration
         isc::dhcp::ConfigurationPtr storage(new isc::dhcp::Configuration());
         isc::dhcp::ConfigurationPtr storage(new isc::dhcp::Configuration());
 
 
-        // Get 'Logging' element from the config
-        isc::data::ConstElementPtr logger = whole_config->get("Logging");
-        if (logger) {
-            // Configure logger first, so it can be applied to DHCPv6
-            // configuration. If we don't have a logger, just pass
-            // empty configuration.
-
-            Daemon::configureLogger(logger, storage);
-        } else {
-            // There was no Logging element defined in the config file.
-            // Let's pass an empty pointer that will remove any current
-            // configuration.
-            Daemon::configureLogger(isc::data::ConstElementPtr(),
-                                    storage);
-        }
+        // Get 'Logging' element from the config and use it to set up
+        // logging. If there's no such element, we'll just pass NULL.
+        Daemon::configureLogger(whole_config->get("Logging"), storage, verbose_);
 
 
         // Extract derivation-specific portion of the configuration.
         // Extract derivation-specific portion of the configuration.
         module_config = whole_config->get(getAppName());
         module_config = whole_config->get(getAppName());

+ 28 - 0
src/bin/d2/tests/d2_process_tests.sh.in

@@ -25,6 +25,20 @@ CONFIG="{
         \"tsig_keys\": [],
         \"tsig_keys\": [],
         \"forward_ddns\" : {},
         \"forward_ddns\" : {},
         \"reverse_ddns\" : {}
         \"reverse_ddns\" : {}
+    },
+    \"Logging\":
+    {
+        \"loggers\": [
+        {
+            \"name\": \"kea-dhcp-ddns\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"DEBUG\"
+        }
+        ]
     }
     }
 }"
 }"
 
 
@@ -38,6 +52,20 @@ CONFIG_INVALID="{
         \"tsig_keys\": [],
         \"tsig_keys\": [],
         \"forward_ddns\" : {},
         \"forward_ddns\" : {},
         \"reverse_ddns\" : {}
         \"reverse_ddns\" : {}
+    },
+    \"Logging\":
+    {
+        \"loggers\": [
+        {
+            \"name\": \"kea-dhcp-ddns\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"INFO\"
+        }
+        ]
     }
     }
 }"
 }"
 
 

+ 6 - 14
src/bin/dhcp4/kea_controller.cc

@@ -66,20 +66,12 @@ void configure(const std::string& file_name) {
 
 
         // Let's configure logging before applying the configuration,
         // Let's configure logging before applying the configuration,
         // so we can log things during configuration process.
         // so we can log things during configuration process.
-        logger = json->get("Logging");
-        if (logger) {
-            // Configure logger first, so it can be applied to DHCPv6
-            // configuration. If we don't have a logger, just pass
-            // empty configuration.
-
-            Daemon::configureLogger(logger, CfgMgr::instance().getConfiguration());
-        } else {
-            // There was no Logging element defined in the config file.
-            // Let's pass an empty pointer that will remove any current
-            // configuration.
-            Daemon::configureLogger(isc::data::ConstElementPtr(),
-                                    CfgMgr::instance().getConfiguration());
-        }
+
+        // If there's no logging element, we'll just pass NULL pointer,
+        // which will be handled by configureLogger().
+        Daemon::configureLogger(json->get("Logging"),
+                                CfgMgr::instance().getConfiguration(),
+                                ControlledDhcpv4Srv::getInstance()->getVerbose());
 
 
         // Get Dhcp4 component from the config
         // Get Dhcp4 component from the config
         dhcp4 = json->get("Dhcp4");
         dhcp4 = json->get("Dhcp4");

+ 3 - 0
src/bin/dhcp4/main.cc

@@ -111,6 +111,9 @@ main(int argc, char* argv[]) {
         // Create the server instance.
         // Create the server instance.
         ControlledDhcpv4Srv server(port_number);
         ControlledDhcpv4Srv server(port_number);
 
 
+        // Remember verbose-mode
+        server.setVerbose(verbose_mode);
+
         try {
         try {
             // Initialize the server.
             // Initialize the server.
             server.init(config_file);
             server.init(config_file);

+ 30 - 0
src/bin/dhcp4/tests/dhcp4_process_tests.sh.in

@@ -34,6 +34,21 @@ CONFIG="{
             \"subnet\": \"10.0.0.0/8\",
             \"subnet\": \"10.0.0.0/8\",
             \"pool\": [ \"10.0.0.10-10.0.0.100\" ]
             \"pool\": [ \"10.0.0.10-10.0.0.100\" ]
         } ]
         } ]
+    },
+
+    \"Logging\":
+    {
+        \"loggers\": [
+        {
+            \"name\": \"kea\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"INFO\"
+        }
+        ]
     }
     }
 }"
 }"
 # Invalid configuration (negative valid-lifetime) to check that Kea
 # Invalid configuration (negative valid-lifetime) to check that Kea
@@ -55,6 +70,21 @@ CONFIG_INVALID="{
             \"subnet\": \"10.0.0.0/8\",
             \"subnet\": \"10.0.0.0/8\",
             \"pool\": [ \"10.0.0.10-10.0.0.100\" ]
             \"pool\": [ \"10.0.0.10-10.0.0.100\" ]
         } ]
         } ]
+    },
+
+    \"Logging\":
+    {
+        \"loggers\": [
+        {
+            \"name\": \"kea\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"INFO\"
+        }
+        ]
     }
     }
 }"
 }"
 
 

+ 5 - 13
src/bin/dhcp6/kea_controller.cc

@@ -70,19 +70,11 @@ void configure(const std::string& file_name) {
 
 
         // Let's configure logging before applying the configuration,
         // Let's configure logging before applying the configuration,
         // so we can log things during configuration process.
         // so we can log things during configuration process.
-        logger = json->get("Logging");
-        if (logger) {
-            // Configure logger first, so it can be applied to DHCPv6
-            // configuration. If we don't have a logger, just pass
-            // empty configuration.
-            Daemon::configureLogger(logger, CfgMgr::instance().getConfiguration());
-        } else {
-            // There was no Logging element defined in the config file.
-            // Let's pass an empty pointer that will remove any current
-            // configuration.
-            Daemon::configureLogger(isc::data::ConstElementPtr(),
-                                    CfgMgr::instance().getConfiguration());
-        }
+        // If there's no logging element, we'll just pass NULL pointer,
+        // which will be handled by configureLogger().
+        Daemon::configureLogger(json->get("Logging"),
+                                CfgMgr::instance().getConfiguration(),
+                                ControlledDhcpv6Srv::getInstance()->getVerbose());
 
 
         // Get Dhcp6 component from the config
         // Get Dhcp6 component from the config
         dhcp6 = json->get("Dhcp6");
         dhcp6 = json->get("Dhcp6");

+ 3 - 0
src/bin/dhcp6/main.cc

@@ -111,6 +111,9 @@ main(int argc, char* argv[]) {
         // Create the server instance.
         // Create the server instance.
         ControlledDhcpv6Srv server(port_number);
         ControlledDhcpv6Srv server(port_number);
 
 
+        // Remember verbose-mode
+        server.setVerbose(verbose_mode);
+
         try {
         try {
             // Initialize the server, i.e. establish control session
             // Initialize the server, i.e. establish control session
             // if BIND10 backend is used or read a configuration file
             // if BIND10 backend is used or read a configuration file

+ 30 - 0
src/bin/dhcp6/tests/dhcp6_process_tests.sh.in

@@ -35,6 +35,21 @@ CONFIG="{
             \"subnet\": \"2001:db8:1::/64\",
             \"subnet\": \"2001:db8:1::/64\",
             \"pool\": [ \"2001:db8:1::10-2001:db8:1::100\" ]
             \"pool\": [ \"2001:db8:1::10-2001:db8:1::100\" ]
         } ]
         } ]
+    },
+
+    \"Logging\":
+    {
+        \"loggers\": [
+        {
+            \"name\": \"kea\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"INFO\"
+        }
+        ]
     }
     }
 }"
 }"
 # Invalid configuration (negative preferred-lifetime) to check that Kea
 # Invalid configuration (negative preferred-lifetime) to check that Kea
@@ -57,6 +72,21 @@ CONFIG_INVALID="{
             \"subnet\": \"2001:db8:1::/64\",
             \"subnet\": \"2001:db8:1::/64\",
             \"pool\": [ \"2001:db8:1::10-2001:db8:1::100\" ]
             \"pool\": [ \"2001:db8:1::10-2001:db8:1::100\" ]
         } ]
         } ]
+    },
+
+    \"Logging\":
+    {
+        \"loggers\": [
+        {
+            \"name\": \"kea\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"INFO\"
+        }
+        ]
     }
     }
 }"
 }"
 
 

+ 19 - 0
src/bin/keactrl/kea.conf.in

@@ -65,6 +65,25 @@
   "tsig_keys": [],
   "tsig_keys": [],
   "forward_ddns" : {},
   "forward_ddns" : {},
   "reverse_ddns" : {}
   "reverse_ddns" : {}
+},
+
+# Logging configuration starts here. It tells Kea servers to store
+# all log messages (on severity INFO or more) in a file.
+# debuglevel variable is used on DEBUG level only.
+"Logging":
+{
+  "loggers": [
+    {
+      "name": "kea",
+      "output_options": [
+          {
+            "output": "@localstatedir@/log/kea.log"
+          }
+      ],
+      "severity": "INFO",
+      "debuglevel": 0
+    }
+  ]
 }
 }
 
 
 }
 }

+ 3 - 4
src/lib/dhcpsrv/configuration.h

@@ -12,8 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 // PERFORMANCE OF THIS SOFTWARE.
 
 
-#ifndef DHCPSRV_CONFIG_H
-#define DHCPSRV_CONFIG_H
+#ifndef DHCPSRV_CONFIGURATION_H
+#define DHCPSRV_CONFIGURATION_H
 
 
 #include <log/logger_level.h>
 #include <log/logger_level.h>
 #include <boost/shared_ptr.hpp>
 #include <boost/shared_ptr.hpp>
@@ -23,7 +23,6 @@
 namespace isc {
 namespace isc {
 namespace dhcp {
 namespace dhcp {
 
 
-
 /// @brief Defines single logging destination
 /// @brief Defines single logging destination
 ///
 ///
 /// This structure is used to keep log4cplus configuration parameters.
 /// This structure is used to keep log4cplus configuration parameters.
@@ -93,4 +92,4 @@ typedef boost::shared_ptr<Configuration> ConfigurationPtr;
 } // namespace isc::dhcp
 } // namespace isc::dhcp
 } // namespace isc
 } // namespace isc
 
 
-#endif
+#endif // DHCPSRV_CONFIGURATION_H

+ 7 - 6
src/lib/dhcpsrv/daemon.cc

@@ -31,7 +31,7 @@ namespace dhcp {
 std::string Daemon::config_file_ = "";
 std::string Daemon::config_file_ = "";
 
 
 Daemon::Daemon()
 Daemon::Daemon()
-    : signal_set_(), signal_handler_() {
+    : signal_set_(), signal_handler_(), verbose_(false) {
 }
 }
 
 
 Daemon::~Daemon() {
 Daemon::~Daemon() {
@@ -55,8 +55,9 @@ void Daemon::handleSignal() {
     }
     }
 }
 }
 
 
-void Daemon::configureLogger(isc::data::ConstElementPtr log_config,
-                             const ConfigurationPtr& storage) {
+void Daemon::configureLogger(const isc::data::ConstElementPtr& log_config,
+                             const ConfigurationPtr& storage,
+                             bool verbose) {
 
 
     // This is utility class that translates JSON structures into formats
     // This is utility class that translates JSON structures into formats
     // understandable by log4cplus.
     // understandable by log4cplus.
@@ -66,7 +67,7 @@ void Daemon::configureLogger(isc::data::ConstElementPtr log_config,
         // There was no logger configuration. Let's clear any config
         // There was no logger configuration. Let's clear any config
         // and revert to the default.
         // and revert to the default.
 
 
-        parser.defaultLogging(); // Set up default logging
+        parser.applyDefaultConfiguration(verbose); // Set up default logging
         return;
         return;
     }
     }
 
 
@@ -77,12 +78,12 @@ void Daemon::configureLogger(isc::data::ConstElementPtr log_config,
         // array in it. Let's clear any old logging configuration
         // array in it. Let's clear any old logging configuration
         // we may have and revert to the default.
         // we may have and revert to the default.
 
 
-        parser.defaultLogging(); // Set up default logging
+        parser.applyDefaultConfiguration(verbose); // Set up default logging
         return;
         return;
     }
     }
 
 
     // Translate JSON structures into log4cplus formats
     // Translate JSON structures into log4cplus formats
-    parser.parseConfiguration(loggers);
+    parser.parseConfiguration(loggers, verbose);
 
 
     // Apply the configuration
     // Apply the configuration
 
 

+ 23 - 2
src/lib/dhcpsrv/daemon.h

@@ -128,8 +128,26 @@ public:
     ///
     ///
     /// @param log_config JSON structures that describe logging
     /// @param log_config JSON structures that describe logging
     /// @param storage configuration will be stored here
     /// @param storage configuration will be stored here
-    static void configureLogger(isc::data::ConstElementPtr log_config,
-                                const isc::dhcp::ConfigurationPtr& storage);
+    /// @param verbose specifies if verbose mode should be enabled
+    static void configureLogger(const isc::data::ConstElementPtr& log_config,
+                                const isc::dhcp::ConfigurationPtr& storage,
+                                bool verbose);
+
+    /// @brief Sets or clears verbose mode
+    ///
+    /// Verbose mode (-v in command-line) triggers loggers to log everythin
+    /// (sets severity to DEBUG and debuglevel to 99). Values specified in the
+    /// config file are ignored.
+    void setVerbose(bool verbose) {
+        verbose_ = verbose;
+    }
+
+    /// @brief Returns if running in verbose mode
+    ///
+    /// @return verbose mode
+    bool getVerbose() {
+        return (verbose_);
+    }
 
 
 protected:
 protected:
 
 
@@ -163,6 +181,9 @@ private:
 
 
     /// @brief Config file name or empty if config file not used.
     /// @brief Config file name or empty if config file not used.
     static std::string config_file_;
     static std::string config_file_;
+
+    /// @brief Verbose mode
+    bool verbose_;
 };
 };
 
 
 }; // end of isc::dhcp namespace
 }; // end of isc::dhcp namespace

+ 25 - 16
src/lib/dhcpsrv/logging.cc

@@ -18,6 +18,7 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/lexical_cast.hpp>
 #include <log/logger_specification.h>
 #include <log/logger_specification.h>
 #include <log/logger_manager.h>
 #include <log/logger_manager.h>
+#include <log/logger_name.h>
 
 
 using namespace isc::data;
 using namespace isc::data;
 using namespace isc::log;
 using namespace isc::log;
@@ -25,17 +26,17 @@ using namespace isc::log;
 namespace isc {
 namespace isc {
 namespace dhcp {
 namespace dhcp {
 
 
-static const char* DEFAULT_SYSLOG_NAME = "kea";
-
 LogConfigParser::LogConfigParser(const ConfigurationPtr& storage)
 LogConfigParser::LogConfigParser(const ConfigurationPtr& storage)
-    :config_(storage) {
+    :config_(storage), verbose_(false) {
     if (!storage) {
     if (!storage) {
-        isc_throw(InvalidOperation, "LogConfigParser needs a pointer to the "
+        isc_throw(BadValue, "LogConfigParser needs a pointer to the "
                   "configuration, so parsed data can be stored there");
                   "configuration, so parsed data can be stored there");
     }
     }
 }
 }
 
 
-void LogConfigParser::parseConfiguration(isc::data::ConstElementPtr loggers) {
+void LogConfigParser::parseConfiguration(isc::data::ConstElementPtr loggers,
+                                         bool verbose) {
+    verbose_ = verbose;
 
 
     // Iterate over all entries in "Logging/loggers" list
     // Iterate over all entries in "Logging/loggers" list
     BOOST_FOREACH(ConstElementPtr logger, loggers->listValue()) {
     BOOST_FOREACH(ConstElementPtr logger, loggers->listValue()) {
@@ -72,9 +73,9 @@ void LogConfigParser::parseConfigEntry(isc::data::ConstElementPtr entry) {
     try {
     try {
         info.severity_ = isc::log::getSeverity(severity_ptr->stringValue().c_str());
         info.severity_ = isc::log::getSeverity(severity_ptr->stringValue().c_str());
     } catch (const std::exception& ex) {
     } catch (const std::exception& ex) {
-        isc_throw(BadValue, "Unable to convert '" << severity_ptr->stringValue()
-                  << "' into allowed severity (" << severity_ptr->getPosition()
-                  << ")");
+        isc_throw(BadValue, "Unsupported severity value '"
+                  << severity_ptr->stringValue() << "' ("
+                  << severity_ptr->getPosition() << ")");
     }
     }
 
 
     // Get debug logging level
     // Get debug logging level
@@ -91,12 +92,21 @@ void LogConfigParser::parseConfigEntry(isc::data::ConstElementPtr entry) {
                 isc_throw(BadValue, "");
                 isc_throw(BadValue, "");
             }
             }
         } catch (...) {
         } catch (...) {
-            isc_throw(BadValue, "Unable to convert '" << debuglevel_ptr->stringValue()
-                      << "' into allowed debuglevel range (0-99) ("
+            isc_throw(BadValue, "Unsupported debuglevel value '"
+                      << debuglevel_ptr->stringValue()
+                      << "', expected 0-99 ("
                       << debuglevel_ptr->getPosition() << ")");
                       << debuglevel_ptr->getPosition() << ")");
         }
         }
     }
     }
 
 
+    // We want to follow the normal path, so it could catch parsing errors even
+    // when verbose mode is enabled. If it is, just override whatever was parsed
+    // in the config file.
+    if (verbose_) {
+        info.severity_ = isc::log::DEBUG;
+        info.debuglevel_ = 99;
+    }
+
     isc::data::ConstElementPtr output_options = entry->get("output_options");
     isc::data::ConstElementPtr output_options = entry->get("output_options");
 
 
     if (output_options) {
     if (output_options) {
@@ -138,8 +148,6 @@ void LogConfigParser::parseOutputOptions(std::vector<LoggingDestination>& destin
 
 
 void LogConfigParser::applyConfiguration() {
 void LogConfigParser::applyConfiguration() {
 
 
-    // Constants: not declared static as this is function is expected to be
-    // called once only
     static const std::string STDOUT = "stdout";
     static const std::string STDOUT = "stdout";
     static const std::string STDERR = "stderr";
     static const std::string STDERR = "stderr";
     static const std::string SYSLOG = "syslog";
     static const std::string SYSLOG = "syslog";
@@ -180,8 +188,8 @@ void LogConfigParser::applyConfiguration() {
                 // Must take account of the string actually being "syslog:"
                 // Must take account of the string actually being "syslog:"
                 if (dest->output_ == SYSLOG_COLON) {
                 if (dest->output_ == SYSLOG_COLON) {
                     // The expected syntax is syslog:facility. User skipped
                     // The expected syntax is syslog:facility. User skipped
-                    // the logging name, so we'll just use DEFAULT_SYSLOG_NAME.
-                    option.facility = DEFAULT_SYSLOG_NAME;
+                    // the logging name, so we'll just use the default ("kea")
+                    option.facility = isc::log::getDefaultRootLoggerName();
                     
                     
                 } else {
                 } else {
                     // Everything else in the string is the facility name
                     // Everything else in the string is the facility name
@@ -203,8 +211,9 @@ void LogConfigParser::applyConfiguration() {
     }
     }
 }
 }
 
 
-void LogConfigParser::defaultLogging() {
-    LoggerSpecification spec("kea", isc::log::INFO, 0);
+void LogConfigParser::applyDefaultConfiguration(bool verbose) {
+    LoggerSpecification spec("kea", (verbose?isc::log::DEBUG : isc::log::INFO),
+                             (verbose?99:0));
 
 
     OutputOption option;
     OutputOption option;
     option.destination = OutputOption::DEST_CONSOLE;
     option.destination = OutputOption::DEST_CONSOLE;

+ 45 - 21
src/lib/dhcpsrv/logging.h

@@ -17,18 +17,34 @@
 
 
 #include <cc/data.h>
 #include <cc/data.h>
 #include <dhcpsrv/configuration.h>
 #include <dhcpsrv/configuration.h>
-#include <dhcpsrv/cfgmgr.h>
-#include <stdint.h>
 #include <vector>
 #include <vector>
 
 
 namespace isc {
 namespace isc {
 namespace dhcp {
 namespace dhcp {
 
 
-/// @brief Interprets JSON structures and translates them to log4cplus
+/// @brief Configures log4cplus by translating Kea configuration structures
 ///
 ///
-/// This parser iterates over provided JSON structures and translates them
+/// This parser iterates over provided data elements and translates them
 /// into values applicable to log4cplus.
 /// into values applicable to log4cplus.
 ///
 ///
+/// The data structures converted to JSON format have the following syntax:
+/// {
+///     "name": "kea",
+///     "output_options": [
+///         {
+///             "output": "/home/thomson/kea-inst/kea-warn.log",
+///             "maxver": 8,
+///             "maxsize": 204800
+///         }
+///     ],
+///     "severity": "WARN"
+/// }
+///
+/// This is only an example and actual values may be different.
+///
+/// The data structures don't have to originate from JSON. JSON is just a
+/// convenient presentation syntax.
+///
 /// This class uses Configuration structure to store logging configuration.
 /// This class uses Configuration structure to store logging configuration.
 class LogConfigParser {
 class LogConfigParser {
 public:
 public:
@@ -44,37 +60,39 @@ public:
     /// parsed information in config_->logging_info_.
     /// parsed information in config_->logging_info_.
     ///
     ///
     /// @param log_config JSON structures to be parsed (loggers list)
     /// @param log_config JSON structures to be parsed (loggers list)
-    void parseConfiguration(isc::data::ConstElementPtr log_config);
+    /// @param verbose specifies verbose mode (true forces DEBUG, debuglevel = 99)
+    void parseConfiguration(isc::data::ConstElementPtr log_config,
+                            bool verbose = false);
 
 
     /// @brief Applies stored configuration
     /// @brief Applies stored configuration
     void applyConfiguration();
     void applyConfiguration();
 
 
     /// @brief Configures default logging
     /// @brief Configures default logging
-    static void defaultLogging();
+    ///
+    /// This method is static,
+    ///
+    /// @param verbose specifies verbose mode (true forces DEBUG, debuglevel = 99)
+    void applyDefaultConfiguration(bool verbose = false);
 
 
-protected:
+private:
 
 
     /// @brief Parses one JSON structure in Logging/loggers" array
     /// @brief Parses one JSON structure in Logging/loggers" array
     ///
     ///
-    /// The structure has the following syntax:
-    /// {
-    ///     "name": "*",
-    ///     "output_options": [
-    ///         {
-    ///             "output": "/home/thomson/kea-inst/kea-warn.log",
-    ///             "maxver": 8,
-    ///             "maxsize": 204800
-    ///         }
-    ///     ],
-    ///     "severity": "WARN"
-    /// }
-    ///
     /// @param entry JSON structure to be parsed
     /// @param entry JSON structure to be parsed
     /// @brief parses one structure in Logging/loggers.
     /// @brief parses one structure in Logging/loggers.
     void parseConfigEntry(isc::data::ConstElementPtr entry);
     void parseConfigEntry(isc::data::ConstElementPtr entry);
 
 
     /// @brief Parses output_options structure
     /// @brief Parses output_options structure
     ///
     ///
+    /// An example data structure that holds output_options in JSON format
+    /// looks like this:
+    ///     "output_options": [
+    ///         {
+    ///             "output": "/var/log/kea-warn.log",
+    ///             "maxver": 8,
+    ///             "maxsize": 204800
+    ///         }
+    ///     ],
     /// @param destination parsed parameters will be stored here
     /// @param destination parsed parameters will be stored here
     /// @param output_options element to be parsed
     /// @param output_options element to be parsed
     void parseOutputOptions(std::vector<LoggingDestination>& destination,
     void parseOutputOptions(std::vector<LoggingDestination>& destination,
@@ -84,9 +102,15 @@ protected:
     ///
     ///
     /// LogConfigParser class uses only config_->logging_info_ field.
     /// LogConfigParser class uses only config_->logging_info_ field.
     ConfigurationPtr config_;
     ConfigurationPtr config_;
+
+    /// @brief Verbose mode
+    ///
+    /// When verbose mode is enabled, logging severity is overridden to DEBUG,
+    /// and debuglevel is always 99.
+    bool verbose_;
 };
 };
 
 
 } // namespace isc::dhcp
 } // namespace isc::dhcp
 } // namespace isc
 } // namespace isc
 
 
-#endif // CFGMGR_H
+#endif // DHCPSRV_LOGGING_H

+ 1 - 1
src/lib/dhcpsrv/subnet.h

@@ -778,4 +778,4 @@ typedef std::vector<Subnet6Ptr> Subnet6Collection;
 } // end of isc::dhcp namespace
 } // end of isc::dhcp namespace
 } // end of isc namespace
 } // end of isc namespace
 
 
-#endif // SUBNET_T
+#endif // SUBNET_H

+ 1 - 1
src/lib/dhcpsrv/tests/configuration_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above

+ 7 - 2
src/lib/dhcpsrv/tests/daemon_unittest.cc

@@ -25,9 +25,14 @@ using namespace isc::data;
 
 
 namespace {
 namespace {
 
 
-// Very simple test. Checks whether Daemon can be instantiated.
+// Very simple test. Checks whether Daemon can be instantiated and its
+// default parameters are sane
 TEST(DaemonTest, noop) {
 TEST(DaemonTest, noop) {
     EXPECT_NO_THROW(Daemon x);
     EXPECT_NO_THROW(Daemon x);
+
+    // Check that the verbose mode is not set by default.
+    Daemon y;
+    EXPECT_FALSE(y.getVerbose());
 }
 }
 
 
 // Checks that configureLogger method is behaving properly.
 // Checks that configureLogger method is behaving properly.
@@ -55,7 +60,7 @@ TEST(DaemonTest, parsingConsoleOutput) {
 
 
     // Spawn a daemon and tell it to configure logger
     // Spawn a daemon and tell it to configure logger
     Daemon x;
     Daemon x;
-    EXPECT_NO_THROW(x.configureLogger(config, storage));
+    EXPECT_NO_THROW(x.configureLogger(config, storage, false));
 
 
     // The parsed configuration should be processed by the daemon and
     // The parsed configuration should be processed by the daemon and
     // stored in configuration storage.
     // stored in configuration storage.

+ 110 - 12
src/lib/dhcpsrv/tests/logging_unittest.cc

@@ -27,8 +27,8 @@ namespace {
 // Checks that contructor is able to process specified storage properly
 // Checks that contructor is able to process specified storage properly
 TEST(LoggingTest, constructor) {
 TEST(LoggingTest, constructor) {
 
 
-    ConfigurationPtr nullPtr;
-    EXPECT_THROW(LogConfigParser parser(nullPtr), InvalidOperation);
+    ConfigurationPtr null_ptr;
+    EXPECT_THROW(LogConfigParser parser(null_ptr), BadValue);
 
 
     ConfigurationPtr nonnull(new Configuration());
     ConfigurationPtr nonnull(new Configuration());
 
 
@@ -40,7 +40,7 @@ TEST(LoggingTest, constructor) {
 // configured to stdout on debug level.
 // configured to stdout on debug level.
 TEST(LoggingTest, parsingConsoleOutput) {
 TEST(LoggingTest, parsingConsoleOutput) {
 
 
-    const char* config_txt = 
+    const char* config_txt =
     "{ \"loggers\": ["
     "{ \"loggers\": ["
     "    {"
     "    {"
     "        \"name\": \"kea\","
     "        \"name\": \"kea\","
@@ -60,7 +60,7 @@ TEST(LoggingTest, parsingConsoleOutput) {
 
 
     // We need to parse properly formed JSON and then extract
     // We need to parse properly formed JSON and then extract
     // "loggers" element from it. For some reason fromJSON is
     // "loggers" element from it. For some reason fromJSON is
-    // throwing at opening square bracket 
+    // throwing at opening square bracket
     ConstElementPtr config = Element::fromJSON(config_txt);
     ConstElementPtr config = Element::fromJSON(config_txt);
     config = config->get("loggers");
     config = config->get("loggers");
 
 
@@ -81,7 +81,7 @@ TEST(LoggingTest, parsingConsoleOutput) {
 // configured to a file on INFO level.
 // configured to a file on INFO level.
 TEST(LoggingTest, parsingFile) {
 TEST(LoggingTest, parsingFile) {
 
 
-    const char* config_txt = 
+    const char* config_txt =
     "{ \"loggers\": ["
     "{ \"loggers\": ["
     "    {"
     "    {"
     "        \"name\": \"kea\","
     "        \"name\": \"kea\","
@@ -100,7 +100,7 @@ TEST(LoggingTest, parsingFile) {
 
 
     // We need to parse properly formed JSON and then extract
     // We need to parse properly formed JSON and then extract
     // "loggers" element from it. For some reason fromJSON is
     // "loggers" element from it. For some reason fromJSON is
-    // throwing at opening square bracket 
+    // throwing at opening square bracket
     ConstElementPtr config = Element::fromJSON(config_txt);
     ConstElementPtr config = Element::fromJSON(config_txt);
     config = config->get("loggers");
     config = config->get("loggers");
 
 
@@ -116,11 +116,109 @@ TEST(LoggingTest, parsingFile) {
     EXPECT_EQ("logfile.txt" , storage->logging_info_[0].destinations_[0].output_);
     EXPECT_EQ("logfile.txt" , storage->logging_info_[0].destinations_[0].output_);
 }
 }
 
 
-// There is no easy way to test applyConfiguration() and defaultLogging().
-// To test them, it would require instrumenting log4cplus to actually fake
-// the logging set up. Alternatively, we could develop set of test suites
-// that check each logging destination spearately (e.g. configure log file, then
-// check if the file is indeed created or configure stdout destination, then
-// swap console file descriptors and check that messages are really logged.
+// Checks if the LogConfigParser class is able to transform data structures
+// into Configuration usable by log4cplus. This test checks that more than
+// one logger can be configured.
+TEST(LoggingTest, multipleLoggers) {
+
+    const char* config_txt =
+    "{ \"loggers\": ["
+    "    {"
+    "        \"name\": \"kea\","
+    "        \"output_options\": ["
+    "            {"
+    "                \"output\": \"logfile.txt\""
+    "            }"
+    "        ],"
+    "        \"severity\": \"INFO\""
+    "    },"
+    "    {"
+    "        \"name\": \"wombat\","
+    "        \"output_options\": ["
+    "            {"
+    "                \"output\": \"logfile2.txt\""
+    "            }"
+    "        ],"
+    "        \"severity\": \"DEBUG\","
+    "        \"debuglevel\": 99"
+    "    }"
+    "]}";
+
+    ConfigurationPtr storage(new Configuration());
+
+    LogConfigParser parser(storage);
+
+    // We need to parse properly formed JSON and then extract
+    // "loggers" element from it. For some reason fromJSON is
+    // throwing at opening square bracket
+    ConstElementPtr config = Element::fromJSON(config_txt);
+    config = config->get("loggers");
+
+    EXPECT_NO_THROW(parser.parseConfiguration(config));
+
+    ASSERT_EQ(2, storage->logging_info_.size());
+
+    EXPECT_EQ("kea", storage->logging_info_[0].name_);
+    EXPECT_EQ(0, storage->logging_info_[0].debuglevel_);
+    EXPECT_EQ(isc::log::INFO, storage->logging_info_[0].severity_);
+    ASSERT_EQ(1, storage->logging_info_[0].destinations_.size());
+    EXPECT_EQ("logfile.txt" , storage->logging_info_[0].destinations_[0].output_);
+
+    EXPECT_EQ("wombat", storage->logging_info_[1].name_);
+    EXPECT_EQ(99, storage->logging_info_[1].debuglevel_);
+    EXPECT_EQ(isc::log::DEBUG, storage->logging_info_[1].severity_);
+    ASSERT_EQ(1, storage->logging_info_[1].destinations_.size());
+    EXPECT_EQ("logfile2.txt" , storage->logging_info_[1].destinations_[0].output_);
+}
+
+// Checks if the LogConfigParser class is able to transform data structures
+// into Configuration usable by log4cplus. This test checks that more than
+// one logging destination can be configured.
+TEST(LoggingTest, multipleLoggingDestinations) {
+
+    const char* config_txt =
+    "{ \"loggers\": ["
+    "    {"
+    "        \"name\": \"kea\","
+    "        \"output_options\": ["
+    "            {"
+    "                \"output\": \"logfile.txt\""
+    "            },"
+    "            {"
+    "                \"output\": \"stdout\""
+    "            }"
+    "        ],"
+    "        \"severity\": \"INFO\""
+    "    }"
+    "]}";
+
+    ConfigurationPtr storage(new Configuration());
+
+    LogConfigParser parser(storage);
+
+    // We need to parse properly formed JSON and then extract
+    // "loggers" element from it. For some reason fromJSON is
+    // throwing at opening square bracket
+    ConstElementPtr config = Element::fromJSON(config_txt);
+    config = config->get("loggers");
+
+    EXPECT_NO_THROW(parser.parseConfiguration(config));
+
+    ASSERT_EQ(1, storage->logging_info_.size());
+
+    EXPECT_EQ("kea", storage->logging_info_[0].name_);
+    EXPECT_EQ(0, storage->logging_info_[0].debuglevel_);
+    EXPECT_EQ(isc::log::INFO, storage->logging_info_[0].severity_);
+    ASSERT_EQ(2, storage->logging_info_[0].destinations_.size());
+    EXPECT_EQ("logfile.txt" , storage->logging_info_[0].destinations_[0].output_);
+    EXPECT_EQ("stdout" , storage->logging_info_[0].destinations_[1].output_);
+}
+
+/// @todo There is no easy way to test applyConfiguration() and defaultLogging().
+/// To test them, it would require instrumenting log4cplus to actually fake
+/// the logging set up. Alternatively, we could develop set of test suites
+/// that check each logging destination spearately (e.g. configure log file, then
+/// check if the file is indeed created or configure stdout destination, then
+/// swap console file descriptors and check that messages are really logged.
 
 
 };
 };

+ 1 - 1
src/lib/log/logger_manager.cc

@@ -51,7 +51,7 @@ int& initDebugLevel() {
 }
 }
 
 
 std::string& initRootName() {
 std::string& initRootName() {
-    static std::string root("bind10");
+    static std::string root(isc::log::getDefaultRootLoggerName());
     return (root);
     return (root);
 }
 }
 
 

+ 5 - 0
src/lib/log/logger_name.cc

@@ -40,6 +40,11 @@ const std::string& getRootLoggerName() {
     return (getRootLoggerNameInternal());
     return (getRootLoggerNameInternal());
 }
 }
 
 
+const std::string& getDefaultRootLoggerName() {
+    static std::string root_name("kea");
+    return (root_name);
+}
+
 std::string expandLoggerName(const std::string& name) {
 std::string expandLoggerName(const std::string& name) {
 
 
     // Are we the root logger, or does the logger name start with
     // Are we the root logger, or does the logger name start with

+ 6 - 0
src/lib/log/logger_name.h

@@ -40,6 +40,12 @@ void setRootLoggerName(const std::string& name);
 /// \return Name of the root logger.
 /// \return Name of the root logger.
 const std::string& getRootLoggerName();
 const std::string& getRootLoggerName();
 
 
+
+/// @brief Returns the default ('kea') root logger name
+///
+/// @return The default name of root logger.
+const std::string& getDefaultRootLoggerName();
+
 /// \brief Expand logger name
 /// \brief Expand logger name
 ///
 ///
 /// Given a logger name, returns the fully-expanded logger name.  If the name
 /// Given a logger name, returns the fully-expanded logger name.  If the name

+ 2 - 3
src/lib/log/logger_unittest_support.cc

@@ -150,11 +150,10 @@ resetUnitTestRootLogger() {
 void initLogger(isc::log::Severity severity, int dbglevel) {
 void initLogger(isc::log::Severity severity, int dbglevel) {
 
 
     // Root logger name is defined by the environment variable B10_LOGGER_ROOT.
     // Root logger name is defined by the environment variable B10_LOGGER_ROOT.
-    // If not present, the name is "bind10".
-    const char* DEFAULT_ROOT = "bind10";
     const char* root = getenv("B10_LOGGER_ROOT");
     const char* root = getenv("B10_LOGGER_ROOT");
     if (! root) {
     if (! root) {
-        root = DEFAULT_ROOT;
+        // If not present, the name is "kea".
+        root = isc::log::getDefaultRootLoggerName().c_str();
     }
     }
 
 
     // Set the local message file
     // Set the local message file

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

@@ -34,7 +34,7 @@ namespace log {
 /// environment variables.  These are:
 /// environment variables.  These are:
 ///
 ///
 /// - B10_LOGGER_ROOT\n
 /// - B10_LOGGER_ROOT\n
-/// Name of the root logger.  If not given, the string "bind10" will be used.
+/// Name of the root logger.  If not given, the string "kea" will be used.
 ///
 ///
 /// - B10_LOGGER_SEVERITY\n
 /// - B10_LOGGER_SEVERITY\n
 /// Severity of messages that will be logged.  This must be one of the strings
 /// Severity of messages that will be logged.  This must be one of the strings

+ 17 - 17
src/lib/log/tests/init_logger_test.sh.in

@@ -37,13 +37,13 @@ echo "1. Checking that B10_LOGGER_SEVERITY/B10_LOGGER_DBGLEVEL work"
 
 
 echo -n  "   - severity=DEBUG, dbglevel=99: "
 echo -n  "   - severity=DEBUG, dbglevel=99: "
 cat > $tempfile << .
 cat > $tempfile << .
-DEBUG [bind10.log] LOG_BAD_DESTINATION unrecognized log destination: debug-0
-DEBUG [bind10.log] LOG_BAD_DESTINATION unrecognized log destination: debug-50
-DEBUG [bind10.log] LOG_BAD_DESTINATION unrecognized log destination: debug-99
-INFO  [bind10.log] LOG_BAD_SEVERITY unrecognized log severity: info
-WARN  [bind10.log] LOG_BAD_STREAM bad log console output stream: warn
-ERROR [bind10.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
-FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
+DEBUG [kea.log] LOG_BAD_DESTINATION unrecognized log destination: debug-0
+DEBUG [kea.log] LOG_BAD_DESTINATION unrecognized log destination: debug-50
+DEBUG [kea.log] LOG_BAD_DESTINATION unrecognized log destination: debug-99
+INFO  [kea.log] LOG_BAD_SEVERITY unrecognized log severity: info
+WARN  [kea.log] LOG_BAD_STREAM bad log console output stream: warn
+ERROR [kea.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
+FATAL [kea.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
 .
 .
 B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=99 ./init_logger_test | \
 B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=99 ./init_logger_test | \
     sed -e 's/\[\([a-z0-9\.]\{1,\}\)\/\([0-9]\{1,\}\)\]/[\1]/' | \
     sed -e 's/\[\([a-z0-9\.]\{1,\}\)\/\([0-9]\{1,\}\)\]/[\1]/' | \
@@ -52,12 +52,12 @@ passfail $?
 
 
 echo -n  "   - severity=DEBUG, dbglevel=50: "
 echo -n  "   - severity=DEBUG, dbglevel=50: "
 cat > $tempfile << .
 cat > $tempfile << .
-DEBUG [bind10.log] LOG_BAD_DESTINATION unrecognized log destination: debug-0
-DEBUG [bind10.log] LOG_BAD_DESTINATION unrecognized log destination: debug-50
-INFO  [bind10.log] LOG_BAD_SEVERITY unrecognized log severity: info
-WARN  [bind10.log] LOG_BAD_STREAM bad log console output stream: warn
-ERROR [bind10.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
-FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
+DEBUG [kea.log] LOG_BAD_DESTINATION unrecognized log destination: debug-0
+DEBUG [kea.log] LOG_BAD_DESTINATION unrecognized log destination: debug-50
+INFO  [kea.log] LOG_BAD_SEVERITY unrecognized log severity: info
+WARN  [kea.log] LOG_BAD_STREAM bad log console output stream: warn
+ERROR [kea.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
+FATAL [kea.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
 .
 .
 B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=50 ./init_logger_test | \
 B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=50 ./init_logger_test | \
     sed -e 's/\[\([a-z0-9\.]\{1,\}\)\/\([0-9]\{1,\}\)\]/[\1]/' | \
     sed -e 's/\[\([a-z0-9\.]\{1,\}\)\/\([0-9]\{1,\}\)\]/[\1]/' | \
@@ -66,9 +66,9 @@ passfail $?
 
 
 echo -n  "   - severity=WARN: "
 echo -n  "   - severity=WARN: "
 cat > $tempfile << .
 cat > $tempfile << .
-WARN  [bind10.log] LOG_BAD_STREAM bad log console output stream: warn
-ERROR [bind10.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
-FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
+WARN  [kea.log] LOG_BAD_STREAM bad log console output stream: warn
+ERROR [kea.log] LOG_DUPLICATE_MESSAGE_ID duplicate message ID (error) in compiled code
+FATAL [kea.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
 .
 .
 B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=WARN ./init_logger_test | \
 B10_LOGGER_DESTINATION=stdout B10_LOGGER_SEVERITY=WARN ./init_logger_test | \
     sed -e 's/\[\([a-z0-9\.]\{1,\}\)\/\([0-9]\{1,\}\)\]/[\1]/' | \
     sed -e 's/\[\([a-z0-9\.]\{1,\}\)\/\([0-9]\{1,\}\)\]/[\1]/' | \
@@ -79,7 +79,7 @@ echo "2. Checking that B10_LOGGER_DESTINATION works"
 
 
 echo -n  "   - stdout: "
 echo -n  "   - stdout: "
 cat > $tempfile << .
 cat > $tempfile << .
-FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
+FATAL [kea.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
 .
 .
 rm -f $destfile_tmp $destfile
 rm -f $destfile_tmp $destfile
 B10_LOGGER_SEVERITY=FATAL B10_LOGGER_DESTINATION=stdout ./init_logger_test 1> $destfile_tmp
 B10_LOGGER_SEVERITY=FATAL B10_LOGGER_DESTINATION=stdout ./init_logger_test 1> $destfile_tmp

+ 1 - 1
src/lib/log/tests/logger_lock_test.sh.in

@@ -33,7 +33,7 @@ echo -n  "Testing that logger acquires and releases locks correctly:"
 cat > $tempfile << .
 cat > $tempfile << .
 LOGGER_LOCK_TEST: MUTEXLOCK
 LOGGER_LOCK_TEST: MUTEXLOCK
 LOGGER_LOCK_TEST: LOCK
 LOGGER_LOCK_TEST: LOCK
-INFO  [bind10.log] LOG_LOCK_TEST_MESSAGE this is a test message.
+INFO  [kea.log] LOG_LOCK_TEST_MESSAGE this is a test message.
 LOGGER_LOCK_TEST: UNLOCK
 LOGGER_LOCK_TEST: UNLOCK
 .
 .
 rm -f $destfile
 rm -f $destfile

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

@@ -114,7 +114,7 @@ public:
     //
     //
     // \return Temporary file name
     // \return Temporary file name
     std::string createTempFilename() {
     std::string createTempFilename() {
-        string filename = TEMP_DIR + "/bind10_logger_manager_test_XXXXXX";
+        string filename = TEMP_DIR + "/kea_logger_manager_test_XXXXXX";
 
 
         // Copy into writeable storage for the call to mkstemp
         // Copy into writeable storage for the call to mkstemp
         boost::scoped_array<char> tname(new char[filename.size() + 1]);
         boost::scoped_array<char> tname(new char[filename.size() + 1]);

+ 5 - 0
src/lib/log/tests/logger_name_unittest.cc

@@ -75,3 +75,8 @@ TEST_F(LoggerNameTest, ExpandLoggerName) {
     EXPECT_EQ(FULL_NAME, expandLoggerName(NAME));
     EXPECT_EQ(FULL_NAME, expandLoggerName(NAME));
     EXPECT_EQ(FULL_NAME, expandLoggerName(FULL_NAME));
     EXPECT_EQ(FULL_NAME, expandLoggerName(FULL_NAME));
 }
 }
+
+// Checks that the default logger name is returned properly.
+TEST_F(LoggerNameTest, default) {
+    EXPECT_EQ("kea", getDefaultRootLoggerName());
+}