Ghi nhật ký Python không xuất ra bất kỳ thứ gì


91

Trong tập lệnh python mà tôi đang viết, tôi đang cố gắng ghi lại các sự kiện bằng mô-đun ghi nhật ký. Tôi có mã sau để định cấu hình trình ghi nhật ký của mình:

ERROR_FORMAT = "%(levelname)s at %(asctime)s in %(funcName)s in %(filename) at line %(lineno)d: %(message)s"
DEBUG_FORMAT = "%(lineno)d in %(filename)s at %(asctime)s: %(message)s"
LOG_CONFIG = {'version':1,
              'formatters':{'error':{'format':ERROR_FORMAT},
                            'debug':{'format':DEBUG_FORMAT}},
              'handlers':{'console':{'class':'logging.StreamHandler',
                                     'formatter':'debug',
                                     'level':logging.DEBUG},
                          'file':{'class':'logging.FileHandler',
                                  'filename':'/usr/local/logs/DatabaseUpdate.log',
                                  'formatter':'error',
                                  'level':logging.ERROR}},
              'root':{'handlers':('console', 'file')}}
logging.config.dictConfig(LOG_CONFIG)

Khi tôi cố gắng chạy logging.debug("Some string"), tôi không nhận được kết quả nào cho bảng điều khiển, mặc dù trang này trong tài liệu nói rằng logging.debugcần có trình ghi gốc xuất ra thông báo. Tại sao chương trình của tôi không xuất ra bất cứ thứ gì và làm cách nào để khắc phục?

Câu trả lời:


97

Mức ghi nhật ký mặc định là cảnh báo. Vì bạn chưa thay đổi cấp độ, cấp độ của trình ghi gốc vẫn đang cảnh báo. Điều đó có nghĩa là nó sẽ bỏ qua bất kỳ ghi nhật ký nào có mức độ thấp hơn cảnh báo, bao gồm ghi nhật ký gỡ lỗi.

Điều này được giải thích trong hướng dẫn :

import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything

Dòng 'thông tin' không in bất cứ thứ gì, vì cấp cao hơn thông tin.

Để thay đổi cấp độ, chỉ cần đặt nó trong trình ghi gốc:

'root':{'handlers':('console', 'file'), 'level':'DEBUG'}

Nói cách khác, nó không đủ để xác định một trình xử lý với level = DEBUG, mức ghi nhật ký thực tế cũng phải là DEBUG để nó xuất ra bất kỳ thứ gì.


6
Tài liệu nói rằng mức mặc định của nó là NOTSET, là mức 0 sẽ xuất ra mọi thứ ... Tại sao điều này không đúng?
Ben

@Ben ở đâu mà nó nói vậy? Tất cả những gì tôi có thể thấy là "Mức mặc định là CẢNH BÁO, có nghĩa là chỉ các sự kiện từ cấp này trở lên mới được theo dõi, trừ khi gói ghi nhật ký được định cấu hình để làm theo cách khác."
Omri Barel


1
@Ben theo tài liệu mà các trình ghi nhật ký được duyệt qua để tìm nguồn gốc đầu tiên có level != NOTSEThoặc gốc (nếu không tìm thấy). Gốc có WARNINGcấp theo mặc định. Điều này được viết trong phần bạn đã liên kết với ( Logger.setLevel).
Omri Barel

5
Hãy nhớ rằng sau khi nhập, loggingbạn cần gọi logging.basicConfig()ít nhất một lần. Nếu không, bạn có thể rất ngạc nhiên rằng các trình ghi chép con sẽ không in bất cứ thứ gì. Các chức năng ghi nhật ký trên root logger gọi nó một cách lười biếng.
Hubert Grzeskowiak

53

Nhiều năm sau, dường như vẫn còn vấn đề về khả năng sử dụng với trình ghi Python. Dưới đây là một số giải thích với các ví dụ:

import logging
# This sets the root logger to write to stdout (your console).
# Your script/app needs to call this somewhere at least once.
logging.basicConfig()

# By default the root logger is set to WARNING and all loggers you define
# inherit that value. Here we set the root logger to NOTSET. This logging
# level is automatically inherited by all existing and new sub-loggers
# that do not set a less verbose level.
logging.root.setLevel(logging.NOTSET)

# The following line sets the root logger level as well.
# It's equivalent to both previous statements combined:
logging.basicConfig(level=logging.NOTSET)


