Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 14 additions & 25 deletions Lib/logging/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1475,8 +1475,6 @@ class Logger(Filterer):
level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
There is no arbitrary limit to the depth of nesting.
"""
_tls = threading.local()

def __init__(self, name, level=NOTSET):
"""
Initialize the logger with a name and an optional level.
Expand Down Expand Up @@ -1673,19 +1671,14 @@ def handle(self, record):
This method is used for unpickled records received from a socket, as
well as those created locally. Logger-level filtering is applied.
"""
if self._is_disabled():
if self.disabled:
return

self._tls.in_progress = True
try:
maybe_record = self.filter(record)
if not maybe_record:
return
if isinstance(maybe_record, LogRecord):
record = maybe_record
self.callHandlers(record)
finally:
self._tls.in_progress = False
maybe_record = self.filter(record)
if not maybe_record:
return
if isinstance(maybe_record, LogRecord):
record = maybe_record
self.callHandlers(record)

def addHandler(self, hdlr):
"""
Expand Down Expand Up @@ -1773,7 +1766,7 @@ def isEnabledFor(self, level):
"""
Is this logger enabled for level 'level'?
"""
if self._is_disabled():
if self.disabled:
return False

try:
Expand Down Expand Up @@ -1823,11 +1816,6 @@ def _hierlevel(logger):
if isinstance(item, Logger) and item.parent is self and
_hierlevel(item) == 1 + _hierlevel(item.parent))

def _is_disabled(self):
# We need to use getattr as it will only be set the first time a log
# message is recorded on any given thread
return self.disabled or getattr(self._tls, 'in_progress', False)

def __repr__(self):
level = getLevelName(self.getEffectiveLevel())
return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
Expand Down Expand Up @@ -1864,9 +1852,9 @@ class LoggerAdapter(object):

def __init__(self, logger, extra=None, merge_extra=False):
"""
Initialize the adapter with a logger and a dict-like object which
provides contextual information. This constructor signature allows
easy stacking of LoggerAdapters, if so desired.
Initialize the adapter with a logger and an optional dict-like object
which provides contextual information. This constructor signature
allows easy stacking of LoggerAdapters, if so desired.

You can effectively pass keyword arguments as shown in the
following example:
Expand Down Expand Up @@ -1897,8 +1885,9 @@ def process(self, msg, kwargs):
Normally, you'll only need to override this one method in a
LoggerAdapter subclass for your specific needs.
"""
if self.merge_extra and "extra" in kwargs:
kwargs["extra"] = {**self.extra, **kwargs["extra"]}
if self.merge_extra and kwargs.get("extra") is not None:
if self.extra is not None:
kwargs["extra"] = {**self.extra, **kwargs["extra"]}
else:
kwargs["extra"] = self.extra
return msg, kwargs
Expand Down
14 changes: 13 additions & 1 deletion Lib/logging/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,8 @@ def configure_handler(self, config):
else:
factory = klass
kwargs = {k: config[k] for k in config if (k != '.' and valid_ident(k))}
# When deprecation ends for using the 'strm' parameter, remove the
# "except TypeError ..."
try:
result = factory(**kwargs)
except TypeError as te:
Expand All @@ -876,6 +878,15 @@ def configure_handler(self, config):
#(e.g. by Django)
kwargs['strm'] = kwargs.pop('stream')
result = factory(**kwargs)

import warnings
warnings.warn(
"Support for custom logging handlers with the 'strm' argument "
"is deprecated and scheduled for removal in Python 3.16. "
"Define handlers with the 'stream' argument instead.",
DeprecationWarning,
stacklevel=2,
)
if formatter:
result.setFormatter(formatter)
if level is not None:
Expand Down Expand Up @@ -1006,7 +1017,8 @@ class ConfigSocketReceiver(ThreadingTCPServer):
A simple TCP socket-based logging config receiver.
"""

allow_reuse_address = 1
allow_reuse_address = True
allow_reuse_port = False

def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT,
handler=None, ready=None, verify=None):
Expand Down
24 changes: 22 additions & 2 deletions Lib/logging/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,11 @@ def shouldRollover(self, record):
if self.stream is None: # delay was set...
self.stream = self._open()
if self.maxBytes > 0: # are we rolling over?
pos = self.stream.tell()
try:
pos = self.stream.tell()
except io.UnsupportedOperation:
# gh-143237: Never rollover a named pipe.
return False
if not pos:
# gh-116263: Never rollover an empty file
return False
Expand Down Expand Up @@ -855,7 +859,7 @@ class SysLogHandler(logging.Handler):
}

def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
facility=LOG_USER, socktype=None):
facility=LOG_USER, socktype=None, timeout=None):
"""
Initialize a handler.

Expand All @@ -872,6 +876,7 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT),
self.address = address
self.facility = facility
self.socktype = socktype
self.timeout = timeout
self.socket = None
self.createSocket()

Expand Down Expand Up @@ -933,6 +938,8 @@ def createSocket(self):
err = sock = None
try:
sock = socket.socket(af, socktype, proto)
if self.timeout:
sock.settimeout(self.timeout)
if socktype == socket.SOCK_STREAM:
sock.connect(sa)
break
Expand Down Expand Up @@ -1529,6 +1536,19 @@ def __init__(self, queue, *handlers, respect_handler_level=False):
self._thread = None
self.respect_handler_level = respect_handler_level

def __enter__(self):
"""
For use as a context manager. Starts the listener.
"""
self.start()
return self

def __exit__(self, *args):
"""
For use as a context manager. Stops the listener.
"""
self.stop()

def dequeue(self, block):
"""
Dequeue a record and return it, optionally blocking.
Expand Down
Loading
Loading