-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
gh-116267: Avoid formatting record twice in RotatingFileHandler. #122731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,6 +67,7 @@ def __init__(self, filename, mode, encoding=None, delay=False, errors=None): | |
self.mode = mode | ||
self.encoding = encoding | ||
self.errors = errors | ||
self._msg = None # cache to avoid reformatting - see gh-116267 | ||
|
||
def emit(self, record): | ||
""" | ||
|
@@ -78,7 +79,15 @@ def emit(self, record): | |
try: | ||
if self.shouldRollover(record): | ||
self.doRollover() | ||
logging.FileHandler.emit(self, record) | ||
if self._msg: | ||
msg = self._msg | ||
self._msg = None | ||
else: | ||
msg = self.format(record) | ||
self.stream.write(msg + self.terminator) | ||
self.flush() | ||
except RecursionError: # See issue bpo-36272 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that it is better to open a separate issue for this. There may be other problems related to handling RecursionError here. For example, in SocketHandler we may want to close socket on RecursionError if closeOnError is true. |
||
raise | ||
except Exception: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not related to this issue, but there should be the |
||
self.handleError(record) | ||
|
||
|
@@ -196,9 +205,9 @@ def shouldRollover(self, record): | |
if self.stream is None: # delay was set... | ||
self.stream = self._open() | ||
if self.maxBytes > 0: # are we rolling over? | ||
msg = "%s\n" % self.format(record) | ||
self._msg = msg = self.format(record) | ||
self.stream.seek(0, 2) #due to non-posix-compliant Windows feature | ||
if self.stream.tell() + len(msg) >= self.maxBytes: | ||
if self.stream.tell() + len(msg) + len(self.terminator) >= self.maxBytes: | ||
# See bpo-45401: Never rollover anything other than regular files | ||
if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): | ||
return False | ||
|
@@ -687,6 +696,8 @@ def emit(self, record): | |
try: | ||
s = self.makePickle(record) | ||
self.send(s) | ||
except RecursionError: # See issue bpo-36272 | ||
raise | ||
except Exception: | ||
self.handleError(record) | ||
|
||
|
@@ -1016,6 +1027,8 @@ def emit(self, record): | |
self.socket.sendto(msg, self.address) | ||
else: | ||
self.socket.sendall(msg) | ||
except RecursionError: # See issue bpo-36272 | ||
raise | ||
except Exception: | ||
self.handleError(record) | ||
|
||
|
@@ -1096,6 +1109,8 @@ def emit(self, record): | |
smtp.login(self.username, self.password) | ||
smtp.send_message(msg) | ||
smtp.quit() | ||
except RecursionError: # See issue bpo-36272 | ||
raise | ||
except Exception: | ||
self.handleError(record) | ||
|
||
|
@@ -1190,6 +1205,8 @@ def emit(self, record): | |
type = self.getEventType(record) | ||
msg = self.format(record) | ||
self._welu.ReportEvent(self.appname, id, cat, type, [msg]) | ||
except RecursionError: # See issue bpo-36272 | ||
raise | ||
except Exception: | ||
self.handleError(record) | ||
|
||
|
@@ -1293,6 +1310,8 @@ def emit(self, record): | |
if self.method == "POST": | ||
h.send(data.encode('utf-8')) | ||
h.getresponse() #can't do anything with the result | ||
except RecursionError: # See issue bpo-36272 | ||
raise | ||
except Exception: | ||
self.handleError(record) | ||
|
||
|
@@ -1488,6 +1507,8 @@ def emit(self, record): | |
""" | ||
try: | ||
self.enqueue(self.prepare(record)) | ||
except RecursionError: # See issue bpo-36272 | ||
raise | ||
except Exception: | ||
self.handleError(record) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FileHandler.emit()
opens a stream if it was not open. If you want to use the cached formatted message, this should perhaps be done inFileHandler.emit()
orStreamHandler.emit()
. Or inlineFileHandler.emit()
andStreamHandler.emit()
completely here. Or add parameter for formatted error message inFileHandler.emit()
andStreamHandler.emit()
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but it's opened in
shouldRollover()
, so that part ofFileHandler.emit()
would never be exercised.cpython/Lib/logging/handlers.py
Lines 196 to 197 in 9e551f9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. Although it may break subclasses that override
shouldRollover()
(if it returns early, before callingsuper().shouldRollover()
).