Commit 9c4e97e7 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

[2445] Make buffering optional, and enable in b10 components

parent bbefd6bc
......@@ -147,7 +147,7 @@ main(int argc, char* argv[]) {
// Initialize logging. If verbose, we'll use maximum verbosity.
isc::log::initLogger(AUTH_NAME,
(verbose ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL);
isc::log::MAX_DEBUG_LEVEL, NULL, true);
int ret = 0;
......@@ -256,7 +256,9 @@ main(int argc, char* argv[]) {
// If we haven't registered callback for data sources, this will be just
// no-op.
config_session->removeRemoteConfig("data_sources");
if (config_session) {
config_session->removeRemoteConfig("data_sources");
}
delete xfrin_session;
delete config_session;
......
......@@ -48,7 +48,7 @@ else:
PREFIX = "@prefix@"
DATAROOTDIR = "@datarootdir@"
SPECFILE_LOCATION = "@datadir@/@PACKAGE@/bob.spec".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
import subprocess
import signal
import re
......@@ -76,7 +76,7 @@ import isc.bind10.socket_cache
import libutil_io_python
import tempfile
isc.log.init("b10-boss")
isc.log.init("b10-boss", buffer=True)
logger = isc.log.Logger("boss")
# Pending system-wide debug level definitions, the ones we
......@@ -166,14 +166,14 @@ class ProcessStartError(Exception): pass
class BoB:
"""Boss of BIND class."""
def __init__(self, msgq_socket_file=None, data_path=None,
config_filename=None, clear_config=False,
verbose=False, nokill=False, setuid=None, setgid=None,
username=None, cmdctl_port=None, wait_time=10):
"""
Initialize the Boss of BIND. This is a singleton (only one can run).
The msgq_socket_file specifies the UNIX domain socket file that the
msgq process listens on. If verbose is True, then the boss reports
what it is doing.
......@@ -400,7 +400,7 @@ class BoB:
logger.error(BIND10_STARTUP_UNEXPECTED_MESSAGE, msg)
except:
logger.error(BIND10_STARTUP_UNRECOGNISED_MESSAGE, msg)
return False
# The next few methods start the individual processes of BIND-10. They
......@@ -464,7 +464,7 @@ class BoB:
time.sleep(1)
time_remaining = time_remaining - 1
msg, env = self.cc_session.group_recvmsg()
if not self.process_running(msg, "ConfigManager"):
raise ProcessStartError("Configuration manager process has not started")
......@@ -481,7 +481,7 @@ class BoB:
process, the log_starting/log_started methods are not used.
"""
logger.info(BIND10_STARTING_CC)
self.ccs = isc.config.ModuleCCSession(SPECFILE_LOCATION,
self.ccs = isc.config.ModuleCCSession(SPECFILE_LOCATION,
self.config_handler,
self.command_handler,
socket_file = self.msgq_socket_file)
......@@ -679,7 +679,7 @@ class BoB:
except:
pass
# XXX: some delay probably useful... how much is uncertain
# I have changed the delay from 0.5 to 1, but sometime it's
# I have changed the delay from 0.5 to 1, but sometime it's
# still not enough.
time.sleep(1)
self.reap_children()
......@@ -728,8 +728,8 @@ class BoB:
return os.waitpid(-1, os.WNOHANG)
def reap_children(self):
"""Check to see if any of our child processes have exited,
and note this for later handling.
"""Check to see if any of our child processes have exited,
and note this for later handling.
"""
while True:
try:
......@@ -760,11 +760,11 @@ class BoB:
"""
Restart any dead processes:
* Returns the time when the next process is ready to be restarted.
* Returns the time when the next process is ready to be restarted.
* If the server is shutting down, returns 0.
* If there are no processes, returns None.
The values returned can be safely passed into select() as the
The values returned can be safely passed into select() as the
timeout value.
"""
......@@ -1006,7 +1006,7 @@ boss_of_bind = None
def reaper(signal_number, stack_frame):
"""A child process has died (SIGCHLD received)."""
# don't do anything...
# don't do anything...
# the Python signal handler has been set up to write
# down a pipe, waking up our select() bit
pass
......@@ -1173,7 +1173,7 @@ and the created lock file must be writable for that user.
except KeyError:
pass
# Next try getting information about the user, assuming user name
# Next try getting information about the user, assuming user name
# passed.
# If the information is both a valid user name and user number, we
# prefer the name because we try it second. A minor point, hopefully.
......
......@@ -27,7 +27,7 @@ import glob
import os.path
import imp
import isc.log
isc.log.init("b10-cfgmgr")
isc.log.init("b10-cfgmgr", buffer=True)
from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError, logger
from isc.log_messages.cfgmgr_messages import *
......
......@@ -49,7 +49,7 @@ from hashlib import sha1
from isc.util import socketserver_mixin
from isc.log_messages.cmdctl_messages import *
isc.log.init("b10-cmdctl")
isc.log.init("b10-cmdctl", buffer=True)
logger = isc.log.Logger("cmdctl")
# Debug level for communication with BIND10
......
......@@ -45,7 +45,7 @@ import os.path
import signal
import socket
isc.log.init("b10-ddns")
isc.log.init("b10-ddns", buffer=True)
logger = isc.log.Logger("ddns")
TRACE_BASIC = logger.DBGLVL_TRACE_BASIC
......
......@@ -95,7 +95,7 @@ main(int argc, char* argv[]) {
// Initialize logging. If verbose, we'll use maximum verbosity.
isc::log::initLogger(DHCP4_NAME,
(verbose_mode ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL);
isc::log::MAX_DEBUG_LEVEL, NULL, true);
LOG_INFO(dhcp4_logger, DHCP4_STARTING);
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_START_INFO)
.arg(getpid()).arg(port_number).arg(verbose_mode ? "yes" : "no")
......
......@@ -105,7 +105,7 @@ main(int argc, char* argv[]) {
// Initialize logging. If verbose, we'll use maximum verbosity.
isc::log::initLogger(DHCP6_NAME,
(verbose_mode ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL);
isc::log::MAX_DEBUG_LEVEL, NULL, true);
LOG_INFO(dhcp6_logger, DHCP6_STARTING);
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_START_INFO)
.arg(getpid()).arg(port_number).arg(verbose_mode ? "yes" : "no")
......@@ -119,7 +119,7 @@ main(int argc, char* argv[]) {
server.establishSession();
} catch (const std::exception& ex) {
LOG_ERROR(dhcp6_logger, DHCP6_SESSION_FAIL).arg(ex.what());
// Let's continue. It is useful to have the ability to run
// Let's continue. It is useful to have the ability to run
// DHCP server in stand-alone mode, e.g. for testing
}
} else {
......
......@@ -143,7 +143,7 @@ main(int argc, char* argv[]) {
// temporary initLogger() code. If verbose, we'll use maximum verbosity.
isc::log::initLogger(RESOLVER_NAME,
(verbose ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL);
isc::log::MAX_DEBUG_LEVEL, NULL, true);
// Print the starting message
string cmdline = argv[0];
......@@ -177,7 +177,7 @@ main(int argc, char* argv[]) {
isc::cache::ResolverCache cache;
resolver->setCache(cache);
// TODO priming query, remove root from direct
// Fake a priming query result here (TODO2 how to flag non-expiry?)
// propagation to runningquery. And check for forwarder mode?
......@@ -185,21 +185,21 @@ main(int argc, char* argv[]) {
isc::dns::Name("."),
isc::dns::RRClass::IN(),
isc::dns::RRType::NS()));
isc::dns::RRsetPtr root_ns_rrset(new isc::dns::RRset(isc::dns::Name("."),
isc::dns::RRsetPtr root_ns_rrset(new isc::dns::RRset(isc::dns::Name("."),
isc::dns::RRClass::IN(),
isc::dns::RRType::NS(),
isc::dns::RRTTL(8888)));
root_ns_rrset->addRdata(isc::dns::rdata::createRdata(isc::dns::RRType::NS(),
isc::dns::RRClass::IN(),
"l.root-servers.net."));
isc::dns::RRsetPtr root_a_rrset(new isc::dns::RRset(isc::dns::Name("l.root-servers.net"),
isc::dns::RRsetPtr root_a_rrset(new isc::dns::RRset(isc::dns::Name("l.root-servers.net"),
isc::dns::RRClass::IN(),
isc::dns::RRType::A(),
isc::dns::RRTTL(8888)));
root_a_rrset->addRdata(isc::dns::rdata::createRdata(isc::dns::RRType::A(),
isc::dns::RRClass::IN(),
"199.7.83.42"));
isc::dns::RRsetPtr root_aaaa_rrset(new isc::dns::RRset(isc::dns::Name("l.root-servers.net"),
isc::dns::RRsetPtr root_aaaa_rrset(new isc::dns::RRset(isc::dns::Name("l.root-servers.net"),
isc::dns::RRClass::IN(),
isc::dns::RRType::AAAA(),
isc::dns::RRTTL(8888)));
......@@ -216,7 +216,7 @@ main(int argc, char* argv[]) {
cache.update(root_ns_rrset);
cache.update(root_a_rrset);
cache.update(root_aaaa_rrset);
DNSService dns_service(io_service, checkin, lookup, answer);
resolver->setDNSService(dns_service);
LOG_DEBUG(resolver_logger, RESOLVER_DBG_INIT, RESOLVER_SERVICE_CREATED);
......
......@@ -31,7 +31,7 @@ import isc.util.process
import isc.log
from isc.log_messages.stats_messages import *
isc.log.init("b10-stats")
isc.log.init("b10-stats", buffer=True)
logger = isc.log.Logger("stats")
# Some constants for debug levels.
......@@ -682,7 +682,7 @@ if __name__ == "__main__":
help="enable maximum debug logging")
(options, args) = parser.parse_args()
if options.verbose:
isc.log.init("b10-stats", "DEBUG", 99)
isc.log.init("b10-stats", "DEBUG", 99, buffer=True)
stats = Stats()
stats.start()
except OptionValueError as ove:
......
......@@ -39,7 +39,7 @@ import isc.util.process
import isc.log
from isc.log_messages.stats_httpd_messages import *
isc.log.init("b10-stats-httpd")
isc.log.init("b10-stats-httpd", buffer=True)
logger = isc.log.Logger("stats-httpd")
# Some constants for debug levels.
......@@ -609,7 +609,7 @@ if __name__ == "__main__":
help="enable maximum debug logging")
(options, args) = parser.parse_args()
if options.verbose:
isc.log.init("b10-stats-httpd", "DEBUG", 99)
isc.log.init("b10-stats-httpd", "DEBUG", 99, buffer=True)
stats_httpd = StatsHttpd()
stats_httpd.start()
except OptionValueError as ove:
......
......@@ -36,7 +36,7 @@ from isc.xfrin.diff import Diff
from isc.server_common.auth_command import auth_loadzone_command
from isc.log_messages.xfrin_messages import *
isc.log.init("b10-xfrin")
isc.log.init("b10-xfrin", buffer=True)
logger = isc.log.Logger("xfrin")
# Pending system-wide debug level definitions, the ones we
......
......@@ -38,7 +38,7 @@ import isc.server_common.tsig_keyring
from isc.log_messages.xfrout_messages import *
isc.log.init("b10-xfrout")
isc.log.init("b10-xfrout", buffer=True)
logger = isc.log.Logger("xfrout")
# Pending system-wide debug level definitions, the ones we
......
......@@ -42,7 +42,7 @@ from isc.log_messages.zonemgr_messages import *
from isc.notify import notify_out
# Initialize logging for called modules.
isc.log.init("b10-zonemgr")
isc.log.init("b10-zonemgr", buffer=True)
logger = isc.log.Logger("zonemgr")
# Pending system-wide debug level definitions, the ones we
......
......@@ -94,9 +94,8 @@ LoggerManager::processEnd() {
void
LoggerManager::init(const std::string& root, isc::log::Severity severity,
int dbglevel, const char* file)
int dbglevel, const char* file, bool buffer)
{
// Load in the messages declared in the program and registered by
// statically-declared MessageInitializer objects.
MessageInitializer::loadDictionary();
......@@ -115,7 +114,9 @@ LoggerManager::init(const std::string& root, isc::log::Severity severity,
// Initialize the implementation logging. After this point, some basic
// logging has been set up and messages can be logged.
LoggerManagerImpl::init(severity, dbglevel);
// However, they will not appear until a logging specification has been
// processed (or the program exits), see TODO
LoggerManagerImpl::init(severity, dbglevel, buffer);
setLoggingInitialized();
// Check if there were any duplicate message IDs in the default dictionary
......@@ -188,9 +189,9 @@ LoggerManager::readLocalMessageFile(const char* file) {
// Reset logging to settings passed to init()
void
LoggerManager::reset() {
LoggerManager::reset(bool buffer) {
setRootLoggerName(initRootName());
LoggerManagerImpl::reset(initSeverity(), initDebugLevel());
LoggerManagerImpl::reset(initSeverity(), initDebugLevel(), buffer);
}
} // namespace log
......
......@@ -60,9 +60,7 @@ public:
void process(T start, T finish) {
processInit();
if (start == finish) {
// empty iterator; set defaults
const LoggerSpecification spec;
processSpecification(spec);
process();
} else {
for (T i = start; i != finish; ++i) {
processSpecification(*i);
......@@ -82,6 +80,22 @@ public:
processEnd();
}
/// \brief Process 'empty' specification
///
/// This will disable any existing output options, and set
/// the logging to go to the built-in default (stdout).
/// If the logger has been initialized with buffering enabled,
/// all log messages up to now shall be printed to stdout.
///
/// This is mainly useful in scenarios where buffering is needed,
/// but it turns out there are no logging specifications to
/// handle.
void process() {
// empty iterator; set defaults
const LoggerSpecification spec;
processSpecification(spec);
}
/// \brief Run-Time Initialization
///
/// Performs run-time initialization of the logger system, in particular
......@@ -97,14 +111,22 @@ public:
/// \param dbglevel Debug severity (ignored if "severity" is not "DEBUG")
/// \param file Name of the local message file. This must be NULL if there
/// is no local message file.
/// \param buffer If true, all log messages will be buffered until one of
/// the \c process() methods is called. If false, initial logging
/// shall go to the default output (i.e. stdout)
static void init(const std::string& root,
isc::log::Severity severity = isc::log::INFO,
int dbglevel = 0, const char* file = NULL);
int dbglevel = 0, const char* file = NULL,
bool buffer = false);
/// \brief Reset logging
///
/// Resets logging to whatever was set in the call to init().
static void reset();
///
/// \param buffer If true, all log messages will be buffered until one of
/// the \c process() methods is called. If false, initial logging
/// shall go to the default output (i.e. stdout)
static void reset(bool buffer = false);
/// \brief Read local message file
///
......
......@@ -65,6 +65,9 @@ public:
// be a good idea.
for (size_t i = 0; i < stored_.size(); ++i) {
std::cout << stored_.at(i).getMessage() << std::endl;
log4cplus::Logger logger = log4cplus::Logger::getInstance(stored_.at(i).getLoggerName());
logger.log(stored_.at(i).getLogLevel(), stored_.at(i).getMessage());
}
stored_.clear();
}
......@@ -241,7 +244,9 @@ LoggerManagerImpl::createSyslogAppender(log4cplus::Logger& logger,
// One-time initialization of the log4cplus system
void
LoggerManagerImpl::init(isc::log::Severity severity, int dbglevel) {
LoggerManagerImpl::init(isc::log::Severity severity, int dbglevel,
bool buffer)
{
// Set up basic configurator. This attaches a ConsoleAppender to the
// root logger with suitable output. This is used until we we have
// actually read the logging configuration, in which case the output
......@@ -252,21 +257,23 @@ LoggerManagerImpl::init(isc::log::Severity severity, int dbglevel) {
// Add the additional debug levels
LoggerLevelImpl::init();
reset(severity, dbglevel);
reset(severity, dbglevel, buffer);
}
// Reset logging to default configuration. This closes all appenders
// and resets the root logger to output INFO messages to the console.
// It is principally used in testing.
void
LoggerManagerImpl::reset(isc::log::Severity severity, int dbglevel) {
LoggerManagerImpl::reset(isc::log::Severity severity, int dbglevel,
bool buffer)
{
// Initialize the root logger
initRootLogger(severity, dbglevel);
initRootLogger(severity, dbglevel, buffer);
}
// Initialize the root logger
void LoggerManagerImpl::initRootLogger(isc::log::Severity severity,
int dbglevel)
int dbglevel, bool buffer)
{
log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
......@@ -281,14 +288,12 @@ void LoggerManagerImpl::initRootLogger(isc::log::Severity severity,
b10root.setLogLevel(LoggerLevelImpl::convertFromBindLevel(
Level(severity, dbglevel)));
// Set the BIND 10 root to use a console logger.
//OutputOption opt;
//createConsoleAppender(b10root, opt);
createBufferAppender(b10root);
//if (!buffer_appender_) {
// buffer_appender_ = new BufferAppender(logger);
// b10_root.addAppender(buffer_appender_);
//}
if (buffer) {
createBufferAppender(b10root);
} else {
OutputOption opt;
createConsoleAppender(b10root, opt);
}
}
void LoggerManagerImpl::setConsoleAppenderLayout(
......
......@@ -88,8 +88,11 @@ public:
///
/// \param severity Severity to be associated with this logger
/// \param dbglevel Debug level associated with the root logger
/// \param buffer If true, all log messages will be buffered until one of
/// the \c process() methods is called. If false, initial logging
/// shall go to the default output (i.e. stdout)
static void init(isc::log::Severity severity = isc::log::INFO,
int dbglevel = 0);
int dbglevel = 0, bool buffer = false);
/// \brief Reset logging
///
......@@ -98,8 +101,11 @@ public:
///
/// \param severity Severity to be associated with this logger
/// \param dbglevel Debug level associated with the root logger
/// \param buffer If true, all log messages will be buffered until one of
/// the \c process() methods is called. If false, initial logging
/// shall go to the default output (i.e. stdout)
static void reset(isc::log::Severity severity = isc::log::INFO,
int dbglevel = 0);
int dbglevel = 0, bool buffer = false);
private:
/// \brief Create console appender
......@@ -142,8 +148,11 @@ private:
///
/// \param severity Severity of messages that the logger should output.
/// \param dbglevel Debug level if severity = DEBUG
/// \param buffer If true, all log messages will be buffered until one of
/// the \c process() methods is called. If false, initial logging
/// shall go to the default output (i.e. stdout)
static void initRootLogger(isc::log::Severity severity = isc::log::INFO,
int dbglevel = 0);
int dbglevel = 0, bool buffer = false);
/// \brief Set layout for console appender
///
......
......@@ -46,8 +46,8 @@ setLoggingInitialized(bool state) {
void
initLogger(const string& root, isc::log::Severity severity, int dbglevel,
const char* file) {
LoggerManager::init(root, severity, dbglevel, file);
const char* file, bool buffer) {
LoggerManager::init(root, severity, dbglevel, file, buffer);
}
} // namespace log
......
......@@ -61,9 +61,13 @@ void setLoggingInitialized(bool state = true);
/// \param severity Severity at which to log
/// \param dbglevel Debug severity (ignored if "severity" is not "DEBUG")
/// \param file Name of the local message file.
/// \param buffer If true, all log messages will be buffered until one of
/// the \c process() methods is called. If false, initial logging
/// shall go to the default output (i.e. stdout)
void initLogger(const std::string& root,
isc::log::Severity severity = isc::log::INFO,
int dbglevel = 0, const char* file = NULL);
int dbglevel = 0, const char* file = NULL,
bool buffer = false);
} // namespace log
} // namespace isc
......
......@@ -166,17 +166,24 @@ reset(PyObject*, PyObject*) {
}
PyObject*
init(PyObject*, PyObject* args) {
init(PyObject*, PyObject* args, PyObject* arg_keywords) {
const char* root;
const char* file(NULL);
const char* severity("INFO");
bool buffer = false;
int dbglevel(0);
if (!PyArg_ParseTuple(args, "s|siz", &root, &severity, &dbglevel, &file)) {
const char* keywords[] = { "name", "severity", "debuglevel", "file",
"buffer", NULL};
if (!PyArg_ParseTupleAndKeywords(args, arg_keywords, "s|sizb",
const_cast<char**>(keywords), &root,
&severity, &dbglevel, &file,
&buffer)) {
return (NULL);
}
try {
LoggerManager::init(root, getSeverity(severity), dbglevel, file);
LoggerManager::init(root, getSeverity(severity), dbglevel, file,
buffer);
}
catch (const std::exception& e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
......@@ -266,12 +273,19 @@ PyMethodDef methods[] = {
"need to call it. It returns None if the message does not exist."},
{"reset", reset, METH_NOARGS,
"Reset all logging. For testing purposes only, do not use."},
{"init", init, METH_VARARGS,
{"init", reinterpret_cast<PyCFunction>(init), METH_VARARGS | METH_KEYWORDS,
"Run-time initialization. You need to call this before you do any "
"logging, to configure the root logger name. You may also provide "
"logging severity (one of 'DEBUG', 'INFO', 'WARN', 'ERROR' or "
"'FATAL'), a debug level (integer in the range 0-99) and a file name "
"of a dictionary with message text translations."},
"Arguments:\n"
"name: root logger name\n"
"severity (optional): one of 'DEBUG', 'INFO', 'WARN', 'ERROR' or "
"'FATAL')\n"
"debuglevel (optional): a debug level (integer in the range 0-99) "
"file (optional): a file name of a dictionary with message text "
"translations\n"
"buffer (optional), boolean, when True, causes all log messages "
"to be stored internally until log_config_update is called, at "
"which pointed they shall be logged."},
{"resetUnitTestRootLogger", resetUnitTestRootLogger, METH_VARARGS,
"Resets the configuration of the root logger to that set by the "
"B10_XXX environment variables. It is aimed at unit tests, where "
......@@ -655,7 +669,7 @@ PyTypeObject logger_type = {
NULL, // tp_as_number
NULL, // tp_as_sequence
NULL, // tp_as_mapping
NULL, // tp_hash
NULL, // tp_hash
NULL, // tp_call
NULL, // tp_str
NULL, // tp_getattro
......
Supports Markdown
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