Mục đích của tôi là để làm một khai thác gỗ đa mô-đun với bộ lọc thứ bậc
cách thức mà nó được đề xuất bởi khai thác gỗ tác giả Vinay Sajip, ít nhất là như xa như tôi đoán ;-)Cách chính xác để lọc các trình ghi nhật ký khác nhau bằng cách sử dụng nhật ký python là gì?
Bạn có thể bỏ qua để "Làm thế nào tôi muốn nó làm việc"
thật không may, tôi đã học rất nhanh đến mức làm việc với các cơ sở khai thác gỗ là phức tạp hơn nhiều so với hầu hết các kinh nghiệm khác của tôi với ngôn ngữ và tôi đã làm rất nhiều chung (thiết kế) sai lầm, ví dụ cố gắng để đạt được một logger lớp tập trung duy nhất đăng nhập cho nhiều mô-đun hoặc thậm chí các chương trình như (using Python logger class to generate multiple logs for different log levels). Nhưng dường như có chỗ cho thiết kế tốt hơn, và nó có thể tồi tệ hơn là dành thời gian tìm và học nó. Vì vậy, ngay bây giờ tôi hy vọng tôi đang đi đúng hướng. Nếu không Vinaj sẽ phải làm rõ phần còn lại ;-)
tôi sắp xếp đăng nhập của tôi như thế này:
- Mỗi module python có của nó own logger
- Mỗi logger có một cái tên tương tự như các mô-đun nó ở đâu được định nghĩa, ví dụ
logger = logging.getLogger(__name__)
- Như thế này, mã bên trong mỗi mô-đun có thể sử dụng riêng logger (được xác định tại địa phương) của mình để gửi tin nhắn đăng nhập (logging.LogRecord) để xử lý (logging.Handler)
- Sử dụng logging.config để đạt được sự linh hoạt đầy đủ trong cấu hình của khai thác gỗ (Lưu ý: trong mã bên dưới, tôi chỉ bắt đầu bằng basicConfig)
Cách tiếp cận này là phương pháp được khuyến nghị và tôi đồng ý với những lợi thế có thể có của nó. Ví dụ, tôi có thể bật/tắt DEBUG của các thư viện bên ngoài bằng cách sử dụng các tên module đủ điều kiện (hệ thống phân cấp đặt tên đã tồn tại trong mã).
Bây giờ để có mức kiểm soát cao hơn, tôi muốn sử dụng đăng nhập. Lớp học, để có thể lọc (chỉ cho phép) một cây con được chọn trong hệ thống phân cấp của nhật ký.
này là tất cả tốt, nhưng tính năng lọc như mô tả ở đây
Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed.
vẫn không làm việc cho tôi.
Tôi đoán là sự thiếu hiểu biết của tôi về các chi tiết đằng sau việc truyền bá LogRecords là nguồn gốc của vấn đề. Trước khi nhảy vào mã tôi muốn thể hiện ở đây một biểu đồ dòng chảy (từ cookbook tutorial mà lúc đầu tôi bằng cách nào đó thất bại trong việc ngay lập tức khám phá):
Ví dụ mã
Tôi bắt đầu với hai mô-đun dụ, mỗi sử dụng nó sở hữu tên logger:
bar.py:
import logging
logger = logging.getLogger(__name__)
def bar():
logger.info('hello from ' + __name__)
foo.py:
import logging
from bar import bar, logger as bar_logger
logger = logging.getLogger('foo')
def foo():
logger.info('hello from foo')
if __name__ == '__main__':
# Trivial logging setup.
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(name)-20s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M'
)
# Do some work.
foo()
bar()
Logging là lần đầu tiên được xây dựng với logging.basicConfig (logger gốc, được tạo ra sau khi import logging
bởi __main__
được một handler dòng gắn liền với nó, để chúng ta có một giao diện điều khiển), được kích hoạt (Logger tương ứng .disabled = False) và cả hai logger mô-đun thanh và foo truyền tới trình ghi nhật ký gốc (vì vậy chúng tôi có tổng cộng ba logger).
print logger
print bar_logger
print logging.root
# Prints
#<logging.Logger object at 0x7f0cfd520790>
#<logging.Logger object at 0x7f0cfd55d710>
#<logging.RootLogger object at 0x7f0cfd520550>
Cách sử dụng thực tế là khi thanh là thư viện bên ngoài mà tôi muốn tắt tiếng (lọc ra).
Làm thế nào nó hoạt động, nhưng "tôi" không thích nó
# Don't like it
bar_logger.addFilter(logging.Filter('foo'))
# Do some work.
foo()
bar()
in chỉ
06-24 14:08 foo INFO hello from foo
Làm thế nào tôi muốn nó làm việc
Tôi muốn lọc nó ra trực thuộc Trung ương , tức là tại logger gốc của tôi w/o sự cần thiết phải nhập khẩu tất cả các logger của tất cả các module bên ngoài ra khỏi đó.
logging.root.addFilter(logging.Filter('foo'))
in
06-24 14:17 foo INFO hello from foo
06-24 14:17 bar INFO hello from bar
Phải có một số rõ ràng/sai lầm ngu ngốc mà tôi bỏ lỡ: Tôi không muốn bất kỳ tin nhắn từ thanh logger. Hey, nhưng cách nào tốt hơn để tìm nó hơn là tóm tắt tất cả trên SO, folks? ;-)
Tôi sẽ cố gắng tìm ra cách để bar_logger đợi quyết định từ trình ghi nhật ký gốc, trước khi phát ra bất kỳ thứ gì. Tôi chỉ hy vọng rằng đây thực sự là cách nó được cho là làm việc ngay từ đầu.
Cũng kiểm http://stackoverflow.com/questions/7507825/python-complete-example-of-dict-for -logging-config-dictconfig –
Bạn cũng có thể tìm thấy *** logging_tree *** introspection rất sâu sắc đối với các trường hợp đăng nhập phức tạp https://pypi.python.org/pypi/logging_tree –
Mẹo tuyệt vời từ một đồng nghiệp của tôi về việc đăng nhập http://pythonsweetness.tumblr.com/post/67394619015/use-of-logging-package-from-within-a-library –