Câu hỏi logger cấu hình để đăng nhập vào tập tin và in để stdout


Tôi đang sử dụng mô-đun đăng nhập của Python để đăng nhập một số chuỗi gỡ lỗi vào một tệp hoạt động khá tốt. Bây giờ ngoài ra, tôi muốn sử dụng mô-đun này để cũng in các chuỗi ra để stdout. Làm thế nào để tôi làm điều này? Để đăng nhập các chuỗi của tôi vào một tệp, tôi sử dụng mã sau:

import logging
import logging.handlers
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
handler = logging.handlers.RotatingFileHandler(
    LOGFILE, maxBytes=(1048576*5), backupCount=7
)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)

và sau đó gọi hàm logger như

logger.debug("I am written to the file")

Cảm ơn bạn đã giúp đỡ ở đây!


198
2017-12-05 22:22


gốc




Các câu trả lời:


Chỉ cần có được một xử lý để logger gốc và thêm StreamHandler. StreamHandler viết để stderr. Không chắc chắn nếu bạn thực sự cần stdout hơn stderr, nhưng đây là những gì tôi sử dụng khi tôi thiết lập các logger Python và tôi cũng thêm FileHandler là tốt. Sau đó, tất cả các bản ghi của tôi đi đến cả hai nơi (đó là những gì nó âm thanh như bạn muốn).

import logging
logging.getLogger().addHandler(logging.StreamHandler())

Bạn cũng có thể thêm một Formatter vào nó để tất cả các dòng log của bạn có một tiêu đề chung.

I E:

import logging
logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s")
rootLogger = logging.getLogger()

fileHandler = logging.FileHandler("{0}/{1}.log".format(logPath, fileName))
fileHandler.setFormatter(logFormatter)
rootLogger.addHandler(fileHandler)

consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(logFormatter)
rootLogger.addHandler(consoleHandler)

In theo định dạng:

2012-12-05 16:58:26,618 [MainThread  ] [INFO ]  my message

269
2017-12-05 22:43



Bạn cũng có thể chỉ khởi tạo StreamHandler với sys.stdout, và sau đó nó sẽ đăng nhập vào đó thay vì stderr. - Silas Ray
@ sr2222 logger.addHandler (sys.stdout) cung cấp cho tôi NameError: tên 'sys' không được định nghĩa - cerr
À vâng ... bạn phải import sys Đầu tiên. Và thực sự khởi tạo trình xử lý, tức là consoleHandler = logging.StreamHandler(sys.stdout) - Silas Ray
@ sr2222 Điều này dường như không làm việc cho tôi, tôi bắt đầu nhận được lỗi dường như không liên quan khi tôi bao gồm một "logger.addHandler (sys.stdout)" - cerr
Bởi vì như tôi đã nói, đó không phải là cách bạn làm điều đó. Tạo bộ xử lý với sys.stdout, sau đó gắn bộ xử lý vào bộ ghi. - Silas Ray


logging.basicConfig() có thể lấy một đối số từ khóa handlers kể từ Python 3.3, đơn giản hóa việc thiết lập đăng nhập rất nhiều, đặc biệt là khi thiết lập nhiều trình xử lý có cùng trình định dạng:

handlers - Nếu được chỉ định, đây phải là một trình xử lý đã được tạo lặp lại để thêm vào trình ghi nhật ký gốc. Bất kỳ trình xử lý nào chưa có bộ định dạng sẽ được gán trình định dạng mặc định được tạo trong hàm này.

Mã ví dụ khá dài và dài dòng từ câu trả lời được chấp nhận do đó trở thành chỉ:

import logging

logging.basicConfig(
    format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s",
    handlers=[
        logging.FileHandler("{0}/{1}.log".format(logPath, fileName)),
        logging.StreamHandler()
    ])

(Hoặc với import sys + StreamHandler(sys.stdout) theo yêu cầu của câu hỏi ban đầu.)


60
2017-09-07 14:17



Một trong những trường hợp mà câu trả lời ở phía dưới là SO hữu ích !!!! Cảm ơn - Dror
đừng quên đặt level = logging.INFO hoặc mức mong muốn - Andy Matteson
Định nghĩa cho FileHandler: logging.FileHandler(filename, mode='a', encoding=None, delay=False). Điều này có nghĩa, khi bạn chỉ muốn đăng nhập vào cùng một thư mục, bạn có thể sử dụng FileHandler("mylog.log"). Nếu bạn muốn ghi đè nhật ký mỗi lần, hãy đặt "w" làm đối số thứ hai. - user136036
Tôi đã thử này, nhưng tập tin đầu ra là sản phẩm nào mặc dù giao diện điều khiển được cho đầu ra .. Bất kỳ đề xuất ..? - Ramesh-X
@ Ramesh-X Nó hoạt động, như hiển nhiên, ví dụ: đây repl.it/repls/ImprobableHilariousLamp Nếu nó không dành cho bạn, hãy kiểm tra phiên bản Python của bạn, các điều khoản thư mục đích, rằng bạn cấu hình việc ghi nhật ký trước sử dụng nó, ... - Yirkha


Thêm một StreamHandler mà không có đối số đi đến stderr thay vì stdout. Nếu một số quy trình khác có sự phụ thuộc vào kết xuất đồ thị (nghĩa là khi viết plugin NRPE), thì hãy đảm bảo chỉ định rõ ràng stdout hoặc bạn có thể gặp phải một số sự cố không mong muốn.

Dưới đây là một ví dụ nhanh tái sử dụng các giá trị giả định và LOGFILE từ câu hỏi:

import logging
from logging.handlers import RotatingFileHandler
from logging import handlers
import sys

log = logging.getLogger('')
log.setLevel(logging.DEBUG)
format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")

ch = logging.StreamHandler(sys.stdout)
ch.setFormatter(format)
log.addHandler(ch)

fh = handlers.RotatingFileHandler(LOGFILE, maxBytes=(1048576*5), backupCount=7)
fh.setFormatter(format)
log.addHandler(fh)

47
2017-09-24 02:49





Hoặc là chạy basicConfig với stream=sys.stdout làm đối số trước khi thiết lập bất kỳ trình xử lý nào khác hoặc ghi nhật ký bất kỳ thư nào hoặc thêm thủ công StreamHandler đẩy các thông điệp đến stdout tới bộ ghi gốc (hoặc bất kỳ bộ ghi nào khác mà bạn muốn, cho vấn đề đó).


18
2017-12-05 22:37



hoops, xem chỉnh sửa ở trên, tôi chỉ nhận ra rằng tôi đã không đăng tất cả ... - cerr


Đối với 2,7, hãy thử các cách sau:

fh = logging.handlers.RotatingFileHandler(LOGFILE, maxBytes=(1048576*5), backupCount=7)

-2
2017-07-19 22:57