diff options
author | Stephen Morris <stephen@isc.org> | 2011-01-24 21:15:05 +0100 |
---|---|---|
committer | Stephen Morris <stephen@isc.org> | 2011-01-24 21:15:05 +0100 |
commit | 6b118748704d34fbea4d80cbed3a1094abd22e11 (patch) | |
tree | c57ce345ee9eb6c607ea58e32ee8e492c5a0e72d /src/lib/log | |
parent | add linker flag to liblog makefile (diff) | |
download | kea-6b118748704d34fbea4d80cbed3a1094abd22e11.tar.xz kea-6b118748704d34fbea4d80cbed3a1094abd22e11.zip |
Minor modifications to logging code made after review.
Diffstat (limited to 'src/lib/log')
-rw-r--r-- | src/lib/log/Message.h | 72 | ||||
-rw-r--r-- | src/lib/log/compiler/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/log/documentation.txt | 85 | ||||
-rw-r--r-- | src/lib/log/filename.cc | 15 | ||||
-rw-r--r-- | src/lib/log/logger.cc | 50 | ||||
-rw-r--r-- | src/lib/log/logger.h | 32 | ||||
-rw-r--r-- | src/lib/log/logger_support.cc | 6 | ||||
-rw-r--r-- | src/lib/log/message_dictionary.cc | 19 | ||||
-rw-r--r-- | src/lib/log/message_reader.cc | 4 | ||||
-rw-r--r-- | src/lib/log/strutil.cc | 10 | ||||
-rw-r--r-- | src/lib/log/strutil.h | 18 | ||||
-rw-r--r-- | src/lib/log/tests/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/log/tests/logger_unittest.cc | 12 | ||||
-rw-r--r-- | src/lib/log/tests/strutil_unittest.cc | 64 | ||||
-rw-r--r-- | src/lib/log/xdebuglevel.cc | 17 |
15 files changed, 243 insertions, 163 deletions
diff --git a/src/lib/log/Message.h b/src/lib/log/Message.h deleted file mode 100644 index 5654bf76ec..0000000000 --- a/src/lib/log/Message.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2010 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. - -// $Id$ - -#ifndef __MESSAGE_H -#define __MESSAGE_H - -/// \brief Log Message -/// -/// This class represents a message in which information about a logging event -/// is encoded. This is invisible to the author of code doing logging unless -/// they are planning on writing an Appender. - -class Message { -public: - - // The following is a placeholder. It will be replaced with a finer- - // grained time definition during implementation. - typedef time_t Time; ///< To be replaced with a finer-grained time later - - // Constructor/destructor stll to be determined - - /// \brief Return Timestamp - /// - /// \return Timestamp associated with the message. - Time getTimestamp() const; - - /// \brief Return Source - /// - /// \return Returns the source of the message. This is a "."-separated - /// string containing the hierarchy of the logger than generated this - /// message. - std::string getSource() const; - - /// \brief Return ID - /// - /// \return Returns the ID of the message, a 32-bit integer. - uint32_t getId() const; - - /// \brief Return Parameters - /// - /// \return The parameters of the message in the form of a vector of - /// strings. Numeric parameters have been converted to strings and - /// included in the message. - std::vector<std::string> getParameters() const; - - /// \brief Return Encoded Message - /// - /// The contents of the message are encoded as a string in the form - /// - /// <message ID><'\0'><param 1><'\0'>... - /// - /// Some Appenders may find this format useful, so the ability to retrieve - /// it directly is provided. - std::string getRawMessage() const; -}; - - - -#endif // __MESSAGE_H diff --git a/src/lib/log/compiler/Makefile.am b/src/lib/log/compiler/Makefile.am index 0b025a9914..2475036e75 100644 --- a/src/lib/log/compiler/Makefile.am +++ b/src/lib/log/compiler/Makefile.am @@ -17,5 +17,4 @@ CLEANFILES = *.gcno *.gcda pkglibexec_PROGRAMS = message message_SOURCES = message.cc message_LDADD = $(top_builddir)/src/lib/log/liblog.la -message_LDADD += $(LOG4CXX_LDFLAGS) diff --git a/src/lib/log/documentation.txt b/src/lib/log/documentation.txt index 6dc84db09a..1439ad553d 100644 --- a/src/lib/log/documentation.txt +++ b/src/lib/log/documentation.txt @@ -268,6 +268,91 @@ To use the current version of the logging: At present, the only logging is to the console. +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. + +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. + +ERROR +----- +Something has happened such that the program can continue but the results +for the current (or future) operations cannot be guaranteed to be correct, +or the results will be correct but the service is impaired. For example, +the program started but attempts to open one or more network interfaces failed. + +WARN +---- +An unusual event happened. Although the program will continue working +normally, the event was sufficiently out of the ordinary to warrant drawings +attention to it. For example, at program start-up a zone was loaded that +contained no resource records, + +INFO +---- +A normal but significant event has occurred that should be recorded, +e.g. the program has started or is just about to terminate, a new zone has +been created, etc. + +DEBUG +----- +This severity is only enabled on for debugging purposes. A debug level is +associated with debug messages, level 0 (the default) being for high-level +messages and level 99 (the maximum) for the lowest level. How the messages +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.) + +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 +probably easier to visualise the debug levels as part of the severity system: + + FATAL High + ERROR + WARN + INFO + DEBUG level 0 + DEBUG level 1 + : + DEBUG level 99 Low + +When a particular severity is set, it - and all severities and/or debug +levels above it - will be logged. + +Logging Sources v Logging Severities +------------------------------------ +When logging events, make a distinction between events related to the server +and events related to DNS messages received. Caution needs to be exercised +with the latter as, if the logging is enabled in the normal course of events, +such logging could be a denoial of service vector. For example, suppose that +the main authoritiative service logger were to log both zone loading and +unloading as INFO and a warning message if it received an invalid packet. An +attacker could make the INFO messages unusable by flooding the server with +malformed packets. + +There are two approaches to get round this: + +a) Make the logging of packet-dependent events a DEBUG-severity message. +DEBUG is not enabled by default, so these events will not be recorded unless +DEBUG is specifically chosen. + +b) Record system-related and packet-related messages via different loggers +(e.g. in the example given, sever events could be logged using the logger +"auth" and packet-related events at that level logged using the logger +"pkt-auth".) +As the loggers are independent and the severity levels independent, fine-tuning +of what and what is not recorded can be achieved. + + Outstanding Issues ================== * Ability to configure system according to configuration database. diff --git a/src/lib/log/filename.cc b/src/lib/log/filename.cc index 60a46e23d3..949ed9f58b 100644 --- a/src/lib/log/filename.cc +++ b/src/lib/log/filename.cc @@ -32,12 +32,13 @@ namespace log { // Split string into components. Any backslashes are assumed to have // been replaced by forward slashes. -void Filename::split(const string& full_name, string& directory, +void +Filename::split(const string& full_name, string& directory, string& name, string& extension) const { directory = name = extension = ""; bool dir_present = false; - if (! full_name.empty()) { + if (!full_name.empty()) { // Find the directory. size_t last_slash = full_name.find_last_of('/'); @@ -84,7 +85,8 @@ void Filename::split(const string& full_name, string& directory, // Expand the stored filename with the default. -string Filename::expandWithDefault(const string& defname) const { +string +Filename::expandWithDefault(const string& defname) const { string def_directory(""); string def_name(""); @@ -92,7 +94,9 @@ string Filename::expandWithDefault(const string& defname) const { // Normalize the input string. string copy_defname = isc::strutil::trim(defname); +#ifdef WIN32 isc::strutil::normalizeSlash(copy_defname); +#endif // Split into the components split(copy_defname, def_directory, def_name, def_extension); @@ -107,7 +111,8 @@ string Filename::expandWithDefault(const string& defname) const { // Use the stored name as default for a given name -string Filename::useAsDefault(const string& name) const { +string +Filename::useAsDefault(const string& name) const { string name_directory(""); string name_name(""); @@ -115,7 +120,9 @@ string Filename::useAsDefault(const string& name) const { // Normalize the input string. string copy_name = isc::strutil::trim(name); +#ifdef WIN32 isc::strutil::normalizeSlash(copy_name); +#endif // Split into the components split(copy_name, name_directory, name_name, name_extension); diff --git a/src/lib/log/logger.cc b/src/lib/log/logger.cc index e183fc356b..494e7bc41a 100644 --- a/src/lib/log/logger.cc +++ b/src/lib/log/logger.cc @@ -51,11 +51,12 @@ Logger::~Logger() { // Initialize logger - create a logger as a child of the root logger. With // log4cxx this is assured by naming the logger <parent>.<child>. -void Logger::initLogger() { +void +Logger::initLogger() { // Initialize basic logging if not already done. This is a one-off for // all loggers. - if (! init_) { + if (!init_) { // TEMPORARY // Add a suitable console logger to the log4cxx root logger. (This @@ -100,13 +101,13 @@ void Logger::initLogger() { // Set the severity for logging. There is a 1:1 mapping between the logging // severity and the log4cxx logging levels, apart from DEBUG. // -// In log4cxx, each of the logging levels (DEBUG, INFO, WARNING etc.) has a -// numeric value. The level is set to one of these and any numeric level equal -// to or above it that is reported. For example INFO has a value of 20000 and -// ERROR a value of 40000. So if a message of WARNING severity (= 30000) is -// logged, it is not logged when the logger's severity level is ERROR (as -// 30000 !>= 40000). It is reported if the logger's severity level is set to -// WARNING (as 30000 >= 30000) or INFO (30000 >= 20000). +// In log4cxx, each of the logging levels (DEBUG, INFO, WARN etc.) has a numeric +// value. The level is set to one of these and any numeric level equal to or +// above it that is reported. For example INFO has a value of 20000 and ERROR +// a value of 40000. So if a message of WARN severity (= 30000) is logged, it is +// not logged when the logger's severity level is ERROR (as 30000 !>= 40000). +// It is reported if the logger's severity level is set to WARN (as 30000 >= +/// 30000) or INFO (30000 >= 20000). // // This gives a simple system for handling different debug levels. The debug // level is a number between 0 and 99, with 0 being least verbose and 99 the @@ -122,7 +123,8 @@ void Logger::initLogger() { // // The extended set of logging levels is implemented by the XDebugLevel class. -void Logger::setSeverity(Severity severity, int dbglevel) { +void +Logger::setSeverity(Severity severity, int dbglevel) { switch (severity) { case NONE: getLogger()->setLevel(log4cxx::Level::getOff()); @@ -136,7 +138,7 @@ void Logger::setSeverity(Severity severity, int dbglevel) { getLogger()->setLevel(log4cxx::Level::getError()); break; - case WARNING: + case WARN: getLogger()->setLevel(log4cxx::Level::getWarn()); break; @@ -159,7 +161,8 @@ void Logger::setSeverity(Severity severity, int dbglevel) { // Convert between numeric log4cxx logging level and BIND-10 logging severity. -Logger::Severity Logger::convertLevel(int value) const { +Logger::Severity +Logger::convertLevel(int value) const { // The order is optimised. This is only likely to be called when testing // for writing debug messages, so the check for DEBUG_INT is first. @@ -168,7 +171,7 @@ Logger::Severity Logger::convertLevel(int value) const { } else if (value <= log4cxx::Level::INFO_INT) { return (INFO); } else if (value <= log4cxx::Level::WARN_INT) { - return (WARNING); + return (WARN); } else if (value <= log4cxx::Level::ERROR_INT) { return (ERROR); } else if (value <= log4cxx::Level::FATAL_INT) { @@ -181,7 +184,8 @@ Logger::Severity Logger::convertLevel(int value) const { // Return the logging severity associated with this logger. -Logger::Severity Logger::getSeverityCommon(const log4cxx::LoggerPtr& ptrlogger, +Logger::Severity +Logger::getSeverityCommon(const log4cxx::LoggerPtr& ptrlogger, bool check_parent) const { log4cxx::LevelPtr level = ptrlogger->getLevel(); @@ -212,7 +216,8 @@ Logger::Severity Logger::getSeverityCommon(const log4cxx::LoggerPtr& ptrlogger, // Get the debug level. This returns 0 unless the severity is DEBUG. -int Logger::getDebugLevel() { +int +Logger::getDebugLevel() { log4cxx::LevelPtr level = getLogger()->getLevel(); if (level == log4cxx::LevelPtr()) { @@ -252,7 +257,8 @@ int Logger::getDebugLevel() { // Output methods -void Logger::debug(int dbglevel, isc::log::MessageID ident, ...) { +void +Logger::debug(int dbglevel, isc::log::MessageID ident, ...) { if (isDebugEnabled(dbglevel)) { char message[MESSAGE_SIZE]; FORMAT_MESSAGE(message); @@ -260,7 +266,8 @@ void Logger::debug(int dbglevel, isc::log::MessageID ident, ...) { } } -void Logger::info(isc::log::MessageID ident, ...) { +void +Logger::info(isc::log::MessageID ident, ...) { if (isInfoEnabled()) { char message[MESSAGE_SIZE]; FORMAT_MESSAGE(message); @@ -268,7 +275,8 @@ void Logger::info(isc::log::MessageID ident, ...) { } } -void Logger::warn(isc::log::MessageID ident, ...) { +void +Logger::warn(isc::log::MessageID ident, ...) { if (isWarnEnabled()) { char message[MESSAGE_SIZE]; FORMAT_MESSAGE(message); @@ -276,7 +284,8 @@ void Logger::warn(isc::log::MessageID ident, ...) { } } -void Logger::error(isc::log::MessageID ident, ...) { +void +Logger::error(isc::log::MessageID ident, ...) { if (isErrorEnabled()) { char message[MESSAGE_SIZE]; FORMAT_MESSAGE(message); @@ -284,7 +293,8 @@ void Logger::error(isc::log::MessageID ident, ...) { } } -void Logger::fatal(isc::log::MessageID ident, ...) { +void +Logger::fatal(isc::log::MessageID ident, ...) { if (isFatalEnabled()) { char message[MESSAGE_SIZE]; FORMAT_MESSAGE(message); diff --git a/src/lib/log/logger.h b/src/lib/log/logger.h index 7842f8c668..4f7847787e 100644 --- a/src/lib/log/logger.h +++ b/src/lib/log/logger.h @@ -36,13 +36,10 @@ public: DEFAULT, // Default to logging level of parent DEBUG, INFO, - WARNING, + WARN, ERROR, - CRITICAL, - NONE, // Disable logging - INFORMATION = INFO, - WARN = WARNING, - FATAL = CRITICAL + FATAL, + NONE // Disable logging } Severity; /// \brief Constructor @@ -60,7 +57,7 @@ public: /// destroyed causes a MutexException to be thrown (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.<BR> + /// have the program crash instead of shut down cleanly.\n\n /// The original implementation of the isc::log::Logger had as a member a /// log4cxx logger (actually a LoggerPtr). If the isc:: Logger was declared /// statically, when it was destroyed at the end of the program the internal @@ -68,7 +65,7 @@ public: /// not occur if the isc::log::Logger was created on the stack. To get /// round this, the internal LoggerPtr is now created dynamically. The /// exit_delete argument controls its destruction: if true, it is destroyed - /// in the ISC Logger destructor. If false, it is not.<BR> + /// in the ISC Logger destructor. If false, it is not.\n\n /// When creating an isc::log::Logger on the stack, the argument should be /// false (the default); when the Logger is destroyed, all the internal /// log4cxx objects are destroyed. As only the logger (and not the internal @@ -171,27 +168,13 @@ public: } - /// \brief Is WARNING Enabled? - virtual bool isWarningEnabled() { - return (getLogger()->isWarnEnabled()); - } - - /// \brief Is ERROR Enabled? virtual bool isErrorEnabled() { return (getLogger()->isErrorEnabled()); } - /// \brief Is CRITICAL Enabled? - virtual bool isCriticalEnabled() { - return (getLogger()->isFatalEnabled()); - } - - /// \brief Is FATAL Enabled? - /// - /// FATAL is a synonym for CRITICAL. virtual bool isFatalEnabled() { return (getLogger()->isFatalEnabled()); } @@ -321,6 +304,11 @@ protected: static void readLocalMessageFile(const char* file); private: + // Note that loggerptr_ is a pointer to a LoggerPtr, which is itself a + // pointer to the underlying log4cxx logger. This is due to the problems + // with memory deletion on program exit, explained in the comments for + // the "exit_delete" parameter in this class's constructor. + log4cxx::LoggerPtr* loggerptr_; ///< Pointer to the underlying logger std::string name_; ///< Name of this logger] bool exit_delete_; ///< Delete loggerptr_ on exit? diff --git a/src/lib/log/logger_support.cc b/src/lib/log/logger_support.cc index cce1f3d45d..c9ba858054 100644 --- a/src/lib/log/logger_support.cc +++ b/src/lib/log/logger_support.cc @@ -55,7 +55,8 @@ Logger logger("log"); /// dictionary, they are listed in a warning message. /// /// \param file Name of the local message file -static void readLocalMessageFile(const char* file) { +static void +readLocalMessageFile(const char* file) { MessageDictionary* dictionary = MessageDictionary::globalDictionary(); MessageReader reader(dictionary); @@ -89,7 +90,8 @@ static void readLocalMessageFile(const char* file) { /// Logger Run-Time Initialization -void runTimeInit(Logger::Severity severity, int dbglevel, const char* file) { +void +runTimeInit(Logger::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 diff --git a/src/lib/log/message_dictionary.cc b/src/lib/log/message_dictionary.cc index 53697f6c00..05c79f8abe 100644 --- a/src/lib/log/message_dictionary.cc +++ b/src/lib/log/message_dictionary.cc @@ -30,8 +30,8 @@ MessageDictionary::~MessageDictionary() { // Add message and note if ID already exists -bool MessageDictionary::add(const MessageID& ident, const std::string& text) -{ +bool +MessageDictionary::add(const MessageID& ident, const std::string& text) { map<MessageID, string>::iterator i = dictionary_.find(ident); bool not_found = (i == dictionary_.end()); if (not_found) { @@ -45,8 +45,8 @@ bool MessageDictionary::add(const MessageID& ident, const std::string& text) // Add message and note if ID does not already exist -bool MessageDictionary::replace(const MessageID& ident, const std::string& text) -{ +bool +MessageDictionary::replace(const MessageID& ident, const std::string& text) { map<MessageID, string>::iterator i = dictionary_.find(ident); bool found = (i != dictionary_.end()); if (found) { @@ -60,7 +60,8 @@ bool MessageDictionary::replace(const MessageID& ident, const std::string& text) // Load a set of messages -vector<MessageID> MessageDictionary::load(const char* messages[]) { +vector<MessageID> +MessageDictionary::load(const char* messages[]) { vector<MessageID> duplicates; int i = 0; while (messages[i]) { @@ -75,7 +76,7 @@ vector<MessageID> MessageDictionary::load(const char* messages[]) { // Add ID and text to message dictionary, noting if the ID was // already present. bool added = add(ident, text); - if (! added) { + if (!added) { duplicates.push_back(ident); } } @@ -85,7 +86,8 @@ vector<MessageID> MessageDictionary::load(const char* messages[]) { // Return message text or blank string -string MessageDictionary::getText(const MessageID& ident) const { +string +MessageDictionary::getText(const MessageID& ident) const { map<MessageID, string>::const_iterator i = dictionary_.find(ident); if (i == dictionary_.end()) { return string(""); @@ -97,7 +99,8 @@ string MessageDictionary::getText(const MessageID& ident) const { // Return global dictionary -MessageDictionary* MessageDictionary::globalDictionary() { +MessageDictionary* +MessageDictionary::globalDictionary() { static MessageDictionary* global = NULL; if (global == NULL) { diff --git a/src/lib/log/message_reader.cc b/src/lib/log/message_reader.cc index 00018e7329..203b836331 100644 --- a/src/lib/log/message_reader.cc +++ b/src/lib/log/message_reader.cc @@ -59,7 +59,7 @@ MessageReader::readFile(const string& file, MessageReader::Mode mode) { } // Why did the loop terminate? - if (! infile.eof()) { + if (!infile.eof()) { throw MessageException(MSG_READERR, file, strerror(errno)); } infile.close(); @@ -175,7 +175,7 @@ MessageReader::parseMessage(const std::string& text, MessageReader::Mode mode) { else { added = dictionary_->replace(ident, text.substr(first_text)); } - if (! added) { + if (!added) { not_added_.push_back(ident); } } diff --git a/src/lib/log/strutil.cc b/src/lib/log/strutil.cc index fd9241e134..4b9660193a 100644 --- a/src/lib/log/strutil.cc +++ b/src/lib/log/strutil.cc @@ -27,8 +27,9 @@ namespace strutil { // Normalize slashes -void normalizeSlash(std::string& name) { - if (! name.empty()) { +void +normalizeSlash(std::string& name) { + if (!name.empty()) { size_t pos = 0; while ((pos = name.find('\\', pos)) != std::string::npos) { name[pos] = '/'; @@ -38,11 +39,12 @@ void normalizeSlash(std::string& name) { // Trim String -string trim(const string& instring) { +string +trim(const string& instring) { static const char* blanks = " \t\n"; string retstring = ""; - if (! instring.empty()) { + if (!instring.empty()) { // Search for first non-blank character in the string size_t first = instring.find_first_not_of(blanks); diff --git a/src/lib/log/strutil.h b/src/lib/log/strutil.h index 16301db094..cb0b79331f 100644 --- a/src/lib/log/strutil.h +++ b/src/lib/log/strutil.h @@ -56,8 +56,8 @@ std::string trim(const std::string& instring); /// that adjacent delimiters are considered to be a single delimiter. /// /// Special cases are: -/// 1) The empty string is considered to be zero tokens. -/// 2) A string comprising nothing but delimiters is considered to be zero +/// -# The empty string is considered to be zero tokens. +/// -# A string comprising nothing but delimiters is considered to be zero /// tokens. /// /// The reasoning behind this is that the string can be thought of as having @@ -79,9 +79,10 @@ std::vector<std::string> tokens(const std::string text, /// \brief Uppercase Character /// -/// Needed to pass as an argument to transform() in uppercase(), as the -/// function std::toupper() takes an "int" as its argument and the template -/// expansion mechanism gets confused. +/// Used in uppercase() to pass as an argument to std::transform(). The +/// function std::toupper() can't be used as it takes an "int" as its argument; +/// this confuses the template expansion mechanism because defererencing a +/// string::iterator returns a char. /// /// \param chr Character to be upper-cased. /// @@ -103,9 +104,10 @@ inline void uppercase(std::string& text) { /// \brief Lowercase Character /// -/// Needed to pass as an argument to transform() in lowercase(), as the -/// function std::tolower() takes an "int" as its argument and the template -/// expansion mechanism gets confused. +/// Used in lowercase() to pass as an argument to std::transform(). The +/// function std::tolower() can't be used as it takes an "int" as its argument; +/// this confuses the template expansion mechanism because defererencing a +/// string::iterator returns a char. /// /// \param chr Character to be lower-cased. /// diff --git a/src/lib/log/tests/Makefile.am b/src/lib/log/tests/Makefile.am index 340b27f29a..a99a6d3c68 100644 --- a/src/lib/log/tests/Makefile.am +++ b/src/lib/log/tests/Makefile.am @@ -35,7 +35,6 @@ 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 += -llog4cxx noinst_PROGRAMS = $(TESTS) diff --git a/src/lib/log/tests/logger_unittest.cc b/src/lib/log/tests/logger_unittest.cc index 214e1db65e..e15ec42fdc 100644 --- a/src/lib/log/tests/logger_unittest.cc +++ b/src/lib/log/tests/logger_unittest.cc @@ -131,10 +131,10 @@ TEST_F(LoggerTest, ConvertLevel) { EXPECT_EQ(Logger::DEBUG, logger.convertLevel(log4cxx::Level::DEBUG_INT)); EXPECT_EQ(Logger::INFO, logger.convertLevel(log4cxx::Level::INFO_INT)); EXPECT_EQ(Logger::WARN, logger.convertLevel(log4cxx::Level::WARN_INT)); - EXPECT_EQ(Logger::WARNING, logger.convertLevel(log4cxx::Level::WARN_INT)); + EXPECT_EQ(Logger::WARN, logger.convertLevel(log4cxx::Level::WARN_INT)); EXPECT_EQ(Logger::ERROR, logger.convertLevel(log4cxx::Level::ERROR_INT)); EXPECT_EQ(Logger::FATAL, logger.convertLevel(log4cxx::Level::FATAL_INT)); - EXPECT_EQ(Logger::CRITICAL, logger.convertLevel(log4cxx::Level::FATAL_INT)); + EXPECT_EQ(Logger::FATAL, logger.convertLevel(log4cxx::Level::FATAL_INT)); EXPECT_EQ(Logger::NONE, logger.convertLevel(log4cxx::Level::OFF_INT)); // Now some debug levels @@ -158,14 +158,14 @@ TEST_F(LoggerTest, Severity) { logger.setSeverity(Logger::NONE); EXPECT_EQ(Logger::NONE, logger.getSeverity()); - logger.setSeverity(Logger::CRITICAL); - EXPECT_EQ(Logger::CRITICAL, logger.getSeverity()); + logger.setSeverity(Logger::FATAL); + EXPECT_EQ(Logger::FATAL, logger.getSeverity()); logger.setSeverity(Logger::ERROR); EXPECT_EQ(Logger::ERROR, logger.getSeverity()); - logger.setSeverity(Logger::WARNING); - EXPECT_EQ(Logger::WARNING, logger.getSeverity()); + logger.setSeverity(Logger::WARN); + EXPECT_EQ(Logger::WARN, logger.getSeverity()); logger.setSeverity(Logger::INFO); EXPECT_EQ(Logger::INFO, logger.getSeverity()); diff --git a/src/lib/log/tests/strutil_unittest.cc b/src/lib/log/tests/strutil_unittest.cc index 147a92179c..6e657f39ae 100644 --- a/src/lib/log/tests/strutil_unittest.cc +++ b/src/lib/log/tests/strutil_unittest.cc @@ -76,24 +76,65 @@ TEST_F(StringUtilTest, Tokens) { vector<string> result; // Default delimiters - result = isc::strutil::tokens(" \n "); // Empty string + + // Degenerate cases + result = isc::strutil::tokens(""); // Empty string + EXPECT_EQ(0, result.size()); + + result = isc::strutil::tokens(" \n "); // String is all delimiters EXPECT_EQ(0, result.size()); - result = isc::strutil::tokens("abc"); // Full string + result = isc::strutil::tokens("abc"); // String has no delimiters ASSERT_EQ(1, result.size()); EXPECT_EQ(string("abc"), result[0]); - result = isc::strutil::tokens("\t xyz \n"); + // String containing leading and/or trailing delimiters, no embedded ones. + result = isc::strutil::tokens("\txyz"); // One leading delimiter + ASSERT_EQ(1, result.size()); + EXPECT_EQ(string("xyz"), result[0]); + + result = isc::strutil::tokens("\t \nxyz"); // Multiple leading delimiters + ASSERT_EQ(1, result.size()); + EXPECT_EQ(string("xyz"), result[0]); + + result = isc::strutil::tokens("xyz\n"); // One trailing delimiter ASSERT_EQ(1, result.size()); EXPECT_EQ(string("xyz"), result[0]); - result = isc::strutil::tokens("abc\ndef\t\tghi "); - ASSERT_EQ(3, result.size()); + result = isc::strutil::tokens("xyz \t"); // Multiple trailing + ASSERT_EQ(1, result.size()); + EXPECT_EQ(string("xyz"), result[0]); + + result = isc::strutil::tokens("\t xyz \n"); // Leading and trailing + ASSERT_EQ(1, result.size()); + EXPECT_EQ(string("xyz"), result[0]); + + // Embedded delimiters + result = isc::strutil::tokens("abc\ndef"); // 2 tokens, one separator + ASSERT_EQ(2, result.size()); + EXPECT_EQ(string("abc"), result[0]); + EXPECT_EQ(string("def"), result[1]); + + result = isc::strutil::tokens("abc\t\t\ndef"); // 2 tokens, 3 separators + ASSERT_EQ(2, result.size()); + EXPECT_EQ(string("abc"), result[0]); + EXPECT_EQ(string("def"), result[1]); + + result = isc::strutil::tokens("abc\n \tdef\t\tghi"); + ASSERT_EQ(3, result.size()); // Multiple tokens, many delims + EXPECT_EQ(string("abc"), result[0]); + EXPECT_EQ(string("def"), result[1]); + EXPECT_EQ(string("ghi"), result[2]); + + // Embedded and non-embedded delimiters + + result = isc::strutil::tokens("\t\t \nabc\n \tdef\t\tghi \n\n"); + ASSERT_EQ(3, result.size()); // Multiple tokens, many delims EXPECT_EQ(string("abc"), result[0]); EXPECT_EQ(string("def"), result[1]); EXPECT_EQ(string("ghi"), result[2]); - // Non-default delimiters + // Non-default delimiter result = isc::strutil::tokens("alpha/beta/ /gamma//delta/epsilon/", "/"); ASSERT_EQ(6, result.size()); EXPECT_EQ(string("alpha"), result[0]); @@ -102,6 +143,17 @@ TEST_F(StringUtilTest, Tokens) { EXPECT_EQ(string("gamma"), result[3]); EXPECT_EQ(string("delta"), result[4]); EXPECT_EQ(string("epsilon"), result[5]); + + // Non-default delimiters (plural) + result = isc::strutil::tokens("+*--alpha*beta+ -gamma**delta+epsilon-+**", + "*+-"); + ASSERT_EQ(6, result.size()); + EXPECT_EQ(string("alpha"), result[0]); + EXPECT_EQ(string("beta"), result[1]); + EXPECT_EQ(string(" "), result[2]); + EXPECT_EQ(string("gamma"), result[3]); + EXPECT_EQ(string("delta"), result[4]); + EXPECT_EQ(string("epsilon"), result[5]); } // Changing case diff --git a/src/lib/log/xdebuglevel.cc b/src/lib/log/xdebuglevel.cc index 77000e171c..7dddcff86b 100644 --- a/src/lib/log/xdebuglevel.cc +++ b/src/lib/log/xdebuglevel.cc @@ -39,7 +39,8 @@ IMPLEMENT_LOG4CXX_LEVEL(XDebugLevel) // Create Extended Debug Level Objects -LevelPtr XDebugLevel::getExtendedDebug(int level) { +LevelPtr +XDebugLevel::getExtendedDebug(int level) { // Initialize the logging levels corresponding to the possible range of // debug if we have not already done so @@ -77,11 +78,13 @@ LevelPtr XDebugLevel::getExtendedDebug(int level) { // 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) { +LevelPtr +XDebugLevel::toLevel(int val) { return toLevel(val, getExtendedDebug(MIN_DEBUG_LEVEL)); } -LevelPtr XDebugLevel::toLevel(int val, const LevelPtr& defaultLevel) { +LevelPtr +XDebugLevel::toLevel(int val, const LevelPtr& defaultLevel) { // Note the reversal of the notion of MIN and MAX - see the header file for // details. @@ -95,13 +98,13 @@ LevelPtr XDebugLevel::toLevel(int val, const LevelPtr& defaultLevel) { // Convert string passed to a logging level or return default level. -LevelPtr XDebugLevel::toLevelLS(const LogString& sArg) { +LevelPtr +XDebugLevel::toLevelLS(const LogString& sArg) { return toLevelLS(sArg, getExtendedDebug(0)); } -LevelPtr XDebugLevel::toLevelLS(const LogString& sArg, - const LevelPtr& defaultLevel) -{ +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 |