logging: Logger.setLevel() and logging.disable() are O(number of loggers)

Đang mở
#160,936 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
38/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python
Lĩnh vực
backend, performance

Hướng nghiên cứu

Start with Manager._clear_cache() and Logger.isEnabledFor() in CPython’s logging implementation, then inspect the logging tests that cover cache invalidation. The issue includes a benchmark reproducing quadratic behavior across thousands of loggers. Done means cache clearing scales with loggers that have cached values while preserving correct isEnabledFor() results after level changes.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

performance stdlib type-bug
Bug report

Every Logger.setLevel() and logging.disable() call goes through Manager._clear_cache(), which walks the whole loggerDict and clears each logger's isEnabledFor cache, even the ones that never cached anything. So setting the level on N loggers one by one is quadratic. That shows up in apps or test suites with thousands of loggers (one per module/plugin/connection) that get configured individually.

import logging, time

for n in (1000, 2000, 4000, 8000):
    logging.root.manager.loggerDict.clear()
    loggers = [logging.getLogger(f"app.mod{i}") for i in range(n)]
    for lg in loggers:
        lg.isEnabledFor(logging.DEBUG)
    t = time.perf_counter()
    for lg in loggers:
        lg.setLevel(logging.INFO)
    print(f"{n:5d} loggers: {time.perf_counter() - t:.3f} s")

On 3.14.7 this gives about 0.23 s at 2000 loggers, 0.89 s at 4000 and 4.4 s at 8000 (each doubling is about 4x).

A fix is to have the manager remember which loggers actually have something in their cache (a WeakSet filled on the isEnabledFor cache-miss path, which already holds the lock) and only clear those. The cache-hit path doesn't change. I have a patch ready and can open a PR.

CPython versions tested on:

3.14, CPython main branch

Operating systems tested on:

Linux

Linked PRs
  • gh-160937
Ngôn ngữ chính
Python
Star
77.8k
Fork
37.7k
Merge trung bình
17 giờ 24 phút
Pull request đã merge (30 ngày)
716

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của python/cpython

Tất cả issue của python/cpython

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.