Commit 551b6283 authored by Iustin Pop's avatar Iustin Pop

Add capability to use syslog for logging

This patch adds a configure-time parameter that will set the defaults
used by all programs, and command-line parameters in the daemons that
allow overriding it.

Syslog 'yes' enables syslog in addition to file-based logging, 'only'
enables syslog and disables file-based syslog.

The log entries will be of the form:
Jan 27 08:45:04 node2 ganeti-noded[14504]: INFO 172.24.227.5:50850 PUT
/jobqueue_update HTTP/1.0 200
Jan 27 08:45:05 node2 ganeti-noded[14505]: INFO 172.24.227.5:50853 PUT
/lv_list HTTP/1.0 200

and (for a multi-threaded program):
Jan 27 08:51:48 node1 ganeti-masterd[15491]: (MainThread) INFO
ganeti-masterd daemon startup
Jan 27 08:51:49 node1 ganeti-masterd[15491]: (MainThread) INFO
Inspecting job queue
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parent 81198f6e
......@@ -446,6 +446,7 @@ lib/_autoconf.py: Makefile stamp-directories
echo "GNT_SCRIPTS = [$(foreach i,$(notdir $(gnt_scripts)),'$(i)',)]"; \
echo "PKGLIBDIR = '$(pkglibdir)'"; \
echo "DRBD_BARRIERS = $(DRBD_BARRIERS)"; \
echo "SYSLOG_USAGE = '$(SYSLOG_USAGE)'"; \
} > $@
$(REPLACE_VARS_SED): Makefile
......
......@@ -131,6 +131,33 @@ AC_ARG_ENABLE([drbd-barriers],
[DRBD_BARRIERS=True])
AC_SUBST(DRBD_BARRIERS, $DRBD_BARRIERS)
# --enable-syslog[=no/yes/only]
AC_ARG_ENABLE([syslog],
[AS_HELP_STRING([--enable-syslog],
[enable use of syslog (default: disabled), one of no/yes/only])],
[[case "$enableval" in
no)
SYSLOG=no
;;
yes)
SYSLOG=yes
;;
only)
SYSLOG=only
;;
*)
SYSLOG=
;;
esac
]],
[SYSLOG=no])
if test -z "$SYSLOG"
then
AC_MSG_ERROR([invalid value for syslog, choose one of no/yes/only])
fi
AC_SUBST(SYSLOG_USAGE, $SYSLOG)
# Check common programs
AC_PROG_INSTALL
AC_PROG_LN_S
......
......@@ -155,6 +155,13 @@ LOG_WATCHER = LOG_DIR + "watcher.log"
LOG_COMMANDS = LOG_DIR + "commands.log"
LOG_BURNIN = LOG_DIR + "burnin.log"
# one of 'no', 'yes', 'only'
SYSLOG_USAGE = _autoconf.SYSLOG_USAGE
SYSLOG_NO = "no"
SYSLOG_YES = "yes"
SYSLOG_ONLY = "only"
SYSLOG_SOCKET = "/dev/log"
OS_SEARCH_PATH = _autoconf.OS_SEARCH_PATH
EXPORT_DIR = _autoconf.EXPORT_DIR
......
......@@ -245,6 +245,12 @@ def GenericMain(daemon_name, optionparser, dirs, check_fn, exec_fn):
optionparser.add_option("-d", "--debug", dest="debug",
help="Enable some debug messages",
default=False, action="store_true")
optionparser.add_option("--syslog", dest="syslog",
help="Enable logging to syslog (except debug"
" messages); one of 'no', 'yes' or 'only' [%s]" %
constants.SYSLOG_USAGE,
default=constants.SYSLOG_USAGE,
choices=["no", "yes", "only"])
if daemon_name in constants.DAEMONS_PORTS:
# for networked daemons we also allow choosing the bind port and address.
# by default we use the port provided by utils.GetDaemonPort, and bind to
......@@ -296,7 +302,9 @@ def GenericMain(daemon_name, optionparser, dirs, check_fn, exec_fn):
utils.SetupLogging(logfile=constants.DAEMONS_LOGFILES[daemon_name],
debug=options.debug,
stderr_logging=not options.fork,
multithreaded=multithread)
multithreaded=multithread,
program=daemon_name,
syslog=options.syslog)
logging.info("%s daemon startup", daemon_name)
exec_fn(options, args)
finally:
......
......@@ -41,6 +41,7 @@ import select
import fcntl
import resource
import logging
import logging.handlers
import signal
from cStringIO import StringIO
......@@ -1762,7 +1763,7 @@ def GetDaemonPort(daemon_name):
def SetupLogging(logfile, debug=False, stderr_logging=False, program="",
multithreaded=False):
multithreaded=False, syslog=constants.SYSLOG_USAGE):
"""Configures the logging module.
@type logfile: str
......@@ -1776,17 +1777,29 @@ def SetupLogging(logfile, debug=False, stderr_logging=False, program="",
@param program: the name under which we should log messages
@type multithreaded: boolean
@param multithreaded: if True, will add the thread name to the log file
@type syslog: string
@param syslog: one of 'no', 'yes', 'only':
- if no, syslog is not used
- if yes, syslog is used (in addition to file-logging)
- if only, only syslog is used
@raise EnvironmentError: if we can't open the log file and
stderr logging is disabled
syslog/stderr logging is disabled
"""
fmt = "%(asctime)s: " + program + " pid=%(process)d"
sft = program + "[%(process)d]:"
if multithreaded:
fmt += "/%(threadName)s"
sft += " (%(threadName)s)"
if debug:
fmt += " %(module)s:%(lineno)s"
# no debug info for syslog loggers
fmt += " %(levelname)s %(message)s"
# yes, we do want the textual level, as remote syslog will probably
# lose the error level, and it's easier to grep for it
sft += " %(levelname)s %(message)s"
formatter = logging.Formatter(fmt)
sys_fmt = logging.Formatter(sft)
root_logger = logging.getLogger("")
root_logger.setLevel(logging.NOTSET)
......@@ -1805,24 +1818,34 @@ def SetupLogging(logfile, debug=False, stderr_logging=False, program="",
stderr_handler.setLevel(logging.CRITICAL)
root_logger.addHandler(stderr_handler)
# this can fail, if the logging directories are not setup or we have
# a permisssion problem; in this case, it's best to log but ignore
# the error if stderr_logging is True, and if false we re-raise the
# exception since otherwise we could run but without any logs at all
try:
logfile_handler = logging.FileHandler(logfile)
logfile_handler.setFormatter(formatter)
if debug:
logfile_handler.setLevel(logging.DEBUG)
else:
logfile_handler.setLevel(logging.INFO)
root_logger.addHandler(logfile_handler)
except EnvironmentError:
if stderr_logging:
logging.exception("Failed to enable logging to file '%s'", logfile)
else:
# we need to re-raise the exception
raise
if syslog in (constants.SYSLOG_YES, constants.SYSLOG_ONLY):
facility = logging.handlers.SysLogHandler.LOG_DAEMON
syslog_handler = logging.handlers.SysLogHandler(constants.SYSLOG_SOCKET,
facility)
syslog_handler.setFormatter(sys_fmt)
# Never enable debug over syslog
syslog_handler.setLevel(logging.INFO)
root_logger.addHandler(syslog_handler)
if syslog != constants.SYSLOG_ONLY:
# this can fail, if the logging directories are not setup or we have
# a permisssion problem; in this case, it's best to log but ignore
# the error if stderr_logging is True, and if false we re-raise the
# exception since otherwise we could run but without any logs at all
try:
logfile_handler = logging.FileHandler(logfile)
logfile_handler.setFormatter(formatter)
if debug:
logfile_handler.setLevel(logging.DEBUG)
else:
logfile_handler.setLevel(logging.INFO)
root_logger.addHandler(logfile_handler)
except EnvironmentError:
if stderr_logging or syslog == constants.SYSLOG_YES:
logging.exception("Failed to enable logging to file '%s'", logfile)
else:
# we need to re-raise the exception
raise
def IsNormAbsPath(path):
......
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