# You can either share the `logger` object between all your files or the
# name handle (here `my-app`) and call `logging.getLogger` with it.
# The result is the same.
handle = "my-app"
logger1 = logging.getLogger(handle)
logger2 = logging.getLogger(handle)
# logger1 and logger2 point to the same object:
# (logger1 is logger2) == True


# Convenient methods in order of verbosity from highest to lowest
logger.debug("this will get printed")
logger.info("this will get printed")
logger.warning("this will get printed")
logger.error("this will get printed")
logger.critical("this will get printed")


# In large applications where you would like more control over the logging,
# create sub-loggers from your main application logger.
component_logger = logger.getChild("component-a")
component_logger.info("this will get printed with the prefix `my-app.component-a`")

# If you wish to control the logging levels, you can set the level anywhere 
# in the hierarchy:
#
# - root
#   - my-app
#     - component-a
#

# Example for development:
logger.setLevel(logging.DEBUG)

# If that prints too much, enable debug printing only for your component:
component_logger.setLevel(logging.DEBUG)


# For production you rather want:
logger.setLevel(logging.WARNING)

Một nguồn nhầm lẫn phổ biến đến từ trình ghi gốc được khởi tạo kém. Xem xét điều này:

import logging
log = logging.getLogger("myapp")
log.warning("woot")
logging.basicConfig()
log.warning("woot")

Đầu ra:

woot
WARNING:myapp:woot

Tùy thuộc vào môi trường thời gian chạy và mức độ ghi nhật ký của bạn, dòng nhật ký đầu tiên (trước cấu hình cơ bản) có thể không hiển thị ở bất kỳ đâu .


Nhật ký của tôi không hoạt động, trong đó nó không tạo ra tệp đầu ra. Bạn có thấy điều gì tôi đang làm rõ ràng là sai không? logging.basicConfig( filename='logging.txt', level=logging.DEBUG) logger = logging.getLogger() logger.info('Test B') logging.info('Test A')
Rylan Schaeffer

Tệp ghi nhật ký thậm chí còn không được tạo
Rylan Schaeffer

Tôi nhận thấy khi tôi giảm điểm ngắt sau đó logger = logging.getLogger(), mức được đặt thành CẢNH BÁO mặc dù tôi đã chỉ định mức là DEBUG. Bạn có biết tôi đang làm gì sai không?
Rylan Schaeffer

Xin chào @RylanSchaeffer, bạn có thể muốn tạo một câu hỏi mới và cung cấp thêm một số chi tiết. Điều này cũng sẽ tạo cơ hội cho người khác giúp đỡ bạn.
Hubert Grzeskowiak

Tôi đã làm. Thông thường, đặt một nhận xét là cách nhanh hơn để tìm câu trả lời vì ít nhất một người hiểu biết sẽ thấy câu hỏi của tôi
Rylan Schaeffer

17

Đối với bất kỳ ai ở đây muốn có câu trả lời siêu đơn giản: chỉ cần đặt mức bạn muốn hiển thị. Ở đầu tất cả các tập lệnh của tôi, tôi chỉ đặt:

import logging
logging.basicConfig(level = logging.INFO)

Sau đó, để hiển thị bất kỳ thứ gì bằng hoặc cao hơn mức đó:

logging.info("Hi you just set your fleeb to level plumbus")

Nó là một tập hợp phân cấp gồm năm cấp độ để các bản ghi sẽ hiển thị ở cấp độ bạn đã đặt hoặc cao hơn . Vì vậy, nếu bạn muốn hiển thị một lỗi, bạn có thể sử dụng logging.error("The plumbus is broken").

Các cấp, các thứ tự tăng dần mức độ nghiêm trọng, là DEBUG, INFO, WARNING, ERROR, và CRITICAL. Cài đặt mặc định là WARNING.

Đây là một bài viết hay chứa thông tin này được thể hiện tốt hơn câu trả lời của tôi:
https://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3


14

Có thể thử cái này? Có vẻ như vấn đề đã được giải quyết sau khi loại bỏ tất cả các trình xử lý trong trường hợp của tôi.

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

logging.basicConfig(filename='output.log', level=logging.INFO)

SyntaxError: invalid syntax
Eric

2
Tại sao điều này là cần thiết? Những trình xử lý nào đi kèm với trình ghi chép python và tại sao chúng ở đó để bắt đầu? Hoặc có thể câu hỏi là, tại sao basicConfig không ghi đè / thay thế chúng?
'19
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.