Căn chỉnh trung tâm đăng nhập python

Khi các ứng dụng trở nên phức tạp hơn, việc có các bản ghi tốt có thể rất hữu ích, không chỉ khi gỡ lỗi mà còn cung cấp thông tin chi tiết về vấn đề/hiệu suất của ứng dụng. Thư viện chuẩn Python đi kèm với một mô-đun ghi nhật ký cung cấp hầu hết các tính năng ghi nhật ký cơ bản và rất tiện dụng nhưng chứa một số điều kỳ quặc có thể khiến bạn đau đầu hàng giờ

Qua

Sơn Nguyễn Kim

Son có kỹ năng cao về kỹ thuật phần mềm và thuật toán ML và luôn cố gắng hết sức để giải quyết vấn đề bằng cách tiếp cận đơn giản

CHIA SẺ

CHIA SẺ

Khi các ứng dụng trở nên phức tạp hơn, việc có các bản ghi tốt có thể rất hữu ích, không chỉ khi gỡ lỗi mà còn cung cấp thông tin chi tiết về các sự cố/hiệu suất của ứng dụng

Thư viện chuẩn Python đi kèm với mô-đun ghi nhật ký cung cấp hầu hết các tính năng ghi nhật ký cơ bản. Bằng cách thiết lập chính xác, một thông báo nhật ký có thể mang lại nhiều thông tin hữu ích về thời gian và vị trí nhật ký được kích hoạt cũng như bối cảnh nhật ký, chẳng hạn như quy trình/luồng đang chạy

Mặc dù có những ưu điểm, nhưng mô-đun ghi nhật ký thường bị bỏ qua vì phải mất một thời gian để thiết lập đúng cách và mặc dù đã hoàn thành, theo ý kiến ​​của tôi, tài liệu ghi nhật ký chính thức tại https. // tài liệu. con trăn. org/3/thư viện/ghi nhật ký. html không thực sự cung cấp các phương pháp hay nhất về ghi nhật ký hoặc nêu bật một số điều bất ngờ khi ghi nhật ký

Hướng dẫn ghi nhật ký Python này không phải là một tài liệu hoàn chỉnh về mô-đun ghi nhật ký mà là hướng dẫn “bắt đầu” giới thiệu một số khái niệm ghi nhật ký cũng như một số “khắc phục sự cố” cần lưu ý. Bài đăng sẽ kết thúc với các phương pháp hay nhất và chứa một số gợi ý cho các chủ đề ghi nhật ký nâng cao hơn

Xin lưu ý rằng tất cả các đoạn mã trong bài đăng giả sử rằng bạn đã nhập mô-đun ghi nhật ký

import logging

Các khái niệm về ghi nhật ký Python

Phần này cung cấp tổng quan về một số khái niệm thường gặp trong mô-đun ghi nhật ký

Cấp độ ghi nhật ký Python

Cấp độ nhật ký tương ứng với “tầm quan trọng” mà nhật ký được đưa ra. nhật ký "lỗi" sẽ khẩn cấp hơn nhật ký "cảnh báo", trong khi nhật ký "gỡ lỗi" chỉ hữu ích khi gỡ lỗi ứng dụng

Có sáu cấp độ nhật ký trong Python; . NOTSET=0, DEBUG=10, INFO=20, WARN=30, ERROR=40, và CRITICAL=50

Python Logging's log levels

Tất cả các cấp đều khá đơn giản (DEBUG < INFO < WARN ) ngoại trừ NOTSET, tính đặc biệt của nó sẽ được giải quyết tiếp theo

Định dạng nhật ký Python

Trình định dạng nhật ký về cơ bản làm phong phú thông điệp tường trình bằng cách thêm thông tin ngữ cảnh vào đó. Có thể hữu ích khi biết nhật ký được gửi khi nào, ở đâu (tệp Python, số dòng, phương thức, v.v. ) và ngữ cảnh bổ sung như luồng và quy trình (có thể cực kỳ hữu ích khi gỡ lỗi ứng dụng đa luồng)

Ví dụ: khi nhật ký “hello world” được gửi qua trình định dạng nhật ký

"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"

nó sẽ trở thành

2018-02-07 19:47:41,864 - a.b.c - WARNING - :1 - hello world
Python logging message formatting

Trình xử lý ghi nhật ký Python

Trình xử lý nhật ký là thành phần ghi/hiển thị nhật ký một cách hiệu quả. Hiển thị nó trong bảng điều khiển (thông qua StreamHandler), trong tệp (thông qua FileHandler) hoặc thậm chí bằng cách gửi email cho bạn qua SMTPHandler, v.v.

Mỗi trình xử lý nhật ký có 2 trường quan trọng

  • Một trình định dạng thêm thông tin ngữ cảnh vào nhật ký
  • Cấp độ nhật ký lọc ra các nhật ký có cấp độ thấp hơn. Vì vậy, trình xử lý nhật ký có cấp INFO sẽ không xử lý nhật ký GỠ LỖI
The Python logging handler

Thư viện tiêu chuẩn cung cấp một số trình xử lý đủ cho các trường hợp sử dụng phổ biến. https. // tài liệu. con trăn. org/3/thư viện/ghi nhật ký. người xử lý. html#module-ghi nhật ký. người xử lý. Những cái phổ biến nhất là StreamHandler và FileHandler

console_handler = logging.StreamHandler()
file_handler = logging.FileHandler("filename")

Trình ghi nhật ký Python

Logger có lẽ là thứ sẽ được sử dụng trực tiếp thường xuyên nhất trong mã và cũng là thứ phức tạp nhất. Một logger mới có thể được lấy bằng cách

toto_logger = logging.getLogger("toto")

Một logger có ba lĩnh vực chính

  • tuyên truyền. Quyết định xem nhật ký có nên được truyền tới cha mẹ của người ghi nhật ký hay không. Theo mặc định, giá trị của nó là True
  • Một cấp độ. Giống như cấp độ trình xử lý nhật ký, cấp độ trình ghi nhật ký được sử dụng để lọc ra các nhật ký “ít quan trọng hơn”. Ngoại trừ, không giống như trình xử lý nhật ký, mức độ chỉ được kiểm tra tại trình ghi nhật ký “con”; . Đây là một hành vi không trực quan
  • xử lý. Danh sách các trình xử lý mà một bản ghi sẽ được gửi đến khi nó đến một bộ ghi. Điều này cho phép xử lý nhật ký linh hoạt—ví dụ: bạn có thể có một trình xử lý nhật ký tệp ghi lại tất cả các nhật ký GỠ LỖI và một trình xử lý nhật ký email sẽ chỉ được sử dụng cho các nhật ký QUAN TRỌNG. Về vấn đề này, mối quan hệ trình xử lý trình ghi nhật ký tương tự như mối quan hệ giữa nhà xuất bản và người tiêu dùng. Nhật ký sẽ được phát tới tất cả các trình xử lý sau khi vượt qua kiểm tra cấp độ trình ghi
Python logging's process

Một logger là duy nhất theo tên, nghĩa là nếu một logger có tên “toto” đã được tạo, các lệnh gọi sau đó của

"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
1 sẽ trả về cùng một đối tượng

assert id(logging.getLogger("toto")) == id(logging.getLogger("toto"))

Như bạn có thể đoán, logger có một hệ thống phân cấp. Trên cùng của hệ thống phân cấp là trình ghi nhật ký gốc, có thể được truy cập thông qua ghi nhật ký. nguồn gốc. Trình ghi nhật ký này được gọi khi các phương thức như

