Browse Source

[trac558] Update Logger Initialization

Updated the initialization function to take the logger name.  Also
added code to detect (and log) if duplicate message IDs were
compiled into the system.
Stephen Morris 14 years ago
parent
commit
a7cbba9981

+ 29 - 11
src/lib/log/logger_support.cc

@@ -24,6 +24,8 @@
 /// These functions will be replaced once the code has bneen written to obtain
 /// the logging parameters from the configuration database.
 
+#include <algorithm>
+#include <string>
 #include <vector>
 #include <boost/lexical_cast.hpp>
 
@@ -32,6 +34,7 @@
 #include <log/messagedef.h>
 #include <log/message_dictionary.h>
 #include <log/message_exception.h>
+#include <log/message_initializer.h>
 #include <log/message_reader.h>
 #include <log/message_types.h>
 #include <log/root_logger_name.h>
@@ -41,7 +44,8 @@ namespace log {
 
 using namespace std;
 
-// Declare a logger for the logging subsystem
+// Declare a logger for the logging subsystem.  This is a sub-logger of the
+// root logger and is used in all functions in this file.
 Logger logger("log");
 
 
@@ -58,6 +62,7 @@ readLocalMessageFile(const char* file) {
     MessageDictionary& dictionary = MessageDictionary::globalDictionary();
     MessageReader reader(&dictionary);
     try {
+        logger.info(MSG_RDLOCMES, file);
         reader.readFile(file, MessageReader::REPLACE);
 
         // File successfully read, list the duplicates
@@ -89,20 +94,33 @@ readLocalMessageFile(const char* file) {
 /// Logger Run-Time Initialization
 
 void
-runTimeInit(isc::log::Severity severity, int dbglevel, const char* file) {
+init(const string& root, isc::log::Severity severity, int dbglevel,
+    const char* file) {
 
-    // Create the application root logger.  This is the logger that has the
-    // name of the application (and is one level down from the log4cxx root
-    // logger).  All other loggers created in this application will be its
-    // child.
-    //
-    // The main purpose of the application root logger is to provide the root
-    // name in output message for all other loggers.
-    Logger logger(isc::log::getRootLoggerName());
+    // Create the application root logger and set the default severity and
+    // 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);
 
     // Set the severity associated with it.  If no other logger has a severity,
     // this will be the default.
-    logger.setSeverity(severity, dbglevel);
+    root_logger.setSeverity(severity, dbglevel);
+
+    // Check if there were any duplicate message IDs in the default dictionary
+    // and if so, log them.  Log using the logging facility root logger.
+    vector<string>& duplicates = MessageInitializer::getDuplicates();
+    if (!duplicates.empty()) {
+
+        // There are - sort and remove any duplicates.
+        sort(duplicates.begin(), duplicates.end());
+        vector<string>::iterator new_end =
+            unique(duplicates.begin(), duplicates.end());
+        for (vector<string>::iterator i = duplicates.begin(); i != new_end; ++i) {
+            logger.warn(MSG_DUPMSGID, i->c_str());
+        }
+
+    }
 
     // Replace any messages with local ones (if given)
     if (file) {

+ 11 - 6
src/lib/log/logger_support.h

@@ -15,6 +15,7 @@
 #ifndef __LOGGER_SUPPORT_H
 #define __LOGGER_SUPPORT_H
 
+#include <string>
 #include <log/logger.h>
 
 namespace isc {
@@ -22,17 +23,21 @@ namespace log {
 
 /// \brief Run-Time Initialization
 ///
-/// This code will be used until the logger is fully integrated into the BIND-10
-/// configuration database.  It performs run-time initialization of the logger,
-/// in particular supplying run-time choices to it:
+/// Performs run-time initialization of the logger in particular supplying:
 ///
-/// * The severity (and if applicable, debug level) at which to log
-/// * Name of a local message file, containing localisation of message text.
+/// - Name of the root logger
+/// - The severity (and if applicable, debug level) for the root logger.
+/// - Name of a local message file, containing localisation of message text.
 ///
+/// This function is likely to change over time as more debugging options are
+/// held in the configuration database.
+///
+/// \param root Name of the root logger
 /// \param severity Severity at which to log
 /// \param dbglevel Debug severiy (ignored if "severity" is not "DEBUG")
 /// \param file Name of the local message file.
-void runTimeInit(isc::log::Severity severity, int dbglevel, const char* file);
+void init(const std::string& root, isc::log::Severity severity, int dbglevel,
+    const char* file);
 
 } // namespace log
 } // namespace isc

+ 15 - 1
src/lib/log/message_initializer.cc

@@ -23,7 +23,21 @@ namespace log {
 
 MessageInitializer::MessageInitializer(const char* values[]) {
     MessageDictionary& global = MessageDictionary::globalDictionary();
-    global.load(values);
+    std::vector<std::string> repeats = global.load(values);
+
+    // Append the IDs in the list just loaded (the "repeats") to the global list
+    // of duplicate IDs.
+    if (!repeats.empty()) {
+        std::vector<std::string>& duplicates = getDuplicates();
+        duplicates.insert(duplicates.end(), repeats.begin(), repeats.end());
+    }
+}
+
+// Return reference to duplicate array
+
+std::vector<std::string>& MessageInitializer::getDuplicates() {
+    static std::vector<std::string> duplicates;
+    return (duplicates);
 }
 
 } // namespace log

+ 16 - 2
src/lib/log/message_initializer.h

@@ -15,6 +15,8 @@
 #ifndef __MESSAGEINITIALIZER_H
 #define __MESSAGEINITIALIZER_H
 
+#include <string>
+#include <vector>
 #include <log/message_dictionary.h>
 
 namespace isc {
@@ -50,9 +52,21 @@ public:
 
     /// \brief Constructor
     ///
-    /// The only method in the class, this adds the array of values to the
-    /// global dictionary.
+    /// Adds the array of values to the global dictionary, and notes any
+    /// duplicates.
+    ///
+    /// \param values NULL-terminated array of alternating identifier strings
+    /// and associated message text.
     MessageInitializer(const char* values[]);
+
+    /// \brief Return Duplicates
+    ///
+    /// When messages are added to the global dictionary, any duplicates are
+    /// recorded.  They can later be output through the logging system.
+    ///
+    /// \return List of duplicate message IDs when the global dictionary was
+    /// loaded.  Note that the duplicates list itself may contain duplicates.
+    static std::vector<std::string>& getDuplicates();
 };
 
 } // namespace log

+ 5 - 1
src/lib/log/messagedef.cc

@@ -1,4 +1,4 @@
-// File created from messagedef.mes on Wed Feb  9 10:11:36 2011
+// File created from messagedef.mes on Wed Feb  9 13:09:05 2011
 
 #include <cstddef>
 #include <log/message_types.h>
@@ -9,6 +9,7 @@ namespace log {
 
 extern const isc::log::MessageID MSG_DUPLNS = "DUPLNS";
 extern const isc::log::MessageID MSG_DUPLPRFX = "DUPLPRFX";
+extern const isc::log::MessageID MSG_DUPMSGID = "DUPMSGID";
 extern const isc::log::MessageID MSG_IDNOTFND = "IDNOTFND";
 extern const isc::log::MessageID MSG_NSEXTRARG = "NSEXTRARG";
 extern const isc::log::MessageID MSG_NSINVARG = "NSINVARG";
@@ -19,6 +20,7 @@ extern const isc::log::MessageID MSG_OPENOUT = "OPENOUT";
 extern const isc::log::MessageID MSG_PRFEXTRARG = "PRFEXTRARG";
 extern const isc::log::MessageID MSG_PRFINVARG = "PRFINVARG";
 extern const isc::log::MessageID MSG_PRFNOARG = "PRFNOARG";
+extern const isc::log::MessageID MSG_RDLOCMES = "RDLOCMES";
 extern const isc::log::MessageID MSG_READERR = "READERR";
 extern const isc::log::MessageID MSG_UNRECDIR = "UNRECDIR";
 extern const isc::log::MessageID MSG_WRITERR = "WRITERR";
@@ -31,6 +33,7 @@ namespace {
 const char* values[] = {
     "DUPLNS", "duplicate $NAMESPACE directive found",
     "DUPLPRFX", "duplicate $PREFIX directive found",
+    "DUPMSGID", "duplicate ID found in source code: %s",
     "IDNOTFND", "could not replace message for '%s': no such message identification",
     "NSEXTRARG", "$NAMESPACE directive has too many arguments",
     "NSINVARG", "$NAMESPACE directive has an invalid argument ('%s')",
@@ -41,6 +44,7 @@ const char* values[] = {
     "PRFEXTRARG", "$PREFIX directive has too many arguments",
     "PRFINVARG", "$PREFIX directive has an invalid argument ('%s')",
     "PRFNOARG", "no arguments were given to the $PREFIX directive",
+    "RDLOCMES", "reading local message file %s",
     "READERR", "error reading from %s: %s",
     "UNRECDIR", "unrecognised directive '%s'",
     "WRITERR", "error writing to %s: %s",

+ 3 - 1
src/lib/log/messagedef.h

@@ -1,4 +1,4 @@
-// File created from messagedef.mes on Wed Feb  9 10:11:36 2011
+// File created from messagedef.mes on Wed Feb  9 13:09:05 2011
 
 #ifndef __MESSAGEDEF_H
 #define __MESSAGEDEF_H
@@ -10,6 +10,7 @@ namespace log {
 
 extern const isc::log::MessageID MSG_DUPLNS;
 extern const isc::log::MessageID MSG_DUPLPRFX;
+extern const isc::log::MessageID MSG_DUPMSGID;
 extern const isc::log::MessageID MSG_IDNOTFND;
 extern const isc::log::MessageID MSG_NSEXTRARG;
 extern const isc::log::MessageID MSG_NSINVARG;
@@ -20,6 +21,7 @@ extern const isc::log::MessageID MSG_OPENOUT;
 extern const isc::log::MessageID MSG_PRFEXTRARG;
 extern const isc::log::MessageID MSG_PRFINVARG;
 extern const isc::log::MessageID MSG_PRFNOARG;
+extern const isc::log::MessageID MSG_RDLOCMES;
 extern const isc::log::MessageID MSG_READERR;
 extern const isc::log::MessageID MSG_UNRECDIR;
 extern const isc::log::MessageID MSG_WRITERR;

+ 11 - 0
src/lib/log/messagedef.mes

@@ -23,6 +23,13 @@ $NAMESPACE isc::log
 # chicken-and-egg situation where we need the files to build the message
 # compiler, yet we need the compiler to build the files.
 
+DUPMSGID  duplicate ID found in source code: %s
++ The same message identification appears in more that one file in the BIND10
++ source code.  Every message logged by BIND10 should have a unique
++ identification associated with it, so this indicates a failure in the build
++ process.  The develops should locate the duplicate IDs and alter one (or more)
++ of them.
+
 DUPLNS    duplicate $NAMESPACE directive found
 + When reading a message file, more than one $NAMESPACE directive was found.  In
 + this version of the code, such a condition is regarded as an error and the
@@ -91,6 +98,10 @@ PRFNOARG    no arguments were given to the $PREFIX directive
 + symbol names when a C++ .h file is created.  This error is generated when the
 + compiler finds a $PREFIX directive with no arguments.
 
+RDLOCMES    reading local message file %s
++ This is an informational message output on BIND start-up when it is about to
++ read a supplied local message file.
+
 READERR     error reading from %s: %s
 + The specified error was encountered reading from the named input file.
 

+ 1 - 3
src/lib/log/tests/logger_support_test.cc

@@ -53,8 +53,6 @@ int main(int argc, char** argv) {
     const char*         localfile = NULL;
     int                 option;
 
-    isc::log::setRootLoggerName("alpha");
-
     // Parse options
     while ((option = getopt(argc, argv, "s:d:")) != -1) {
         switch (option) {
@@ -91,7 +89,7 @@ int main(int argc, char** argv) {
     }
 
     // Update the logging parameters
-    runTimeInit(severity, dbglevel, localfile);
+    init("alpha", severity, dbglevel, localfile);
 
     // Log a few messages
     logger_ex.fatal(MSG_WRITERR, "test1", "42");

+ 37 - 9
src/lib/log/tests/message_dictionary_unittest.cc

@@ -16,12 +16,29 @@
 #include <string>
 #include <gtest/gtest.h>
 #include <log/message_dictionary.h>
+#include <log/message_initializer.h>
 #include <log/message_types.h>
 
 using namespace isc;
 using namespace isc::log;
 using namespace std;
 
+// set up another message initializer.  This will add a symbol found in the
+// logging library and a symbol not found in the logging library.  When the
+// global dictionary is loaded, the former should be marked as a duplicate
+// and the latter should be present.
+
+static const char* values[] = {
+    "DUPLNS", "duplicate $NAMESPACE directive found",
+    "NEWSYM", "new symbol added",
+    NULL
+};
+
+MessageInitializer init(values);
+
+
+
+
 class MessageDictionaryTest : public ::testing::Test {
 protected:
     MessageDictionaryTest() : 
@@ -40,15 +57,6 @@ protected:
 
 };
 
-
-// Check that the global dictionary is a singleton.
-
-TEST_F(MessageDictionaryTest, GlobalTest) {
-    MessageDictionary& global = MessageDictionary::globalDictionary();
-    MessageDictionary& global2 = MessageDictionary::globalDictionary();
-    EXPECT_TRUE(&global2 == &global);
-}
-
 // Check that adding messages works
 
 TEST_F(MessageDictionaryTest, Add) {
@@ -167,3 +175,23 @@ TEST_F(MessageDictionaryTest, Lookups) {
     EXPECT_EQ(string(""), dictionary.getText(""));
     EXPECT_EQ(string(""), dictionary.getText("\n\n\n"));
 }
+
+// Check that the global dictionary is a singleton.
+
+TEST_F(MessageDictionaryTest, GlobalTest) {
+    MessageDictionary& global = MessageDictionary::globalDictionary();
+    MessageDictionary& global2 = MessageDictionary::globalDictionary();
+    EXPECT_TRUE(&global2 == &global);
+}
+
+// Check that the global dictionary has detected the duplicate and the
+// new symbol.
+
+TEST_F(MessageDictionaryTest, GlobalLoadTest) {
+    vector<string>& duplicates = MessageInitializer::getDuplicates();
+    ASSERT_EQ(1, duplicates.size());
+    EXPECT_EQ(string("DUPLNS"), duplicates[0]);
+
+    string text = MessageDictionary::globalDictionary().getText("NEWSYM");
+    EXPECT_EQ(string("new symbol added"), text);
+}

+ 1 - 2
src/lib/log/tests/run_time_init_test.sh.in

@@ -73,9 +73,8 @@ WARN  [alpha.log] IDNOTFND, could not replace message for 'NOTHERE': no such mes
 FATAL [alpha.example] WRITERR, error writing to test1: 42
 ERROR [alpha.example] UNRECDIR, replacement unrecognised directive message, parameter is 'false'
 WARN  [alpha.dlm] READERR, replacement read error, parameters: 'a.txt' and 'dummy test'
-INFO  [alpha.dlm] OPENIN, unable to open message file example.msg for input: dummy test
 .
-./logger_support_test $localmes | cut -d' ' -f3- | diff $tempfile -
+./logger_support_test -s warn $localmes | cut -d' ' -f3- | diff $tempfile -
 passfail $?
 
 rm -f $localmes