Cách ghi tên tệp nguồn và số dòng bằng Python


123

Có thể trang trí / mở rộng hệ thống ghi nhật ký tiêu chuẩn python để khi một phương thức ghi nhật ký được gọi, nó cũng ghi lại tệp và số dòng nơi nó được gọi hoặc có thể phương thức đã gọi nó?

Câu trả lời:


228

Chắc chắn, hãy kiểm tra định dạng trong tài liệu ghi nhật ký. Cụ thể là các biến lineno và pathname.

% (pathname) s Tên đường dẫn đầy đủ của tệp nguồn nơi phát hành lệnh gọi ghi nhật ký (nếu có).

% (filename) s Phần tên tệp của tên đường dẫn.

% (module) s Mô-đun (phần tên của tên tệp).

% (funcName) s Tên hàm chứa lệnh gọi ghi nhật ký.

% (lineno) d Số dòng nguồn nơi lệnh gọi ghi nhật ký được phát hành (nếu có).

Trông giống như sau:

formatter = logging.Formatter('[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s','%m-%d %H:%M:%S')

1
Và, có, sự lộn xộn chữ hoa / thường trong các biến cần được xem xét.
Tom Pohl

1
Nếu không được gọi là "trường hợp lạc đà được triển khai rất kém".
Jon Spencer

81

Ngoài câu trả lời rất hữu ích của Seb , đây là một đoạn mã hữu ích thể hiện việc sử dụng trình ghi nhật ký với định dạng hợp lý:

#!/usr/bin/env python
import logging

logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG)

logger = logging.getLogger(__name__)
logger.debug("This is a debug log")
logger.info("This is an info log")
logger.critical("This is critical")
logger.error("An error occurred")

Tạo đầu ra này:

2017-06-06:17:07:02,158 DEBUG    [log.py:11] This is a debug log
2017-06-06:17:07:02,158 INFO     [log.py:12] This is an info log
2017-06-06:17:07:02,158 CRITICAL [log.py:13] This is critical
2017-06-06:17:07:02,158 ERROR    [log.py:14] An error occurred

5
Sử dụng cái này để biết thêm chi tiết: formatter = logging.Formatter ('% (asctime) s,% (levelname) -8s [% (filename) s:% (module) s:% (funcName) s:% (lineno) d] % (message) s ')
Girish Gupta

có cách nào để thay đổi chỉ ở một vị trí ở đầu mã cho dù các thông báo ghi nhật ký có được in hay không? Tôi muốn có hai chế độ, một chế độ có nhiều bản in để xem chính xác chương trình làm gì; và một, khi nó đủ ổn định, nơi không có đầu ra nào được hiển thị.
Marie. P.

3
@ Marie.P. không hỏi các câu hỏi khác nhau trong nhận xét. Câu trả lời là cấp độ ghi nhật ký mặc dù.
bugmenot123

4

Để xây dựng trên những điều trên theo cách gửi ghi nhật ký gỡ lỗi thành tiêu chuẩn:

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
formatter = logging.Formatter(FORMAT)
ch.setFormatter(formatter)
root.addHandler(ch)

logging.debug("I am sent to standard out.")

Đưa phần trên vào một tệp được gọi là debug_logging_example.pytạo ra kết quả:

[debug_logging_example.py:14 -             <module>() ] I am sent to standard out.

Sau đó, nếu bạn muốn tắt đăng xuất bình luận root.setLevel(logging.DEBUG).

Đối với các tệp đơn (ví dụ: bài tập trong lớp), tôi thấy đây là một cách tốt hơn nhiều để thực hiện việc này thay vì sử dụng các print()câu lệnh. Nơi nó cho phép bạn tắt đầu ra gỡ lỗi ở một nơi duy nhất trước khi bạn gửi nó.


1

Đối với các nhà phát triển sử dụng PyCharm hoặc Eclipse pydev, phần sau sẽ tạo liên kết đến nguồn của câu lệnh nhật ký trong đầu ra nhật ký bảng điều khiển:

import logging, sys, os
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='%(message)s | \'%(name)s:%(lineno)s\'')
log = logging.getLogger(os.path.basename(__file__))


log.debug("hello logging linked to source")

Xem các siêu liên kết tệp nguồn Pydev trong bảng điều khiển Eclipse để biết thêm lịch sử và thảo luận.


0
# your imports above ...


logging.basicConfig(
    format='%(asctime)s,%(msecs)d %(levelname)-8s [%(pathname)s:%(lineno)d in 
    function %(funcName)s] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG
)

logger = logging.getLogger(__name__)

# your classes and methods below ...
# An naive Sample of usage:
try:
    logger.info('Sample of info log')
    # your code here
except Exception as e:
    logger.error(e)

Khác với các câu trả lời khác, điều này sẽ ghi lại đường dẫn đầy đủ của tệp và tên hàm có thể đã xảy ra lỗi. Điều này hữu ích nếu bạn có một dự án với nhiều hơn một mô-đun và một số tệp có cùng tên được phân phối trong các mô-đun này.

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.