Commit 839d2324 authored by Stephen Morris's avatar Stephen Morris
Browse files

[trac1071] Add destination selection to initLogger

Add support of B10_LOGGER_DESTINATION to choose logging destination
for unit tests, and add tests to check that they work.  Also update
some documentation.
parent 9c846eb1
......@@ -920,6 +920,7 @@ AC_OUTPUT([doc/version.ent
src/lib/cc/tests/session_unittests_config.h
src/lib/log/tests/console_test.sh
src/lib/log/tests/destination_test.sh
src/lib/log/tests/init_logger_test.sh
src/lib/log/tests/local_file_test.sh
src/lib/log/tests/severity_test.sh
src/lib/log/tests/tempdir.h
......@@ -949,9 +950,10 @@ AC_OUTPUT([doc/version.ent
chmod +x src/bin/msgq/tests/msgq_test
chmod +x src/lib/dns/gen-rdatacode.py
chmod +x src/lib/dns/tests/testdata/gen-wiredata.py
chmod +x src/lib/log/tests/local_file_test.sh
chmod +x src/lib/log/tests/console_test.sh
chmod +x src/lib/log/tests/destination_test.sh
chmod +x src/lib/log/tests/init_logger_test.sh
chmod +x src/lib/log/tests/local_file_test.sh
chmod +x src/lib/log/tests/severity_test.sh
chmod +x src/lib/util/python/mkpywrapper.py
chmod +x src/lib/python/isc/log/tests/log_console.py
......
......@@ -59,6 +59,7 @@ nodist_b10_resolver_SOURCES = resolver_messages.cc resolver_messages.h
b10_resolver_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
b10_resolver_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_resolver_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_resolver_LDADD += $(top_builddir)/src/lib/util/libutil.la
b10_resolver_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
b10_resolver_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
b10_resolver_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
......@@ -67,6 +68,7 @@ b10_resolver_LDADD += $(top_builddir)/src/lib/log/liblog.la
b10_resolver_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
b10_resolver_LDADD += $(top_builddir)/src/lib/cache/libcache.la
b10_resolver_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
b10_resolver_LDADD += $(top_builddir)/src/lib/acl/libacl.la
b10_resolver_LDADD += $(top_builddir)/src/lib/resolve/libresolve.la
b10_resolver_LDADD += $(top_builddir)/src/bin/auth/change_user.o
b10_resolver_LDFLAGS = -pthread
......
......@@ -410,6 +410,44 @@ 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.
Logging Initialization
======================
In all cases, if an attempt is made to use a logging method before the logging
has been initialized, the program will terminate with a LoggingNotInitialized
call.
C++
---
Logging Initialization is carried out by calling initLogger(). There are two
variants to the call, one for use by production programs and one for use by
unit tests.
Variant #1, Used by Production Programs
---------------------------------------
void initLogger(const std::string& root,
isc::log::Severity severity = isc::log::INFO,
int dbglevel = 0, const char* file = NULL);
This is the call that should be used by production programs:
root
Name of the program (e.g. "b10-auth"). This is also the name of the root
logger and is used when configuring logging.
severity
Default severity that the program will start logging with. Although this may
be overridden when the program obtains its configuration from the configuration
database, this is the severity that it used until then. (This may be set by
a command-line parameter.)
dbglevel
The debug level used if "severity" is set to isc::log::DEBUG.
file
The name of a local message file. This will be read and its defintitions used
to replace the compiled-in text of the messages.
Notes
=====
......@@ -419,3 +457,47 @@ in both the message compiler and the server; in the server it is used
when the server starts up (or when triggered by a command) to read in
a message file to overwrite the internal dictionary. Writing it in C++
means there is only one piece of code that does this functionality.
Variant #2, Used by Unit Tests
------------------------------
void initLogger()
This is the call that should be used by unit tests. In this variant, all the
options are supplied by environment variables. (It should not be used for
production programs to avoid the chance that the program operation is affected
by inadvertantly-defined environment variables.)
The environment variables are:
B10_LOGGER_ROOT
Sets the "root" for the unit test. If not defined, the name "bind10" is used.
B10_LOGGER_SEVERITY
The severity to set for the root logger in the unit test. Valid values are
"DEBUG", "INFO", "WARN", "ERROR", "FATAL" and "NONE". If not defined, "INFO"
is used.
B10_LOGGER_DBGLEVEL
If B10_LOGGER_SEVERITY is set to "DEBUG", the debug level. This can be a
number between 0 and 99, and defaults to 0.
B10_LOGGER_LOCALMSG
If defined, points to a local message file. The default is not to use a local
message file.
B10_LOGGER_DESTINATION
The location to which log message are written. This can be one of:
stdout Message are written to stdout
stderr Messages are written to stderr
syslog[:facility] Messages are written to syslog. If the optional
"facility" is used, the messages are written using
that facility. (This defaults to "local7" if not
specified)
Anything else Interpreted as the name of a file to which output
is appended. If the file does not exist, a new one
is opened.
In the case of "stdout", "stderr" and "syslog", they must be written exactly
as is - no leading or trailing spaces, and in lower-case.
......@@ -31,7 +31,9 @@
#include <log/logger_level.h>
#include <log/logger_manager.h>
#include <log/logger_specification.h>
#include <log/logger_support.h>
#include <log/output_option.h>
using namespace std;
......@@ -40,6 +42,68 @@ namespace {
// Flag to hold logging initialization state.
bool logging_init_state = false;
// Set logging destination according to the setting of B10_LOGGER_DESTINATION.
// (See header for initLogger() for more details.)
void
setDestination(const char* root, const isc::log::Severity severity,
const int dbglevel) {
using namespace isc::log;
// Constants:
static const string STDOUT = "stdout";
static const string STDERR = "stderr";
static const string SYSLOG = "syslog";
static const string SYSLOG_COLON = "syslog:";
const char* destination = getenv("B10_LOGGER_DESTINATION");
if (destination != NULL) {
// Destination is present, adjust root logger destination to it.
LoggerSpecification spec(root, severity, dbglevel);
OutputOption option;
const string dest = destination;
if (dest == STDOUT) {
option.destination = OutputOption::DEST_CONSOLE;
option.stream = OutputOption::STR_STDOUT;
} else if (dest == STDERR) {
option.destination = OutputOption::DEST_CONSOLE;
option.stream = OutputOption::STR_STDERR;
} else if (dest == SYSLOG) {
option.destination = OutputOption::DEST_SYSLOG;
option.facility = "local0";
} else if (dest.find(SYSLOG_COLON) == 0) {
option.destination = OutputOption::DEST_SYSLOG;
// Must take account of the string actually being "syslog:".
if (dest == SYSLOG_COLON) {
cerr << "**ERROR** value for B10_LOGGER_DESTINATION of " <<
SYSLOG_COLON << " is invalid, " << SYSLOG <<
" will be used instead\n";
option.facility = "local0";
} else {
// Everything else is the facility name
option.facility = dest.substr(SYSLOG_COLON.size());
}
} else {
// Not a recognised destination, assume a file.
option.destination = OutputOption::DEST_FILE;
option.filename = dest;
}
// ... and set it.
spec.addOutputOption(option);
LoggerManager manager;
manager.process(spec);
}
}
} // Anonymous namespace
namespace isc {
......@@ -115,11 +179,14 @@ void initLogger(isc::log::Severity severity, int dbglevel) {
}
}
/// Set the local message file
// Set the local message file
const char* localfile = getenv("B10_LOGGER_LOCALMSG");
// Initialize logging
initLogger(root, severity, dbglevel, localfile);
// Now set the destination
setDestination(root, severity, dbglevel);
}
} // namespace log
......
......@@ -68,26 +68,37 @@ void initLogger(const std::string& root,
/// Performs run-time initialization of the logger via the setting of
/// environment variables. These are:
///
/// B10_LOGGER_ROOT
/// - B10_LOGGER_ROOT\n
/// Name of the root logger. If not given, the string "bind10" will be used.
///
/// B10_LOGGER_SEVERITY
/// - B10_LOGGER_SEVERITY\n
/// Severity of messages that will be logged. This must be one of the strings
/// "DEBUG", "INFO", "WARN", "ERROR", "FATAL" or "NONE". (Must be upper case
/// and must not contain leading or trailing spaces.) If not specified (or if
/// specified but incorrect), the default passed as argument to this function
/// (currently INFO) will be used.
///
/// B10_LOGGER_DBGLEVEL
/// - B10_LOGGER_DBGLEVEL\n
/// Ignored if the level is not DEBUG, this should be a number between 0 and
/// 99 indicating the logging severity. The default is 0. If outside these
/// limits or if not a number, The value passed to this function (default
/// of 0) is used.
///
/// B10_LOGGER_LOCALMSG
/// - B10_LOGGER_LOCALMSG\n
/// If defined, the path specification of a file that contains message
/// definitions replacing ones in the default dictionary.
///
/// - B10_LOGGER_DESTINATION\n
/// If defined, the destination of the logging output. This can be one of:
/// - \c stdout Send output to stdout.
/// - \c stderr Send output to stderr
/// - \c syslog Send output to syslog using the facility local0.
/// - \c syslog:xxx Send output to syslog, using the facility xxx. ("xxx"
/// should be one of the syslog facilities such as "local0".) There must
/// be a colon between "syslog" and "xxx
/// - \c other Anything else is interpreted as the name of a file to which
/// output is appended. If the file does not exist, it is created.
///
/// Any errors in the settings cause messages to be output to stderr.
///
/// This function is aimed at test programs, allowing the default settings to
......
......@@ -52,12 +52,23 @@ logger_example_LDFLAGS = $(AM_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
logger_example_LDADD = $(top_builddir)/src/lib/log/liblog.la
logger_example_LDADD += $(top_builddir)/src/lib/util/libutil.la
check_PROGRAMS += init_logger_test
init_logger_test_SOURCES = init_logger_test.cc
init_logger_test_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
init_logger_test_LDFLAGS = $(AM_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
init_logger_test_LDADD = $(top_builddir)/src/lib/log/liblog.la
init_logger_test_LDADD += $(top_builddir)/src/lib/util/libutil.la
noinst_PROGRAMS = $(TESTS)
# Additional test using the shell
PYTESTS = console_test.sh local_file_test.sh severity_test.sh
# Additional test using the shell. These are principally tests
# where the global logging environment is affected, and where the
# output needs to be compared with stored output (where "cut" and
# "diff" are useful utilities).
check-local:
$(SHELL) $(abs_builddir)/console_test.sh
$(SHELL) $(abs_builddir)/destination_test.sh
$(SHELL) $(abs_builddir)/init_logger_test.sh
$(SHELL) $(abs_builddir)/local_file_test.sh
$(SHELL) $(abs_builddir)/severity_test.sh
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <log/macros.h>
#include <log/logger_support.h>
#include <log/log_messages.h>
using namespace isc::log;
/// \brief Test InitLogger
///
/// A test program that initializes using initLogger(), then outputs several
/// messages at different severities. An external script sets the environment
/// variables and checks that they have the desired effect.
int
main(int, char**) {
initLogger();
Logger logger("log");
LOG_DEBUG(logger, 0, LOG_BAD_DESTINATION).arg("debug-0");
LOG_DEBUG(logger, 50, LOG_BAD_DESTINATION).arg("debug-50");
LOG_DEBUG(logger, 99, LOG_BAD_DESTINATION).arg("debug-99");
LOG_INFO(logger, LOG_BAD_SEVERITY).arg("info");
LOG_WARN(logger, LOG_BAD_STREAM).arg("warn");
LOG_ERROR(logger, LOG_DUPLICATE_MESSAGE_ID).arg("error");
LOG_FATAL(logger, LOG_NO_MESSAGE_ID).arg("fatal");
return (0);
}
#!/bin/sh
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# \brief Severity test
#
# Checks that the logger will limit the output of messages less severy than
# the severity/debug setting.
testname="initLogger test"
echo $testname
failcount=0
tempfile=@abs_builddir@/init_logger_test_tempfile_$$
destfile=@abs_builddir@/init_logger_test_destfile_$$
passfail() {
if [ $1 -eq 0 ]; then
echo " pass"
else
echo " FAIL"
failcount=`expr $failcount + $1`
fi
}
echo "1. Checking that B10_LOGGER_SEVERITY/B10_LOGGER_DBGLEVEL work"
echo -n " - severity=DEBUG, dbglevel=99: "
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
.
rm -f $destfile
B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=99 ./init_logger_test 2> $destfile
cut -d' ' -f3- $destfile | diff $tempfile -
passfail $?
echo -n " - severity=DEBUG, dbglevel=50: "
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
.
rm -f $destfile
B10_LOGGER_SEVERITY=DEBUG B10_LOGGER_DBGLEVEL=50 ./init_logger_test 2> $destfile
cut -d' ' -f3- $destfile | diff $tempfile -
passfail $?
echo -n " - severity=WARN: "
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
.
rm -f $destfile
B10_LOGGER_SEVERITY=WARN ./init_logger_test 2> $destfile
cut -d' ' -f3- $destfile | diff $tempfile -
passfail $?
echo "2. Checking that B10_LOGGER_DESTINATION works"
echo -n " - stdout: "
cat > $tempfile << .
FATAL [bind10.log] LOG_NO_MESSAGE_ID line fatal: message definition line found without a message ID
.
rm -f $destfile
B10_LOGGER_SEVERITY=FATAL B10_LOGGER_DESTINATION=stdout ./init_logger_test 1> $destfile
cut -d' ' -f3- $destfile | diff $tempfile -
passfail $?
echo -n " - stderr: "
rm -f $destfile
B10_LOGGER_SEVERITY=FATAL B10_LOGGER_DESTINATION=stderr ./init_logger_test 2> $destfile
cut -d' ' -f3- $destfile | diff $tempfile -
passfail $?
echo -n " - file: "
rm -f $destfile
B10_LOGGER_SEVERITY=FATAL B10_LOGGER_DESTINATION=$destfile ./init_logger_test
cut -d' ' -f3- $destfile | diff $tempfile -
passfail $?
# Note: can't automatically test syslog output.
if [ $failcount -eq 0 ]; then
echo "PASS: $testname"
elif [ $failcount -eq 1 ]; then
echo "FAIL: $testname - 1 test failed"
else
echo "FAIL: $testname - $failcount tests failed"
fi
# Tidy up.
rm -f $tempfile $destfile
exit $failcount
......@@ -33,7 +33,7 @@ passfail() {
fi
}
echo -n "1. runInitTest default parameters:"
echo -n "1. Default parameters:"
cat > $tempfile << .
FATAL [example] LOG_WRITE_ERROR error writing to test1: 42
ERROR [example] LOG_READING_LOCAL_FILE reading local message file dummy/file
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment