2013-08-05 50 views
5

Tôi muốn ghi nhật ký của tên trình ghi cụ thể, ở mức độ nhất định và cao hơn (nói INFO trở lên) vào trình xử lý nhật ký cụ thể. nhận tất cả các thông điệp tường trình vào bàn điều khiển. Python là phiên bản 2.7.Ghi nhật ký Python: thông báo tin nhắn cấp dưới mức nhật ký hiện tại

gì tôi đã cố gắng cho đến nay là để tạo ra hai logger:

  • Một logger gốc
  • Một tên logger

Đối với logger gốc, I kèm theo một logging.StreamHandler, và thiết lập các bản ghi cấp độ đến logging.DEBUG.

Sau đó, tôi đính kèm một trình xử lý vào bộ ghi có tên và đặt mức thành logging.INFO cho trình ghi nhật ký đó.

Khi bây giờ tôi gọi mô-đun của mình, sử dụng trình ghi nhật ký có tên, tôi không nhận được DEBUG nhật ký được truyền cho trình ghi nhật ký nữa.

Lưu ý: extraLogger có StreamHandler tại đây để minh họa sự cố. Trong mã sản xuất của tôi, tôi muốn sử dụng một FileHandler

import logging 

def do_logging(turn): 
    logger = logging.getLogger('extra') 
    logger.info('some info turn %d' % turn) 
    logger.debug('this is debug fudge turn %d' % turn) 

rootLogger = logging.getLogger() 
handler = logging.StreamHandler() 
rootFormatter = logging.Formatter('root - %(levelname)s: %(msg)s') 
handler.setFormatter(rootFormatter) 
rootLogger.addHandler(handler) 
rootLogger.setLevel(logging.DEBUG) 

do_logging(1) 

extraLogger = logging.getLogger('extra') 
extraHandler = logging.StreamHandler() 
extraFormatter = logging.Formatter('extra - %(levelname)s: %(msg)s') 
extraHandler.setFormatter(extraFormatter) 
extraLogger.addHandler(extraHandler) 
extraLogger.setLevel(logging.INFO) 

do_logging(2) 

Output Thực tế:

root - INFO: some info turn 1 
root - DEBUG: this is debug fudge turn 1 
extra - INFO: some info turn 2 
root - INFO: some info turn 2 

Output mà tôi muốn có:

root - INFO: some info turn 1 
root - DEBUG: this is debug fudge turn 1 
extra - INFO: some info turn 2 
root - INFO: some info turn 2 
root - DEBUG: this is debug fudge turn 2 

Tôi nghi ngờ rằng một tùy chỉnh Filter sẽ hữu ích trong trường hợp này, nhưng tôi không biết làm thế nào ...

Trả lời

4

Bạn có thể sử dụng robert's LevelFilter như thế này:

# Put the Filter on the Handler so only INFO and higher is handled 
extraHandler.addFilter(LevelFilter(logging.INFO)) 

# Let the Logger process everything (so it can propagate records to root) 
extraLogger.setLevel(logging.DEBUG) 

import logging 

class LevelFilter(logging.Filter): 
    """ 
    https://stackoverflow.com/a/7447596/190597 (robert) 
    """ 
    def __init__(self, level): 
     self.level = level 

    def filter(self, record): 
     return record.levelno >= self.level 

def do_logging(turn): 
    logger = logging.getLogger('extra') 
    logger.info('some info turn %d' % turn) 
    logger.debug('this is debug fudge turn %d' % turn) 

rootLogger = logging.getLogger() 
handler = logging.StreamHandler() 
rootFormatter = logging.Formatter('root - %(levelname)s: %(msg)s') 
handler.setFormatter(rootFormatter) 
rootLogger.addHandler(handler) 
rootLogger.setLevel(logging.DEBUG) 
do_logging(1) 

extraLogger = logging.getLogger('extra') 
extraHandler = logging.StreamHandler() 
extraFormatter = logging.Formatter('extra - %(levelname)s: %(msg)s') 
extraHandler.setFormatter(extraFormatter) 
extraLogger.addHandler(extraHandler) 

# Put the Filter on the Handler so only INFO and higher is handled 
extraHandler.addFilter(LevelFilter(logging.INFO)) 

# Handle everything (so it can propagate to root) 
extraLogger.setLevel(logging.DEBUG) 
do_logging(2) 
+1

Hoạt động tốt, cảm ơn bạn rất nhiều. Có vẻ như sau khi bộ ghi nhật ký loại bỏ các mục nhập nhật ký dựa trên cơ chế mức trần, nó không truyền bá chúng nữa. Ở đây điều này được làm việc xung quanh bằng cách thiết lập mức nhật ký thấp hơn, nhưng chỉ có các thông điệp tường trình của mức mong muốn, cho phép các mục nhật ký của mức truyền thấp hơn. – trapicki

+1

Vâng, đúng vậy. Có [biểu đồ luồng tốt đẹp trong tài liệu] (http://docs.python.org/2/howto/logging.html#logging-flow) đặt mô hình tâm thần phù hợp. Bạn không muốn bộ lọc được gắn vào bộ ghi log để loại bỏ bản ghi vì nó không bao giờ được đưa đến bước truyền. – unutbu

+1

Ồ, có một sự khác biệt lớn nếu bộ lọc được gắn vào trình xử lý hoặc bộ ghi ... Biểu đồ con _handler có vẻ sai lạc: _Stop_ sẽ không dừng xử lý, chỉ cần quay lại từ trình xử lý đó mà không phát ra thứ gì đó và luồng sẽ truyền người xử lý tiếp theo, hay tôi sai, @unutbu? – trapicki

0

Có một phương thức trong lớp logger gọi là "tuyên truyền" mà dường như để làm những gì bạn hỏi: http://docs.python.org/2/library/logging.html#logger-objects

+0

AFAIU 'Logger.propagate 'là một thuộc tính boolean điều khiển sự lan truyền xảy ra ở tất cả. Tôi đã cố gắng để fiddle với điều đó, nhưng có vẻ như các mục đăng nhập được loại bỏ dựa trên mức độ và do đó không tuyên truyền để các logger gốc anyway. – trapicki

Các vấn đề liên quan