Rewritten XendLogging to not be a singleton class, and not have methods used

from nowhere at all.

Log to a temporary file if permission is denied to log to /var/log/xend.log,
as happens when you are not root.  Fixes bug #305.

Remove all the log-related garbage from XendRoot -- just about every module
was going straight to XendLogging.log already, so there was no need to have
XendRoot replicate this functionality.

Remove XendRoot.event_handler, which hasn't been in use since the EventServer
was removed.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
This commit is contained in:
emellor@ewan committed 2005-10-10 16:15:48 +01:00
1 parent 5910d2c460
commit dc988367d8
4 files changed
+90 -152

No files matched your search

+70 -67
View File
@@ -13,79 +13,82 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
import tempfile
import types
import logging
from logging import Formatter, StreamHandler
from logging.handlers import RotatingFileHandler
import logging.handlers
class XendLogging:
KB = 1024
MB = 1024 * KB
maxBytes = 1 * MB
backupCount = 5
__all__ = [ 'log', 'init', 'getLogFilename', 'addLogStderr',
'removeLogStderr' ]
logStderrFormat = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
logFileFormat = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
dateFormat = "%Y-%m-%d %H:%M:%S"
def __init__(self, filename, level=logging.INFO, maxBytes=None, backupCount=None):
"""Initialise logging. Logs to 'filename' by default, but does not log to
stderr unless addLogStderr() is called.
"""
self.setLevel(level)
if maxBytes:
self.maxBytes = maxBytes
if backupCount:
self.backupCount = backupCount
self.initLogFile(filename)
self.initLogStderr()
def setLevel(self, level):
if isinstance(level, types.StringType):
level = logging._levelNames[level]
self.getLogger().setLevel(level)
self.level = level
def getLogger(self):
return logging.getLogger("xend")
def initLogFile(self, filename):
"""Create the file logger and add it.
"""
self.logfile = RotatingFileHandler(filename,
mode='a',
maxBytes=self.maxBytes,
backupCount=self.backupCount)
self.logfilename = filename
self.logfile.setFormatter(Formatter(self.logFileFormat, self.dateFormat))
self.getLogger().addHandler(self.logfile)
def getLogFile(self):
return self.logfile
def getLogFilename(self):
return self.logfilename
def initLogStderr(self):
"""Create the stderr logger, but don't add it.
"""
self.logstderr = StreamHandler()
self.logstderr.setFormatter(Formatter(self.logStderrFormat, self.dateFormat))
def addLogStderr(self):
"""Add logging to stderr."""
self.getLogger().addHandler(self.logstderr)
def removeLogStderr(self):
"""Remove logging to stderr."""
self.getLogger().removeHandler(self.logstderr)
def getLogStderr(self):
return self.logstderr
log = logging.getLogger("xend")
DEFAULT_MAX_BYTES = 1 << 20 # 1MB
DEFAULT_BACKUP_COUNT = 5
STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
LOGFILE_FORMAT = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
stderrHandler = logging.StreamHandler()
stderrHandler.setFormatter(logging.Formatter(STDERR_FORMAT, DATE_FORMAT))
logfilename = None
def init(filename, level=logging.INFO, maxBytes=None, backupCount=None):
"""Initialise logging. Logs to 'filename' by default, but does not log to
stderr unless addLogStderr() is called.
"""
def openFileHandler(fname):
return logging.handlers.RotatingFileHandler(fname,
mode='a',
maxBytes=maxBytes,
backupCount=backupCount)
if not maxBytes:
maxBytes = DEFAULT_MAX_BYTES
if not backupCount:
backupCount = DEFAULT_BACKUP_COUNT
# Rather unintuitively, getLevelName will get the number corresponding to
# a level name, as well as getting the name corresponding to a level
# number. setLevel seems to take the number only though, so convert if we
# are given a string.
if isinstance(level, types.StringType):
level = logging.getLevelName(level)
log.setLevel(level)
try:
fileHandler = openFileHandler(filename)
logfilename = filename
except IOError:
logfilename = tempfile.mkstemp("-xend.log")[1]
fileHandler = openFileHandler(logfilename)
fileHandler.setFormatter(logging.Formatter(LOGFILE_FORMAT, DATE_FORMAT))
log.addHandler(fileHandler)
def getLogFilename():
return logfilename
def addLogStderr():
"""Add logging to stderr."""
log.addHandler(stderrHandler)
def removeLogStderr():
"""Remove logging to stderr."""
log.removeHandler(stderrHandler)
+13 -79
View File
@@ -13,6 +13,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
"""Xend root class.
@@ -29,7 +30,7 @@ import os.path
import string
import sys
from XendLogging import XendLogging
import XendLogging
from XendError import XendError
import sxp
@@ -92,7 +93,6 @@ class XendRoot:
def __init__(self):
self.config_path = None
self.config = None
self.logging = None
self.configure()
@@ -114,84 +114,22 @@ class XendRoot:
"""
return self.components.get(name)
def _format(self, msg, args):
if args:
return str(msg) % args
else:
return str(msg)
def _log(self, mode, fmt, args):
"""Logging function that uses the logger if it exists, otherwise
logs to stderr. We use this for XendRoot log messages because
they may be logged before the logger has been configured.
Other components can safely use the logger.
def _logError(self, fmt, args):
"""Logging function to log to stderr. We use this for XendRoot log
messages because they may be logged before the logger has been
configured. Other components can safely use the logger.
"""
log = self.get_logger()
if mode not in ['warning', 'info', 'debug', 'error']:
mode = 'info'
level = mode.upper()
if log:
getattr(log, mode)(fmt, *args)
else:
print >>sys.stderr, "xend", "[%s]" % level, self._format(fmt, args)
def logDebug(self, fmt, *args):
"""Log a debug message.
@param fmt: message format
@param args: arguments
"""
self._log('debug', fmt, args)
def logInfo(self, fmt, *args):
"""Log an info message.
@param fmt: message format
@param args: arguments
"""
self._log('info', fmt, args)
def logWarning(self, fmt, *args):
"""Log a warning message.
@param fmt: message format
@param args: arguments
"""
self._log('warning', fmt, args)
def logError(self, fmt, *args):
"""Log an error message.
@param fmt: message format
@param args: arguments
"""
self._log('error', fmt, args)
def event_handler(self, event, val):
self.logInfo("EVENT> %s %s", str(event), str(val))
print >>sys.stderr, "xend [ERROR]", fmt % args
def configure(self):
self.set_config()
self.configure_logger()
def configure_logger(self):
logfile = self.get_config_value("logfile", self.logfile_default)
loglevel = self.get_config_value("loglevel", self.loglevel_default)
self.logging = XendLogging(logfile, level=loglevel)
XendLogging.init(logfile, level = loglevel)
from xen.xend.server import params
if params.XEND_DEBUG:
self.logging.addLogStderr()
def get_logging(self):
"""Get the XendLogging instance.
"""
return self.logging
def get_logger(self):
"""Get the logger.
"""
return self.logging and self.logging.getLogger()
XendLogging.addLogStderr()
def set_config(self):
"""If the config file exists, read it. If not, ignore it.
@@ -200,7 +138,6 @@ class XendRoot:
"""
self.config_path = os.getenv(self.config_var, self.config_default)
if os.path.exists(self.config_path):
#self.logInfo('Reading config file %s', self.config_path)
try:
fin = file(self.config_path, 'rb')
try:
@@ -210,10 +147,12 @@ class XendRoot:
config.insert(0, 'xend-config')
self.config = config
except Exception, ex:
self.logError('Reading config file %s: %s', self.config_path, str(ex))
self._logError('Reading config file %s: %s',
self.config_path, str(ex))
raise
else:
self.logError('Config file does not exist: %s', self.config_path)
self._logError('Config file does not exist: %s',
self.config_path)
self.config = ['xend-config']
def get_config(self, name=None):
@@ -339,11 +278,6 @@ def instance():
inst = XendRoot()
return inst
def logger():
"""Get the logger.
"""
return instance().get_logger()
def add_component(name, val):
"""Register a component with XendRoot.
This is used to work-round import cycles.
+4 -3
View File
@@ -13,11 +13,12 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
from xen.web import static
from xen.xend import XendRoot
from xen.xend import XendLogging
from xen.web.SrvDir import SrvDir
@@ -27,8 +28,8 @@ class SrvXendLog(SrvDir):
def __init__(self):
SrvDir.__init__(self)
logging = XendRoot.instance().get_logging()
self.logfile = static.File(logging.getLogFilename(), defaultType="text/plain")
self.logfile = static.File(XendLogging.getLogFilename(),
defaultType="text/plain")
self.logfile.type = "text/plain"
self.logfile.encoding = None
+3 -3
View File
@@ -25,6 +25,7 @@ from xen.xend import scheduler
from xen.xend import sxp
from xen.xend import PrettyPrint
from xen.xend.XendError import XendError
from xen.xend import XendLogging
from xen.xend import XendRoot
@@ -146,11 +147,10 @@ class EventProtocol(protocol.Protocol):
def op_log_stderr(self, _, v):
mode = v[1]
logging = xroot.get_logging()
if mode == 'on':
logging.addLogStderr()
XendLogging.addLogStderr()
else:
logging.removeLogStderr()
XendLogging.removeLogStderr()
def op_domain_ls(self, _1, _2):
xd = xroot.get_component("xen.xend.XendDomain")
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.