Browse Source

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

Jelte Jansen 12 years ago
parent
commit
9c4e97e7f8

+ 4 - 2
src/bin/auth/main.cc

@@ -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;

+ 14 - 14
src/bin/bind10/bind10_src.py.in

@@ -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.

+ 1 - 1
src/bin/cfgmgr/b10-cfgmgr.py.in

@@ -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 *
 

+ 1 - 1
src/bin/cmdctl/cmdctl.py.in

@@ -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

+ 1 - 1
src/bin/ddns/ddns.py.in

@@ -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
 

+ 1 - 1
src/bin/dhcp4/main.cc

@@ -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")

+ 2 - 2
src/bin/dhcp6/main.cc

@@ -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 {

+ 6 - 6
src/bin/resolver/main.cc

@@ -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);

+ 2 - 2
src/bin/stats/stats.py.in

@@ -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:

+ 2 - 2
src/bin/stats/stats_httpd.py.in

@@ -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:

+ 1 - 1
src/bin/xfrin/xfrin.py.in

@@ -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

+ 1 - 1
src/bin/xfrout/xfrout.py.in

@@ -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

+ 1 - 1
src/bin/zonemgr/zonemgr.py.in

@@ -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

+ 6 - 5
src/lib/log/logger_manager.cc

@@ -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

+ 27 - 5
src/lib/log/logger_manager.h

@@ -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
     ///

+ 18 - 13
src/lib/log/logger_manager_impl.cc

@@ -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(

+ 12 - 3
src/lib/log/logger_manager_impl.h

@@ -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
     ///

+ 2 - 2
src/lib/log/logger_support.cc

@@ -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

+ 5 - 1
src/lib/log/logger_support.h

@@ -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

+ 22 - 8
src/lib/python/isc/log/log.cc

@@ -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