Issue #7086: Added TCP support to SysLogHandler and tidied up some anachronisms in the code.
This commit is contained in:
parent
6e3dbbdf39
commit
1c77b7f84c
|
@ -764,12 +764,12 @@ functions.
|
||||||
|
|
||||||
Does basic configuration for the logging system by creating a
|
Does basic configuration for the logging system by creating a
|
||||||
:class:`StreamHandler` with a default :class:`Formatter` and adding it to the
|
:class:`StreamHandler` with a default :class:`Formatter` and adding it to the
|
||||||
root logger. The function does nothing if any handlers have been defined for
|
root logger. The functions :func:`debug`, :func:`info`, :func:`warning`,
|
||||||
the root logger. The functions :func:`debug`, :func:`info`, :func:`warning`,
|
|
||||||
:func:`error` and :func:`critical` will call :func:`basicConfig` automatically
|
:func:`error` and :func:`critical` will call :func:`basicConfig` automatically
|
||||||
if no handlers are defined for the root logger.
|
if no handlers are defined for the root logger.
|
||||||
|
|
||||||
This function does nothing if the root logger already has handlers configured.
|
This function does nothing if the root logger already has handlers
|
||||||
|
configured for it.
|
||||||
|
|
||||||
.. versionchanged:: 2.4
|
.. versionchanged:: 2.4
|
||||||
Formerly, :func:`basicConfig` did not take any keyword arguments.
|
Formerly, :func:`basicConfig` did not take any keyword arguments.
|
||||||
|
@ -2008,16 +2008,22 @@ The :class:`SysLogHandler` class, located in the :mod:`logging.handlers` module,
|
||||||
supports sending logging messages to a remote or local Unix syslog.
|
supports sending logging messages to a remote or local Unix syslog.
|
||||||
|
|
||||||
|
|
||||||
.. class:: SysLogHandler([address[, facility]])
|
.. class:: SysLogHandler([address[, facility[, socktype]]])
|
||||||
|
|
||||||
Returns a new instance of the :class:`SysLogHandler` class intended to
|
Returns a new instance of the :class:`SysLogHandler` class intended to
|
||||||
communicate with a remote Unix machine whose address is given by *address* in
|
communicate with a remote Unix machine whose address is given by *address* in
|
||||||
the form of a ``(host, port)`` tuple. If *address* is not specified,
|
the form of a ``(host, port)`` tuple. If *address* is not specified,
|
||||||
``('localhost', 514)`` is used. The address is used to open a UDP socket. An
|
``('localhost', 514)`` is used. The address is used to open a socket. An
|
||||||
alternative to providing a ``(host, port)`` tuple is providing an address as a
|
alternative to providing a ``(host, port)`` tuple is providing an address as a
|
||||||
string, for example "/dev/log". In this case, a Unix domain socket is used to
|
string, for example "/dev/log". In this case, a Unix domain socket is used to
|
||||||
send the message to the syslog. If *facility* is not specified,
|
send the message to the syslog. If *facility* is not specified,
|
||||||
:const:`LOG_USER` is used.
|
:const:`LOG_USER` is used. The type of socket opened depends on the
|
||||||
|
*socktype* argument, which defaults to :const:`socket.SOCK_DGRAM` and thus
|
||||||
|
opens a UDP socket. To open a TCP socket (for use with the newer syslog
|
||||||
|
daemons such as rsyslog), specify a value of :const:`socket.SOCK_STREAM`.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.7
|
||||||
|
*socktype* was added.
|
||||||
|
|
||||||
|
|
||||||
.. method:: close()
|
.. method:: close()
|
||||||
|
|
|
@ -23,6 +23,8 @@ Copyright (C) 2001-2009 Vinay Sajip. All Rights Reserved.
|
||||||
To use, simply 'import logging' and log away!
|
To use, simply 'import logging' and log away!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys, os, time, cStringIO, traceback, warnings
|
||||||
|
|
||||||
__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
|
__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
|
||||||
'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
|
'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
|
||||||
'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
|
'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
|
||||||
|
@ -31,8 +33,6 @@ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
|
||||||
'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
|
'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
|
||||||
'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning']
|
'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning']
|
||||||
|
|
||||||
import sys, os, types, time, string, cStringIO, traceback, warnings
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import codecs
|
import codecs
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -46,12 +46,17 @@ except ImportError:
|
||||||
|
|
||||||
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
|
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
|
||||||
__status__ = "production"
|
__status__ = "production"
|
||||||
__version__ = "0.5.0.8"
|
__version__ = "0.5.0.9"
|
||||||
__date__ = "27 April 2009"
|
__date__ = "09 October 2009"
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Miscellaneous module data
|
# Miscellaneous module data
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
try:
|
||||||
|
unicode
|
||||||
|
_unicode = True
|
||||||
|
except NameError:
|
||||||
|
_unicode = False
|
||||||
|
|
||||||
#
|
#
|
||||||
# _srcfile is used when walking the stack to check when we've got the first
|
# _srcfile is used when walking the stack to check when we've got the first
|
||||||
|
@ -59,7 +64,7 @@ __date__ = "27 April 2009"
|
||||||
#
|
#
|
||||||
if hasattr(sys, 'frozen'): #support for py2exe
|
if hasattr(sys, 'frozen'): #support for py2exe
|
||||||
_srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
|
_srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
|
||||||
elif string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
|
elif __file__[-4:].lower() in ['.pyc', '.pyo']:
|
||||||
_srcfile = __file__[:-4] + '.py'
|
_srcfile = __file__[:-4] + '.py'
|
||||||
else:
|
else:
|
||||||
_srcfile = __file__
|
_srcfile = __file__
|
||||||
|
@ -71,7 +76,7 @@ def currentframe():
|
||||||
try:
|
try:
|
||||||
raise Exception
|
raise Exception
|
||||||
except:
|
except:
|
||||||
return sys.exc_traceback.tb_frame.f_back
|
return sys.exc_info()[2].tb_frame.f_back
|
||||||
|
|
||||||
if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
|
if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
|
||||||
# done filching
|
# done filching
|
||||||
|
@ -255,9 +260,7 @@ class LogRecord:
|
||||||
# 'Value is %d' instead of 'Value is 0'.
|
# 'Value is %d' instead of 'Value is 0'.
|
||||||
# For the use case of passing a dictionary, this should not be a
|
# For the use case of passing a dictionary, this should not be a
|
||||||
# problem.
|
# problem.
|
||||||
if args and len(args) == 1 and (
|
if args and len(args) == 1 and isinstance(args[0], dict) and args[0]:
|
||||||
type(args[0]) == types.DictType
|
|
||||||
) and args[0]:
|
|
||||||
args = args[0]
|
args = args[0]
|
||||||
self.args = args
|
self.args = args
|
||||||
self.levelname = getLevelName(level)
|
self.levelname = getLevelName(level)
|
||||||
|
@ -306,11 +309,11 @@ class LogRecord:
|
||||||
Return the message for this LogRecord after merging any user-supplied
|
Return the message for this LogRecord after merging any user-supplied
|
||||||
arguments with the message.
|
arguments with the message.
|
||||||
"""
|
"""
|
||||||
if not hasattr(types, "UnicodeType"): #if no unicode support...
|
if not _unicode: #if no unicode support...
|
||||||
msg = str(self.msg)
|
msg = str(self.msg)
|
||||||
else:
|
else:
|
||||||
msg = self.msg
|
msg = self.msg
|
||||||
if type(msg) not in (types.UnicodeType, types.StringType):
|
if not isinstance(msg, basestring):
|
||||||
try:
|
try:
|
||||||
msg = str(self.msg)
|
msg = str(self.msg)
|
||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
|
@ -447,7 +450,7 @@ class Formatter:
|
||||||
formatException() and appended to the message.
|
formatException() and appended to the message.
|
||||||
"""
|
"""
|
||||||
record.message = record.getMessage()
|
record.message = record.getMessage()
|
||||||
if string.find(self._fmt,"%(asctime)") >= 0:
|
if self._fmt.find("%(asctime)") >= 0:
|
||||||
record.asctime = self.formatTime(record, self.datefmt)
|
record.asctime = self.formatTime(record, self.datefmt)
|
||||||
s = self._fmt % record.__dict__
|
s = self._fmt % record.__dict__
|
||||||
if record.exc_info:
|
if record.exc_info:
|
||||||
|
@ -541,7 +544,7 @@ class Filter:
|
||||||
return 1
|
return 1
|
||||||
elif self.name == record.name:
|
elif self.name == record.name:
|
||||||
return 1
|
return 1
|
||||||
elif string.find(record.name, self.name, 0, self.nlen) != 0:
|
elif record.name.find(self.name, 0, self.nlen) != 0:
|
||||||
return 0
|
return 0
|
||||||
return (record.name[self.nlen] == ".")
|
return (record.name[self.nlen] == ".")
|
||||||
|
|
||||||
|
@ -667,8 +670,8 @@ class Handler(Filterer):
|
||||||
This version is intended to be implemented by subclasses and so
|
This version is intended to be implemented by subclasses and so
|
||||||
raises a NotImplementedError.
|
raises a NotImplementedError.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError, 'emit must be implemented '\
|
raise NotImplementedError('emit must be implemented '
|
||||||
'by Handler subclasses'
|
'by Handler subclasses')
|
||||||
|
|
||||||
def handle(self, record):
|
def handle(self, record):
|
||||||
"""
|
"""
|
||||||
|
@ -781,7 +784,7 @@ class StreamHandler(Handler):
|
||||||
msg = self.format(record)
|
msg = self.format(record)
|
||||||
stream = self.stream
|
stream = self.stream
|
||||||
fs = "%s\n"
|
fs = "%s\n"
|
||||||
if not hasattr(types, "UnicodeType"): #if no unicode support...
|
if not _unicode: #if no unicode support...
|
||||||
stream.write(fs % msg)
|
stream.write(fs % msg)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
@ -903,8 +906,8 @@ def setLoggerClass(klass):
|
||||||
"""
|
"""
|
||||||
if klass != Logger:
|
if klass != Logger:
|
||||||
if not issubclass(klass, Logger):
|
if not issubclass(klass, Logger):
|
||||||
raise TypeError, "logger not derived from logging.Logger: " + \
|
raise TypeError("logger not derived from logging.Logger: "
|
||||||
klass.__name__
|
+ klass.__name__)
|
||||||
global _loggerClass
|
global _loggerClass
|
||||||
_loggerClass = klass
|
_loggerClass = klass
|
||||||
|
|
||||||
|
@ -967,7 +970,7 @@ class Manager:
|
||||||
from the specified logger to the root of the logger hierarchy.
|
from the specified logger to the root of the logger hierarchy.
|
||||||
"""
|
"""
|
||||||
name = alogger.name
|
name = alogger.name
|
||||||
i = string.rfind(name, ".")
|
i = name.rfind(".")
|
||||||
rv = None
|
rv = None
|
||||||
while (i > 0) and not rv:
|
while (i > 0) and not rv:
|
||||||
substr = name[:i]
|
substr = name[:i]
|
||||||
|
@ -980,7 +983,7 @@ class Manager:
|
||||||
else:
|
else:
|
||||||
assert isinstance(obj, PlaceHolder)
|
assert isinstance(obj, PlaceHolder)
|
||||||
obj.append(alogger)
|
obj.append(alogger)
|
||||||
i = string.rfind(name, ".", 0, i - 1)
|
i = name.rfind(".", 0, i - 1)
|
||||||
if not rv:
|
if not rv:
|
||||||
rv = self.root
|
rv = self.root
|
||||||
alogger.parent = rv
|
alogger.parent = rv
|
||||||
|
@ -994,7 +997,6 @@ class Manager:
|
||||||
namelen = len(name)
|
namelen = len(name)
|
||||||
for c in ph.loggerMap.keys():
|
for c in ph.loggerMap.keys():
|
||||||
#The if means ... if not c.parent.name.startswith(nm)
|
#The if means ... if not c.parent.name.startswith(nm)
|
||||||
#if string.find(c.parent.name, nm) <> 0:
|
|
||||||
if c.parent.name[:namelen] != name:
|
if c.parent.name[:namelen] != name:
|
||||||
alogger.parent = c.parent
|
alogger.parent = c.parent
|
||||||
c.parent = alogger
|
c.parent = alogger
|
||||||
|
@ -1090,7 +1092,7 @@ class Logger(Filterer):
|
||||||
"""
|
"""
|
||||||
Convenience method for logging an ERROR with exception information.
|
Convenience method for logging an ERROR with exception information.
|
||||||
"""
|
"""
|
||||||
self.error(*((msg,) + args), **{'exc_info': 1})
|
self.error(msg, exc_info=1, *args)
|
||||||
|
|
||||||
def critical(self, msg, *args, **kwargs):
|
def critical(self, msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -1115,9 +1117,9 @@ class Logger(Filterer):
|
||||||
|
|
||||||
logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
|
logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
|
||||||
"""
|
"""
|
||||||
if type(level) != types.IntType:
|
if not isinstance(level, int):
|
||||||
if raiseExceptions:
|
if raiseExceptions:
|
||||||
raise TypeError, "level must be an integer"
|
raise TypeError("level must be an integer")
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
if self.isEnabledFor(level):
|
if self.isEnabledFor(level):
|
||||||
|
@ -1173,7 +1175,7 @@ class Logger(Filterer):
|
||||||
else:
|
else:
|
||||||
fn, lno, func = "(unknown file)", 0, "(unknown function)"
|
fn, lno, func = "(unknown file)", 0, "(unknown function)"
|
||||||
if exc_info:
|
if exc_info:
|
||||||
if type(exc_info) != types.TupleType:
|
if not isinstance(exc_info, tuple):
|
||||||
exc_info = sys.exc_info()
|
exc_info = sys.exc_info()
|
||||||
record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
|
record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
|
||||||
self.handle(record)
|
self.handle(record)
|
||||||
|
@ -1449,7 +1451,7 @@ def critical(msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
basicConfig()
|
basicConfig()
|
||||||
root.critical(*((msg,)+args), **kwargs)
|
root.critical(msg, *args, **kwargs)
|
||||||
|
|
||||||
fatal = critical
|
fatal = critical
|
||||||
|
|
||||||
|
@ -1459,14 +1461,14 @@ def error(msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
basicConfig()
|
basicConfig()
|
||||||
root.error(*((msg,)+args), **kwargs)
|
root.error(msg, *args, **kwargs)
|
||||||
|
|
||||||
def exception(msg, *args):
|
def exception(msg, *args):
|
||||||
"""
|
"""
|
||||||
Log a message with severity 'ERROR' on the root logger,
|
Log a message with severity 'ERROR' on the root logger,
|
||||||
with exception information.
|
with exception information.
|
||||||
"""
|
"""
|
||||||
error(*((msg,)+args), **{'exc_info': 1})
|
error(msg, exc_info=1, *args)
|
||||||
|
|
||||||
def warning(msg, *args, **kwargs):
|
def warning(msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -1474,7 +1476,7 @@ def warning(msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
basicConfig()
|
basicConfig()
|
||||||
root.warning(*((msg,)+args), **kwargs)
|
root.warning(msg, *args, **kwargs)
|
||||||
|
|
||||||
warn = warning
|
warn = warning
|
||||||
|
|
||||||
|
@ -1484,7 +1486,7 @@ def info(msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
basicConfig()
|
basicConfig()
|
||||||
root.info(*((msg,)+args), **kwargs)
|
root.info(msg, *args, **kwargs)
|
||||||
|
|
||||||
def debug(msg, *args, **kwargs):
|
def debug(msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -1492,7 +1494,7 @@ def debug(msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
basicConfig()
|
basicConfig()
|
||||||
root.debug(*((msg,)+args), **kwargs)
|
root.debug(msg, *args, **kwargs)
|
||||||
|
|
||||||
def log(level, msg, *args, **kwargs):
|
def log(level, msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -1500,7 +1502,7 @@ def log(level, msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
basicConfig()
|
basicConfig()
|
||||||
root.log(*((level, msg)+args), **kwargs)
|
root.log(level, msg, *args, **kwargs)
|
||||||
|
|
||||||
def disable(level):
|
def disable(level):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -19,15 +19,12 @@ Configuration functions for the logging package for Python. The core package
|
||||||
is based on PEP 282 and comments thereto in comp.lang.python, and influenced
|
is based on PEP 282 and comments thereto in comp.lang.python, and influenced
|
||||||
by Apache's log4j system.
|
by Apache's log4j system.
|
||||||
|
|
||||||
Should work under Python versions >= 1.5.2, except that source line
|
Copyright (C) 2001-2009 Vinay Sajip. All Rights Reserved.
|
||||||
information is not available unless 'sys._getframe()' is.
|
|
||||||
|
|
||||||
Copyright (C) 2001-2008 Vinay Sajip. All Rights Reserved.
|
|
||||||
|
|
||||||
To use, simply 'import logging' and log away!
|
To use, simply 'import logging' and log away!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, logging, logging.handlers, string, socket, struct, os, traceback, types
|
import sys, logging, logging.handlers, socket, struct, os, traceback
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import thread
|
import thread
|
||||||
|
@ -52,7 +49,7 @@ else:
|
||||||
# _listener holds the server object doing the listening
|
# _listener holds the server object doing the listening
|
||||||
_listener = None
|
_listener = None
|
||||||
|
|
||||||
def fileConfig(fname, defaults=None, disable_existing_loggers=1):
|
def fileConfig(fname, defaults=None, disable_existing_loggers=True):
|
||||||
"""
|
"""
|
||||||
Read the logging configuration from a ConfigParser-format file.
|
Read the logging configuration from a ConfigParser-format file.
|
||||||
|
|
||||||
|
@ -89,7 +86,7 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=1):
|
||||||
|
|
||||||
def _resolve(name):
|
def _resolve(name):
|
||||||
"""Resolve a dotted name to a global object."""
|
"""Resolve a dotted name to a global object."""
|
||||||
name = string.split(name, '.')
|
name = name.split('.')
|
||||||
used = name.pop(0)
|
used = name.pop(0)
|
||||||
found = __import__(used)
|
found = __import__(used)
|
||||||
for n in name:
|
for n in name:
|
||||||
|
@ -102,14 +99,14 @@ def _resolve(name):
|
||||||
return found
|
return found
|
||||||
|
|
||||||
def _strip_spaces(alist):
|
def _strip_spaces(alist):
|
||||||
return map(lambda x: string.strip(x), alist)
|
return map(lambda x: x.strip(), alist)
|
||||||
|
|
||||||
def _create_formatters(cp):
|
def _create_formatters(cp):
|
||||||
"""Create and return formatters"""
|
"""Create and return formatters"""
|
||||||
flist = cp.get("formatters", "keys")
|
flist = cp.get("formatters", "keys")
|
||||||
if not len(flist):
|
if not len(flist):
|
||||||
return {}
|
return {}
|
||||||
flist = string.split(flist, ",")
|
flist = flist.split(",")
|
||||||
flist = _strip_spaces(flist)
|
flist = _strip_spaces(flist)
|
||||||
formatters = {}
|
formatters = {}
|
||||||
for form in flist:
|
for form in flist:
|
||||||
|
@ -138,7 +135,7 @@ def _install_handlers(cp, formatters):
|
||||||
hlist = cp.get("handlers", "keys")
|
hlist = cp.get("handlers", "keys")
|
||||||
if not len(hlist):
|
if not len(hlist):
|
||||||
return {}
|
return {}
|
||||||
hlist = string.split(hlist, ",")
|
hlist = hlist.split(",")
|
||||||
hlist = _strip_spaces(hlist)
|
hlist = _strip_spaces(hlist)
|
||||||
handlers = {}
|
handlers = {}
|
||||||
fixups = [] #for inter-handler references
|
fixups = [] #for inter-handler references
|
||||||
|
@ -181,8 +178,8 @@ def _install_loggers(cp, handlers, disable_existing_loggers):
|
||||||
|
|
||||||
# configure the root first
|
# configure the root first
|
||||||
llist = cp.get("loggers", "keys")
|
llist = cp.get("loggers", "keys")
|
||||||
llist = string.split(llist, ",")
|
llist = llist.split(",")
|
||||||
llist = map(lambda x: string.strip(x), llist)
|
llist = list(map(lambda x: x.strip(), llist))
|
||||||
llist.remove("root")
|
llist.remove("root")
|
||||||
sectname = "logger_root"
|
sectname = "logger_root"
|
||||||
root = logging.root
|
root = logging.root
|
||||||
|
@ -195,7 +192,7 @@ def _install_loggers(cp, handlers, disable_existing_loggers):
|
||||||
root.removeHandler(h)
|
root.removeHandler(h)
|
||||||
hlist = cp.get(sectname, "handlers")
|
hlist = cp.get(sectname, "handlers")
|
||||||
if len(hlist):
|
if len(hlist):
|
||||||
hlist = string.split(hlist, ",")
|
hlist = hlist.split(",")
|
||||||
hlist = _strip_spaces(hlist)
|
hlist = _strip_spaces(hlist)
|
||||||
for hand in hlist:
|
for hand in hlist:
|
||||||
log.addHandler(handlers[hand])
|
log.addHandler(handlers[hand])
|
||||||
|
@ -209,7 +206,7 @@ def _install_loggers(cp, handlers, disable_existing_loggers):
|
||||||
#what's left in existing is the set of loggers
|
#what's left in existing is the set of loggers
|
||||||
#which were in the previous configuration but
|
#which were in the previous configuration but
|
||||||
#which are not in the new configuration.
|
#which are not in the new configuration.
|
||||||
existing = root.manager.loggerDict.keys()
|
existing = list(root.manager.loggerDict.keys())
|
||||||
#The list needs to be sorted so that we can
|
#The list needs to be sorted so that we can
|
||||||
#avoid disabling child loggers of explicitly
|
#avoid disabling child loggers of explicitly
|
||||||
#named loggers. With a sorted list it is easier
|
#named loggers. With a sorted list it is easier
|
||||||
|
@ -247,7 +244,7 @@ def _install_loggers(cp, handlers, disable_existing_loggers):
|
||||||
logger.disabled = 0
|
logger.disabled = 0
|
||||||
hlist = cp.get(sectname, "handlers")
|
hlist = cp.get(sectname, "handlers")
|
||||||
if len(hlist):
|
if len(hlist):
|
||||||
hlist = string.split(hlist, ",")
|
hlist = hlist.split(",")
|
||||||
hlist = _strip_spaces(hlist)
|
hlist = _strip_spaces(hlist)
|
||||||
for hand in hlist:
|
for hand in hlist:
|
||||||
logger.addHandler(handlers[hand])
|
logger.addHandler(handlers[hand])
|
||||||
|
@ -278,7 +275,7 @@ def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
|
||||||
stopListening().
|
stopListening().
|
||||||
"""
|
"""
|
||||||
if not thread:
|
if not thread:
|
||||||
raise NotImplementedError, "listen() needs threading to work"
|
raise NotImplementedError("listen() needs threading to work")
|
||||||
|
|
||||||
class ConfigStreamHandler(StreamRequestHandler):
|
class ConfigStreamHandler(StreamRequestHandler):
|
||||||
"""
|
"""
|
||||||
|
@ -321,7 +318,7 @@ def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
os.remove(file)
|
os.remove(file)
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
if type(e.args) != types.TupleType:
|
if not isinstance(e.args, tuple):
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
errcode = e.args[0]
|
errcode = e.args[0]
|
||||||
|
|
|
@ -24,7 +24,7 @@ Copyright (C) 2001-2009 Vinay Sajip. All Rights Reserved.
|
||||||
To use, simply 'import logging.handlers' and log away!
|
To use, simply 'import logging.handlers' and log away!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging, socket, types, os, string, cPickle, struct, time, re
|
import logging, socket, os, cPickle, struct, time, re
|
||||||
from stat import ST_DEV, ST_INO
|
from stat import ST_DEV, ST_INO
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -41,6 +41,7 @@ DEFAULT_UDP_LOGGING_PORT = 9021
|
||||||
DEFAULT_HTTP_LOGGING_PORT = 9022
|
DEFAULT_HTTP_LOGGING_PORT = 9022
|
||||||
DEFAULT_SOAP_LOGGING_PORT = 9023
|
DEFAULT_SOAP_LOGGING_PORT = 9023
|
||||||
SYSLOG_UDP_PORT = 514
|
SYSLOG_UDP_PORT = 514
|
||||||
|
SYSLOG_TCP_PORT = 514
|
||||||
|
|
||||||
_MIDNIGHT = 24 * 60 * 60 # number of seconds in a day
|
_MIDNIGHT = 24 * 60 * 60 # number of seconds in a day
|
||||||
|
|
||||||
|
@ -155,9 +156,9 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||||
If backupCount is > 0, when rollover is done, no more than backupCount
|
If backupCount is > 0, when rollover is done, no more than backupCount
|
||||||
files are kept - the oldest ones are deleted.
|
files are kept - the oldest ones are deleted.
|
||||||
"""
|
"""
|
||||||
def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=0, utc=0):
|
def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False):
|
||||||
BaseRotatingHandler.__init__(self, filename, 'a', encoding, delay)
|
BaseRotatingHandler.__init__(self, filename, 'a', encoding, delay)
|
||||||
self.when = string.upper(when)
|
self.when = when.upper()
|
||||||
self.backupCount = backupCount
|
self.backupCount = backupCount
|
||||||
self.utc = utc
|
self.utc = utc
|
||||||
# Calculate the real rollover interval, which is just the number of
|
# Calculate the real rollover interval, which is just the number of
|
||||||
|
@ -204,8 +205,6 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||||
self.interval = self.interval * interval # multiply by units requested
|
self.interval = self.interval * interval # multiply by units requested
|
||||||
self.rolloverAt = self.computeRollover(int(time.time()))
|
self.rolloverAt = self.computeRollover(int(time.time()))
|
||||||
|
|
||||||
#print "Will rollover at %d, %d seconds from now" % (self.rolloverAt, self.rolloverAt - currentTime)
|
|
||||||
|
|
||||||
def computeRollover(self, currentTime):
|
def computeRollover(self, currentTime):
|
||||||
"""
|
"""
|
||||||
Work out the rollover time based on the specified time.
|
Work out the rollover time based on the specified time.
|
||||||
|
@ -692,7 +691,8 @@ class SysLogHandler(logging.Handler):
|
||||||
"CRITICAL" : "critical"
|
"CRITICAL" : "critical"
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER):
|
def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
|
||||||
|
facility=LOG_USER, socktype=socket.SOCK_DGRAM):
|
||||||
"""
|
"""
|
||||||
Initialize a handler.
|
Initialize a handler.
|
||||||
|
|
||||||
|
@ -704,13 +704,16 @@ class SysLogHandler(logging.Handler):
|
||||||
|
|
||||||
self.address = address
|
self.address = address
|
||||||
self.facility = facility
|
self.facility = facility
|
||||||
if type(address) == types.StringType:
|
self.socktype = socktype
|
||||||
|
|
||||||
|
if isinstance(address, basestring):
|
||||||
self.unixsocket = 1
|
self.unixsocket = 1
|
||||||
self._connect_unixsocket(address)
|
self._connect_unixsocket(address)
|
||||||
else:
|
else:
|
||||||
self.unixsocket = 0
|
self.unixsocket = 0
|
||||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
self.socket = socket.socket(socket.AF_INET, socktype)
|
||||||
|
if socktype == socket.SOCK_STREAM:
|
||||||
|
self.socket.connect(address)
|
||||||
self.formatter = None
|
self.formatter = None
|
||||||
|
|
||||||
def _connect_unixsocket(self, address):
|
def _connect_unixsocket(self, address):
|
||||||
|
@ -736,9 +739,9 @@ class SysLogHandler(logging.Handler):
|
||||||
priority_names mapping dictionaries are used to convert them to
|
priority_names mapping dictionaries are used to convert them to
|
||||||
integers.
|
integers.
|
||||||
"""
|
"""
|
||||||
if type(facility) == types.StringType:
|
if isinstance(facility, basestring):
|
||||||
facility = self.facility_names[facility]
|
facility = self.facility_names[facility]
|
||||||
if type(priority) == types.StringType:
|
if isinstance(priority, basestring):
|
||||||
priority = self.priority_names[priority]
|
priority = self.priority_names[priority]
|
||||||
return (facility << 3) | priority
|
return (facility << 3) | priority
|
||||||
|
|
||||||
|
@ -783,8 +786,10 @@ class SysLogHandler(logging.Handler):
|
||||||
except socket.error:
|
except socket.error:
|
||||||
self._connect_unixsocket(self.address)
|
self._connect_unixsocket(self.address)
|
||||||
self.socket.send(msg)
|
self.socket.send(msg)
|
||||||
else:
|
elif self.socktype == socket.SOCK_DGRAM:
|
||||||
self.socket.sendto(msg, self.address)
|
self.socket.sendto(msg, self.address)
|
||||||
|
else:
|
||||||
|
self.socket.sendall(msg)
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except (KeyboardInterrupt, SystemExit):
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
|
@ -805,16 +810,16 @@ class SMTPHandler(logging.Handler):
|
||||||
for the credentials argument.
|
for the credentials argument.
|
||||||
"""
|
"""
|
||||||
logging.Handler.__init__(self)
|
logging.Handler.__init__(self)
|
||||||
if type(mailhost) == types.TupleType:
|
if isinstance(mailhost, tuple):
|
||||||
self.mailhost, self.mailport = mailhost
|
self.mailhost, self.mailport = mailhost
|
||||||
else:
|
else:
|
||||||
self.mailhost, self.mailport = mailhost, None
|
self.mailhost, self.mailport = mailhost, None
|
||||||
if type(credentials) == types.TupleType:
|
if isinstance(credentials, tuple):
|
||||||
self.username, self.password = credentials
|
self.username, self.password = credentials
|
||||||
else:
|
else:
|
||||||
self.username = None
|
self.username = None
|
||||||
self.fromaddr = fromaddr
|
self.fromaddr = fromaddr
|
||||||
if type(toaddrs) == types.StringType:
|
if isinstance(toaddrs, basestring):
|
||||||
toaddrs = [toaddrs]
|
toaddrs = [toaddrs]
|
||||||
self.toaddrs = toaddrs
|
self.toaddrs = toaddrs
|
||||||
self.subject = subject
|
self.subject = subject
|
||||||
|
@ -865,7 +870,7 @@ class SMTPHandler(logging.Handler):
|
||||||
msg = self.format(record)
|
msg = self.format(record)
|
||||||
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
|
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
|
||||||
self.fromaddr,
|
self.fromaddr,
|
||||||
string.join(self.toaddrs, ","),
|
",".join(self.toaddrs),
|
||||||
self.getSubject(record),
|
self.getSubject(record),
|
||||||
formatdate(), msg)
|
formatdate(), msg)
|
||||||
if self.username:
|
if self.username:
|
||||||
|
@ -909,8 +914,8 @@ class NTEventLogHandler(logging.Handler):
|
||||||
logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE,
|
logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE,
|
||||||
}
|
}
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print "The Python Win32 extensions for NT (service, event "\
|
print("The Python Win32 extensions for NT (service, event "\
|
||||||
"logging) appear not to be available."
|
"logging) appear not to be available.")
|
||||||
self._welu = None
|
self._welu = None
|
||||||
|
|
||||||
def getMessageID(self, record):
|
def getMessageID(self, record):
|
||||||
|
@ -988,9 +993,9 @@ class HTTPHandler(logging.Handler):
|
||||||
("GET" or "POST")
|
("GET" or "POST")
|
||||||
"""
|
"""
|
||||||
logging.Handler.__init__(self)
|
logging.Handler.__init__(self)
|
||||||
method = string.upper(method)
|
method = method.upper()
|
||||||
if method not in ["GET", "POST"]:
|
if method not in ["GET", "POST"]:
|
||||||
raise ValueError, "method must be GET or POST"
|
raise ValueError("method must be GET or POST")
|
||||||
self.host = host
|
self.host = host
|
||||||
self.url = url
|
self.url = url
|
||||||
self.method = method
|
self.method = method
|
||||||
|
@ -1016,7 +1021,7 @@ class HTTPHandler(logging.Handler):
|
||||||
url = self.url
|
url = self.url
|
||||||
data = urllib.urlencode(self.mapLogRecord(record))
|
data = urllib.urlencode(self.mapLogRecord(record))
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
if (string.find(url, '?') >= 0):
|
if (url.find('?') >= 0):
|
||||||
sep = '&'
|
sep = '&'
|
||||||
else:
|
else:
|
||||||
sep = '?'
|
sep = '?'
|
||||||
|
@ -1024,7 +1029,7 @@ class HTTPHandler(logging.Handler):
|
||||||
h.putrequest(self.method, url)
|
h.putrequest(self.method, url)
|
||||||
# support multiple hosts on one IP address...
|
# support multiple hosts on one IP address...
|
||||||
# need to strip optional :port from host, if present
|
# need to strip optional :port from host, if present
|
||||||
i = string.find(host, ":")
|
i = host.find(":")
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
host = host[:i]
|
host = host[:i]
|
||||||
h.putheader("Host", host)
|
h.putheader("Host", host)
|
||||||
|
|
|
@ -398,6 +398,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #7086: Added TCP support to SysLogHandler, and tidied up some
|
||||||
|
anachronisms in the code which were a relic of 1.5.2 compatibility.
|
||||||
|
|
||||||
- Issue #7082: When falling back to the MIME 'name' parameter, the
|
- Issue #7082: When falling back to the MIME 'name' parameter, the
|
||||||
correct place to look for it is the Content-Type header.
|
correct place to look for it is the Content-Type header.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue