Có nhật ký tốt là rất quan trọng để theo dõi các ứng dụng, hiểu hành vi sản xuất và bắt lỗi. Đăng nhập vào python được thực hiện tốt và được ghi chép đầy đủ. Tuy nhiên, đôi khi bạn chỉ cần hoàn thành công việc nhanh chóng và bạn không có thời gian để đọc tài liệu chính thức xuất sắc nhưng khá dài
Ghi nhật ký rất quan trọng để bạn hiểu về hành vi của ứng dụng và để giúp các hoạt động CNTT có một bảng điều khiển chuyên dụng để nhanh chóng theo dõi và phân tích các vấn đề của ứng dụng
Trong bài viết này, chúng tôi sẽ cố gắng tìm ra các công thức nhanh chóng để ghi nhật ký hiệu quả. Trước khi chúng tôi bắt đầu, chỉ cần một số thuật ngữ cơ bản để ghi nhật ký python
- Người khai thác gỗ. Các tác nhân chính cung cấp một số phương pháp để cho phép ghi nhật ký thời gian chạy từ các ứng dụng của bạn
- xử lý. Họ lấy thông điệp bản ghi của bạn và định tuyến chúng đến các vị trí cụ thể, chẳng hạn như tệp hoặc bảng điều khiển
- Trình định dạng. Chúng làm cho nhật ký của bạn xuất hiện theo cách bạn muốn, ở định dạng cụ thể mà bạn có thể xác định
Không có gì khó chịu, chúng ta hãy đi thẳng vào nó và nhận một số công thức nhanh chóng để đăng nhập ứng dụng python của bạn ngay lập tức
Cách nhanh nhất để ghi nhật ký cho các ứng dụng đơn giản là sử dụng ghi nhật ký. basicConfig, nó sẽ tạo StreamHandler [và FileHandler nếu chúng ta chỉ định tên tệp] và thêm nó vào bộ ghi ROOT.
Cấu hình như sau.
import logging
logging.basicConfig[filename='my_log_file.log',level=logging.INFO]
Sau đó sử dụng nó như sau
import logging
from time import sleep
def setup_logger[]:
logging.basicConfig[filename='my_log_file.log', level=logging.INFO]
def my_app_logic[]:
logging.info["Just entered the function"]
sleep[0.1]
logging.info["Just after the sleep"]
try:
res = 1 / 0
except ZeroDivisionError:
logging.exception["Attempted division by zero"]
if __name__ == '__main__':
setup_logger[]
my_app_logic[]
Điều này sẽ dẫn đến đầu ra sau trên my_log_file của chúng tôi. tệp nhật ký
INFO:root:Just entered the function
INFO:root:Just after the sleep
ERROR:root:Attempted division by zero
Traceback [most recent call last]:
File "/xxxx/simple_application.py", line 14, in my_app_logic
res = 1 / 0
ZeroDivisionError: division by zero
Trong trường hợp bạn cũng muốn hiển thị thời gian, chỉ cần thêm định dạng như sau
logging.basicConfig[filename='my_log_file.log', format='%[asctime]s - %[message]s', level=logging.INFO]
Cái nào sẽ thay đổi thông báo đầu ra trong tệp nhật ký của bạn thành
2020-07-20 17:05:29,686 - Just entered the function
2020-07-20 17:05:29,790 - Just after the sleep
2020-07-20 17:05:29,790 - Attempted division by zero
...
Khi nào thì sử dụng nó. Các ứng dụng đơn giản mà bạn chỉ cần thực hiện một số thao tác ghi nhật ký mà không cần quá nhiều thao tác. Sử dụng tối thiểu các thư viện bên ngoài và bạn không cần kiểm soát quá nhiều về cách thực hiện ghi nhật ký
Khi nào không sử dụng nó. Khi bạn cần kiểm soát chi tiết về cách thực hiện ghi nhật ký hoặc bất kỳ ứng dụng đa quy trình nào
kịch bản 2. Tôi có một ứng dụng, đơn/đa luồng đang sử dụng một số thư viện và tôi muốn thực hiện một số thao tác ghi nhật kýNếu ứng dụng của bạn bắt đầu phức tạp hơn một chút và bạn cần kiểm soát nhiều hơn đối với việc ghi nhật ký, chúng ta nên tránh sử dụng trình ghi ROOT, thay vào đó, hãy tạo trình ghi nhật ký của riêng chúng tôi như sau
logger = logging.getLogger['non_simple_example']
Hãy thêm trình xử lý để gửi nhật ký tới bảng điều khiển và/hoặc tới tệp, trình định dạng để chỉ định định dạng ghi nhật ký yêu thích của chúng ta
# create console handler and set level to info
stream_handler = logging.StreamHandler[]
stream_handler.setLevel[logging.INFO]
# create file handler and set level to info
file_handler = logging.FileHandler[filename='my_log_name.log']
file_handler.setLevel[logging.DEBUG]
# create formatter
formatter = logging.Formatter['%[asctime]s - %[name]s - %[levelname]s - %[message]s']
# add formatters to our handlers
stream_handler.setFormatter[formatter]
file_handler.setFormatter[formatter]
# add Handlers to our logger
logger.addHandler[stream_handler]
logger.addHandler[file_handler]
Sau đó, chỉ cần sử dụng trình ghi nhật ký trong ứng dụng của bạn, ví dụ
logger.info["Info message"]
logger.debug["Debug message"]
Chúng tôi sẽ có những thứ được ghi vào bảng điều khiển/tệp theo cấp độ ghi nhật ký và cấu hình trình xử lý. Trong ví dụ trước, trình xử lý tệp có mức GỠ LỖI, trong khi trình xử lý bảng điều khiển có mức INFO. Điều này có nghĩa là mọi nhật ký có mức GỠ LỖI sẽ không được hiển thị trong bảng điều khiển nhưng nó sẽ được hiển thị trong tệp nhật ký
Đây là đầu ra của giao diện điều khiển
Và đầu ra sau trong tệp nhật ký của chúng tôi
2020-07-20 17:13:34,439 - non_simple_example - INFO - Info message
2020-07-20 17:13:34,439 - non_simple_example - DEBUG - Debug message
Tìm mã đầy đủ tại đây.
Cách tiếp cận này cũng hoạt động rất tốt với các ứng dụng đa luồng, vì thực tế mô-đun ghi nhật ký là luồng an toàn. Tuy nhiên, nó sẽ không hoạt động để ghi nhật ký nhiều quy trình đòi hỏi nhiều nỗ lực hơn.
Khi nào thì sử dụng nó. Khi bạn cần thêm một số quyền kiểm soát đối với việc ghi nhật ký và bạn muốn tránh sử dụng/làm ô nhiễm trình ghi nhật ký gốc
Khi nào không sử dụng nó. Nếu bạn có nhiều quy trình
kịch bản 3. Nhật ký của tôi ngày càng lớn, tôi có thể làm gì?Rất dễ dàng, hãy chuyển từ một FileHandler đơn giản sang một RotatingFileHandler tinh vi hơn sẽ chuyển các tệp nhật ký khi chúng đạt đến một kích thước cụ thể
import logging
from time import sleep
def setup_logger[]:
logging.basicConfig[filename='my_log_file.log', level=logging.INFO]
def my_app_logic[]:
logging.info["Just entered the function"]
sleep[0.1]
logging.info["Just after the sleep"]
try:
res = 1 / 0
except ZeroDivisionError:
logging.exception["Attempted division by zero"]
if __name__ == '__main__':
setup_logger[]
my_app_logic[]
0Bạn có thể sử dụng TimedRotatingFileHandler nếu bạn muốn chuyển nhật ký vào mỗi cuối ngày/tuần/tháng
import logging
from time import sleep
def setup_logger[]:
logging.basicConfig[filename='my_log_file.log', level=logging.INFO]
def my_app_logic[]:
logging.info["Just entered the function"]
sleep[0.1]
logging.info["Just after the sleep"]
try:
res = 1 / 0
except ZeroDivisionError:
logging.exception["Attempted division by zero"]
if __name__ == '__main__':
setup_logger[]
my_app_logic[]
1Tình huống 4. Tôi có ứng dụng đa quy trình và tôi cần đăng nhậpGhi nhật ký từ các quy trình khác nhau không phải là chuyện nhỏ và nó cần thêm một số nỗ lực. Tôi khuyên bạn không nên sử dụng giải pháp nhanh và bẩn mà hãy thực sự đọc qua tài liệu chính thức giải thích chi tiết chính xác điều gì đang xảy ra và một số chiến lược để giải quyết thách thức là gì
Một cách thú vị để giải quyết vấn đề này là sử dụng WatchedFileHandler và sử dụng một tiện ích bên ngoài như logrotate để thực sự xoay nhật ký theo cấu hình