"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
2 được sử dụng. Theo mặc định, cấp độ nhật ký gốc là WARN, vì vậy mọi nhật ký có cấp độ thấp hơn (ví dụ: qua
"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
3) sẽ bị bỏ qua. Một điểm đặc biệt khác của trình ghi nhật ký gốc là trình xử lý mặc định của nó sẽ được tạo lần đầu tiên khi nhật ký có mức lớn hơn WARN được ghi. Sử dụng bộ ghi gốc trực tiếp hoặc gián tiếp thông qua các phương pháp như
"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
2 thường không được khuyến nghị

Theo mặc định, khi một bộ ghi mới được tạo, cha của nó sẽ được đặt thành bộ ghi gốc

"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
0

Tuy nhiên, thiết bị ghi nhật ký sử dụng “ký hiệu dấu chấm”, nghĩa là thiết bị ghi nhật ký có tên “a. b” sẽ là con của logger “a. ” Tuy nhiên, điều này chỉ đúng nếu logger “a” đã được tạo, nếu không thì “ab” cha vẫn là gốc

"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
1

Khi bộ ghi nhật ký quyết định xem nhật ký có vượt qua được hay không theo kiểm tra mức độ (e. g. , nếu cấp nhật ký thấp hơn cấp nhật ký, nhật ký sẽ bị bỏ qua), nó sử dụng “mức hiệu quả” thay vì cấp thực tế. Mức hiệu quả giống như mức của bộ ghi nếu mức đó không phải là NOTSET, tôi. e. , tất cả các giá trị từ GỠ LỖI cho đến QUAN TRỌNG;

Theo mặc định, trình ghi nhật ký mới có mức NOTSET và vì trình ghi nhật ký gốc có mức CẢNH BÁO, mức hiệu quả của trình ghi nhật ký sẽ là WARN. Vì vậy, ngay cả khi một trình ghi nhật ký mới có một số trình xử lý được đính kèm, những trình xử lý này sẽ không được gọi trừ khi mức nhật ký vượt quá WARN

"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
2

Theo mặc định, cấp độ nhật ký sẽ được sử dụng để quyết định nhật ký đi qua. Nếu cấp nhật ký thấp hơn cấp nhật ký, nhật ký sẽ bị bỏ qua

Các phương pháp hay nhất về ghi nhật ký Python

