8000 [3.13] gh-120683: Fix an error in logging.LogRecord timestamp (GH-120… · python/cpython@544a472 · GitHub
[go: up one dir, main page]

Skip to content

Commit 544a472

Browse files
[3.13] gh-120683: Fix an error in logging.LogRecord timestamp (GH-120709) (GH-120933)
The integer part of the timestamp can be rounded up, while the millisecond calculation truncates, causing the log timestamp to be wrong by up to 999 ms (affected roughly 1 in 8 million timestamps). (cherry picked from commit 1500a23) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent b7240ed commit 544a472

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

Lib/logging/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,14 @@ def __init__(self, name, level, pathname, lineno,
340340
self.lineno = lineno
341341
self.funcName = func
342342
self.created = ct / 1e9 # ns to float seconds
343-
344343
# Get the number of whole milliseconds (0-999) in the fractional part of seconds.
345344
# Eg: 1_677_903_920_999_998_503 ns --> 999_998_503 ns--> 999 ms
346345
# Convert to float by adding 0.0 for historical reasons. See gh-89047
347346
self.msecs = (ct % 1_000_000_000) // 8000 1_000_000 + 0.0
347+
if self.msecs == 999.0 and int(self.created) != ct // 1_000_000_000:
348+
# ns -> sec conversion can round up, e.g:
349+
# 1_677_903_920_999_999_900 ns --> 1_677_903_921.0 sec
350+
self.msecs = 0.0
348351

349352
self.relativeCreated = (ct - _startTime) / 1e6
350353
if logThreads:

Lib/test/test_logging.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4648,13 +4648,18 @@ def test_msecs_has_no_floating_point_precision_loss(self):
46484648
(1_677_902_297_100_000_000, 100.0), # exactly 100ms
46494649
(1_677_903_920_999_998_503, 999.0), # check truncating doesn't round
46504650
(1_677_903_920_000_998_503, 0.0), # check truncating doesn't round
4651+
(1_677_903_920_999_999_900, 0.0), # check rounding up
46514652
)
46524653
for ns, want in tests:
46534654
with patch('time.time_ns') as patched_ns:
46544655
patched_ns.return_value = ns
46554656
record = logging.makeLogRecord({'msg': 'test'})
4656-
self.assertEqual(record.msecs, want)
4657-
self.assertEqual(record.created, ns / 1e9)
4657+
with self.subTest(ns):
4658+
self.assertEqual(record.msecs, want)
4659+
self.assertEqual(record.created, ns / 1e9)
4660+
self.assertAlmostEqual(record.created - int(record.created),
4661+
record.msecs / 1e3,
4662+
delta=1e-3)
46584663

46594664
def test_relativeCreated_has_higher_precision(self):
46604665
# See issue gh-102402.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix an error in :class:`logging.LogRecord`, when the integer part of the
2+
timestamp is rounded up, while the millisecond calculation truncates,
3+
causing the log timestamp to be wrong by up to 999 ms (affected roughly 1 in
4+
8 million timestamps).

0 commit comments

Comments
 (0)
0