# HG changeset patch
# User emellor@ewan
# Node ID d6d1c3cbc151299053d2fafe579ac3cdd34a2195
# Parent 1ac39c7a043541cfa94655f0e9ab98d4503c29a2
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@xxxxxxxxxxxxx>
diff -r 1ac39c7a0435 -r d6d1c3cbc151 tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py Mon Oct 10 13:46:53 2005
+++ b/tools/python/xen/xend/XendLogging.py Mon Oct 10 15:15:48 2005
@@ -13,79 +13,82 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# 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)
diff -r 1ac39c7a0435 -r d6d1c3cbc151 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Mon Oct 10 13:46:53 2005
+++ b/tools/python/xen/xend/XendRoot.py Mon Oct 10 15:15:48 2005
@@ -13,6 +13,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
#============================================================================
"""Xend root class.
@@ -29,7 +30,7 @@
import string
import sys
-from XendLogging import XendLogging
+import XendLogging
from XendError import XendError
import sxp
@@ -92,7 +93,6 @@
def __init__(self):
self.config_path = None
self.config = None
- self.logging = None
self.configure()
@@ -114,84 +114,22 @@
"""
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.
- """
- 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))
+ 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.
+ """
+ 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 @@
"""
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 @@
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 @@
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.
diff -r 1ac39c7a0435 -r d6d1c3cbc151 tools/python/xen/xend/server/SrvXendLog.py
--- a/tools/python/xen/xend/server/SrvXendLog.py Mon Oct 10 13:46:53 2005
+++ b/tools/python/xen/xend/server/SrvXendLog.py Mon Oct 10 15:15:48 2005
@@ -13,11 +13,12 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# 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 @@
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
diff -r 1ac39c7a0435 -r d6d1c3cbc151 tools/python/xen/xend/server/event.py
--- a/tools/python/xen/xend/server/event.py Mon Oct 10 13:46:53 2005
+++ b/tools/python/xen/xend/server/event.py Mon Oct 10 15:15:48 2005
@@ -25,6 +25,7 @@
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 @@
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")
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|