Mô-đun ghi nhật ký thực sự rất tiện dụng, nhưng nó chứa một số điều kỳ quặc có thể khiến ngay cả những nhà phát triển Python giỏi nhất cũng phải đau đầu trong nhiều giờ. Dưới đây là những cách thực hành tốt nhất để sử dụng mô-đun này theo ý kiến ​​của tôi

  • Định cấu hình bộ ghi gốc nhưng không bao giờ sử dụng nó trong mã của bạn—e. g. , không bao giờ gọi một hàm như
    "%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
    
    5, hàm này thực sự gọi trình ghi nhật ký gốc ở hậu trường. Nếu bạn muốn bắt các thông báo lỗi từ các thư viện mà bạn sử dụng, hãy đảm bảo cấu hình trình ghi nhật ký gốc để ghi vào một tệp chẳng hạn, để giúp việc gỡ lỗi dễ dàng hơn. Theo mặc định, trình ghi nhật ký gốc chỉ xuất ra thành
    "%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
    
    6, vì vậy nhật ký có thể bị mất dễ dàng
  • Để sử dụng nhật ký, hãy đảm bảo tạo một nhật ký mới bằng cách sử dụng
    "%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
    
    7. Tôi thường sử dụng
    "%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
    
    8 làm tên nhật ký, nhưng bất kỳ thứ gì cũng có thể được sử dụng, miễn là nó phù hợp. Để thêm nhiều trình xử lý hơn, tôi thường có một phương thức trả về trình ghi nhật ký (bạn có thể tìm thấy ý chính trên https. //ý chính. github. com/nguyenkims/e92df0f8bd49973f0c94bddf36ed7fd0)
"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
7

Sau khi bạn có thể tạo một logger mới và sử dụng nó

"%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"
0
  • Sử dụng các lớp RotatingFileHandler, chẳng hạn như TimedRotatingFileHandler được sử dụng trong ví dụ thay vì FileHandler, vì nó sẽ tự động xoay tệp cho bạn khi tệp đạt đến giới hạn kích thước hoặc làm điều đó hàng ngày
  • Sử dụng các công cụ như Sentry, Airbrake, Raygun, v.v. , để tự động ghi nhật ký lỗi cho bạn. Điều này đặc biệt hữu ích trong ngữ cảnh của ứng dụng web, nơi nhật ký có thể rất dài dòng và nhật ký lỗi có thể dễ dàng bị mất. Một ưu điểm khác của việc sử dụng các công cụ này là bạn có thể nhận thông tin chi tiết về các giá trị biến trong lỗi để bạn có thể biết URL nào gây ra lỗi, người dùng nào lo ngại, v.v.

Nếu bạn quan tâm đến các phương pháp hay nhất khác, hãy đọc 10 lỗi phổ biến nhất mà các nhà phát triển Python mắc phải của đồng nghiệp Toptaler Martin Chikilian

Đọc thêm trên Blog Kỹ thuật Toptal

  • Đảm bảo mã sạch. Nhìn vào Python, được tham số hóa
  • 10 sai lầm hàng đầu mà các nhà phát triển Django mắc phải
  • Hướng dẫn đa luồng và đa xử lý Python
  • Khai thác tối đa tệp nhật ký PHP của bạn. Hướng dẫn thực hành
  • Quét web hiện đại với Python và Selenium

Hiểu những điều cơ bản

Công cụ sửa lỗi là gì?

Công cụ sửa lỗi là công cụ cho phép nhà phát triển phát hiện lỗi và điều tra sự cố. Nó có thể là một công cụ dòng lệnh như gdb, pdb (dành cho Python) hoặc có thể được nhúng trong IDE (Visual Studio, bộ ý tưởng, v.v.)

Nhật ký gỡ lỗi là gì?

Đây chỉ đơn giản là đầu ra của chương trình, một phiên bản tốt hơn của “bản in” theo thuật ngữ của giáo dân. Trong ngữ cảnh của ứng dụng web, nhật ký này thường chứa thông tin yêu cầu đến như đường dẫn yêu cầu, thời gian yêu cầu, trạng thái HTTP, v.v.

"Đăng nhập" trong Python là gì?

Ghi nhật ký là một mô-đun trong thư viện chuẩn Python cung cấp nhật ký có định dạng phong phú với bộ lọc linh hoạt và khả năng chuyển hướng nhật ký sang các nguồn khác như nhật ký hệ thống hoặc email

Trình gỡ lỗi Python là gì?

Trình gỡ lỗi python phổ biến nhất là pdb. Hiện tại có một số dự án đang làm việc để cải thiện khả năng sử dụng của pdb bằng cách cung cấp tính năng hoàn thành tab, cú pháp màu, duyệt mã hoặc gỡ lỗi từ xa. Các dự án này bao gồm ipdb, pudb và wdb. Ngoài ra còn có một số trình gỡ lỗi dành riêng cho IDE như công cụ pydev hoặc PTVS

Thẻ

Ghi nhật ký Python

Người làm việc tự do? Tìm công việc tiếp theo của bạn.

Việc làm Lập trình viên Python

Xem thông tin đầy đủ

Sơn Nguyễn Kim

Nhà phát triển Python

Giới thiệu về tác giả

Son có kỹ năng cao về công nghệ phần mềm và các thuật toán ML, đồng thời luôn cố gắng hết sức để giải quyết các vấn đề bằng cách tiếp cận đơn giản nhưng hiệu quả, giúp mã có thể duy trì trong thời gian dài. Là một doanh nhân, anh tận tâm với công việc và hiểu rõ tầm quan trọng của tinh thần trách nhiệm và sự chủ động. Anh ấy có thể giao tiếp hiệu quả với cả hai bên kinh doanh và kỹ thuật

thuê con trai

Bình luận

Laszlo Marai

hửm. Tại sao bạn lại định cấu hình trình ghi nhật ký của mình từ mã (giống như cách bạn thực hiện trong hàm get_logger và hai hàm get_* khác) thay vì sử dụng từ điển (xem ghi nhật ký. cấu hình. dictConfig) hoặc tệp cấu hình (ghi nhật ký. cấu hình. fileConfig) như được mô tả tại đây. https. // tài liệu. con trăn. org/3/thư viện/ghi nhật ký. cấu hình. html

Laszlo Marai

hửm. Tại sao bạn lại định cấu hình trình ghi nhật ký của mình từ mã (giống như cách bạn thực hiện trong hàm get_logger và hai hàm get_* khác) thay vì sử dụng từ điển (xem ghi nhật ký. cấu hình. dictConfig) hoặc tệp cấu hình (ghi nhật ký. cấu hình. fileConfig) như được mô tả tại đây. https. // tài liệu. con trăn. org/3/thư viện/ghi nhật ký. cấu hình. html

nguyễn kim sơn

Có, hoàn toàn có thể định cấu hình trình ghi nhật ký từ tệp cấu hình (. yml,. json) và đó thực sự là cách tốt nhất để làm như vậy. Nhưng vì tôi muốn tất cả các đoạn mã có thể được sử dụng dưới dạng sao chép/dán nên tôi chọn cấu hình bộ ghi trực tiếp trong mã

nguyễn kim sơn

Có, hoàn toàn có thể định cấu hình trình ghi nhật ký từ tệp cấu hình (. yml,. json) và đó thực sự là cách tốt nhất để làm như vậy. Nhưng vì tôi muốn tất cả các đoạn mã có thể được sử dụng dưới dạng sao chép/dán nên tôi chọn cấu hình bộ ghi trực tiếp trong mã

Vô danh

"Theo mặc định, cấp độ nhật ký sẽ được sử dụng để quyết định nhật ký đi qua. " có thể muốn đại tu điều đó

Sven

Đoạn mã thực sự không tốt lắm. vấn đề 1. gọi 2 lần get_logger(__name__) bên trong một tệp hoặc chỉ gọi một hàm chứa get_logger(__name__) sẽ dẫn đến có nhiều phiên bản của cùng một trình ghi -> thông báo lần đầu được in 1x, lần thứ 2 thông báo được in 2x, lần thứ 3 . giải pháp. dict của logger đang sử dụng và trả lại logger nếu đã có trong dict nếu không tạo 1 và lưu trữ trong dict Vấn đề 2. tạo một phiên bản mới của TimedRotatingFileHandler cho mỗi logger sử dụng cùng một tệp sẽ dẫn đến việc ghi đè các tệp khi được gọi. giải pháp. xác định 1 phiên bản TimedRotatingFileHandler và sử dụng nó cho tất cả các logger. hoặc sử dụng một tên tệp khác cho mỗi bộ ghi (nhưng trong dự án lớn hơn, bạn sẽ có rất nhiều tệp) Vấn đề 3. ConsoleHandler giống như Sự cố 2 không dẫn đến sự cố lớn nhưng không thể là Phương pháp hay nhất để có nhiều phiên bản nếu một phiên bản thực hiện cùng một công việc. Vì vậy, đoạn mã này rõ ràng là không bao giờ được sử dụng trong một dự án thực tế

thất nghiệp

Rất đẹp. Cám ơn vì đã chia sẻ

Arthur Bowers

Tôi đã đặt cấp độ của mình thành ghi nhật ký. LỖI nhưng nó vẫn đang ghi thông báo INFO. làm thế nào mà?

phê bình

Đây là một trong những hướng dẫn đăng nhập tồi tệ nhất mà tôi từng thấy

Keith A. cổng tây

tại sao? . Sven đã đưa ra một lời phê bình tốt đẹp. hoặc ít nhất là trỏ đến một cái tốt hơn