Hướng dẫn python log levels - cấp nhật ký python
Trong quá trình vận hành và sử dụng phần mềm, "phần mềm" cũng có lúc khỏe lúc yếu, lúc hoạt động trơn tru, lúc lại dặt dẹo. Vậy có những cách nào để "phần mềm" thông báo trạng thái hoạt động của mình với người dùng, IT-OPs, lập trình viên ? Show Tại sao phải đặt log ?Thông thường trong quá trình xây dựng và phát triển phần mềm, các lập trình viên sẽ đặt các đoạn lệnh Vậy thì muốn check lỗi của phần mềm thì IT-OPs/Dev phải làm thế nào ? Nếu bạn mang câu hỏi này đi hỏi các lập trình viên có kinh nghiệm, câu trả lời dễ tìm thấy là "Ghi lỗi vào log file để có lỗi còn biết mà check & fix lỗi chứ" (Nhiều khi là đi "ăn vạ", "bắt đền" nếu lỗi phát sinh từ hệ thống khác). Một số lập trình viên có thói quen đặt câu lệnh print ra màn hình console các thông tin trong quá trình ứng dụng chạy để "debug chay", trước khi release thì thực hiện "rào" (thực hiện chuyển command thành comment) hoặc xóa các dòng lệnh print này. Thật là mất thời gian và nếu có sai sót lại mất thêm cả thời gian để fix lỗi. Log file có phải chỉ để ghi lỗi ?Log file thường được ưu tiên để ghi vào các lỗi nhưng có những hệ thống đặc biệt, ngoài log lỗi thì log file còn có thể chứa các thông tin liên quan đến các action của người dùng vào hệ thống.Ví dụ: Hệ thống fintech liên quan đến thanh toán giao dịch tiền, toàn bộ các action của người dùng trên phần mềm (hoặc web-app) đều cần phải ghi vào log: - Khi người dùng đăng nhập vào --> Ghi log lại để có thể theo dõi thói quen của người dùng. Từ đó có thể trích xuất ra thông tin trong thời gian từ mấy giờ đến mấy giờ người dùng sẽ sử dụng ứng dụng nhiều.- Khi thực hiện đặt lệnh thanh toán tiền --> Ghi log lại với thông tin của khác hàng + thông tin đích đến + thông tin số tiền để thực hiện đối soát dữ liệu mỗi ngày.... Qua hai đầu mục trên, chúng ta đã thấy tầm quan trọng của log file, vậy đặt log như thế nào cho hiệu quả và dễ dàng khai thác thông tin sau này? Ghi log thế nào cho hiệu quả?1. Format logĐể việc sử dụng log đạt hiệu quả, trong mỗi team hoặc mỗi công ty cần có một chuẩn đặt log chúng để dễ dàng sử dụng sau khi thu thập log về chung một hệ thống lưu trữ. Một cụm log nên chứa các thông tin sau:
Ví dụ: Một kiểu format log như sau:Datetime, Log Level, Component [code line] [Class/File name] [method/function...] Log Content [parameter input] [parameter output]
2. Chú ý phân loại log-levelNhư đã viết ở trên, log-level được định nghĩa và sử dụng tùy mục đích sử dụng và phân loại của từng công ty. Dưới đây là một cách định nghĩa (mà các bạn có thể tham khảo): DEBUG: Log dùng để debug (rất nhiều và hỗn loạn). Mục đích sử dụng thường là dành cho developer.Thông thường là đặt log level này enable trên môi trường LOCAL/DEVELOPING và disable ở PRODUCTION do số lượng dữ liệu log sẽ rất nhiều. Tuy nhiên đôi khi cũng phải enable lại level log này trên PRODUCTION để thực hiện ghi log và phát hiện ra các lỗi chỉ xảy ra trên PRODUCTION (Không phát sinh trên local).:
Ví dụ: Hệ thống dữ liệu trên PRODUCTION thường lớn hơn nhiều so với DEVELOPING nên số lượng trường hợp xảy ra khi áp dữ liệu vào phần mềm cũng nhiều hơn. Các test-case có thể chưa bao quát được hết các lỗi --> Việc đặt debug có thể giúp developer/tester có thể giả lập lại được chính xác toàn bộ thao tác, workflow của cụm dữ liệu khi đi vào/đi ra khỏi phần mềm. INFO:Log mang tính chất cung cấp thông tin chung, không nên mang ý nghĩa chỉ định lỗi. Ví dụ: Hành vi đăng nhâp vào hệ thống bởi tài khoản nào, version của phần mềm, ...: WARN (WARNING):Log lại các lỗi tiềm ẩn, có thể gây ra lỗi nhưng chưa ảnh hưởng đến trải nghiệm của người dùng.Ví dụ: Khách hàng cố tình nhấn nhiều lần vào button thanh toán trong khi người dùng không đủ điều kiện để thanh toán, các warning sẽ được log lại khi khách hàng "cố gắng" làm sai với hướng dẫn. ERROR:Log lại các event trên hệ thống đã gây ra lỗi tương đối lớn, có thể gây ảnh hưởng đến trải nghiệm của người dùng. Ví dụ: Khách hàng thanh toán tiền cho dịch vụ A nhưng không thể trừ tiền của khách hàng do hệ thống thanh toán đang quá tải. Mỗi ERROR sẽ được ghi vào log-files để sau này có thể đối soát được lỗi quá tải đã gây ảnh hưởng đến bao nhiêu khách hàng. FATAL/CRITICAL:Log chỉ định để ghi các lỗi nghiêm trọng, thậm chí là đã gây ra gián đoạn dịch vụ, treo/crash phần mềm. Ví dụ:Phần mềm sử dụng nhiều, chiếm dụng RAM nhiều, gây tràn memory, phần mềm trước khi bị tự tắt đi sẽ đưa ra các thông báo. Ghi chú: Với các case dạng này thì ngoài việc ghi vào log file thì nên thực hiện thông báo trực tiếp qua các kênh truyền thông với IT-Ops hoặc developer. 3. Thư viện hỗ trợ ghi log ?Một lập trình viên, việc ghi log theo format như trên là một thử thách khá lớn về format chuỗi, format thời gian, ....Hiểu được điều này các ngôn ngữ lập trình hiện đại sẽ có các module/library hỗ trợ việc ghi log cho đúng chuẩn và tiết kiệm thời gian, tài nguyên.Ví dụ: Thư viện Log4j cho java, thư viện log4net cho .Net của Apache,... Với ngôn ngữ lập trình Python, không cần phải cài đặt/thêm bớt library của hãng thứ 3 vào project của mình. Mọi thứ đã có sẵn trong module logging. Việc của lập trình viên chỉ là import vào sử dụng. Đặt log với logging trong pythonNgôn ngữ lập trình Python cung cấp một module cho phép các lập trình viên thực hiện việc đặt log trong ứng dụng của mình là logging. Sử dụng logging, lập trình viên sẽ được cung cấp các chức năng sau:
Chúng ta sẽ cùng nhau khám phá về logging qua các ví dụ dưới đây nhé. 1. Đặt log, đưa dữ liệu vào màn hình console.
Mặc định thì log sẽ được đẩy vào màn hình console, tất nhiên là màn hình console chỉ dành cho lập trình viên khi thực hiện debug nên các ứng dụng khi đưa lên PRODUCTION thì cần đặt log vào một log file
Lưu ý: Trường dữ liệu filename có thể là đường dẫn tuyệt đối hoặc tương đối đến vị trí đặt file. Mỗi lần có thêm log, mặc định là log mới sẽ thêm tiếp vào cuối file log cũ. Trường dữ liệu level sẽ thiết lập dữ liệu log nào được phép hiển thị theo từng cấp bậc. Ví dụ ở trên chúng ta thiết lập level=logging.INFO, ở dòng lệnh bên dưới có logging.debug('This is a debug log message.') nhưng trong file log không xuất hiện dòng lệnh này do thứ tự "cấp bậc" của INFO lớn hơn DEBUG. sẽ thiết lập dữ liệu log nào được phép hiển thị theo từng cấp bậc. Thứ tự các level được mặc định như sau: DEBUG --> INFO --> WARNING --> ERROR --> CRITICAL Tại một phiên làm việc, logging chỉ nhận một giá trị level, muốn thay đổi log level, tùy chỉnh nhiều hơn, chúng ta nên sử dụng các đối tượng handlers của logging. 2. Đối tượng logging handlersCác đối tượng logging handlers, chúng ta có thể tìm hiểu chúng ở đường dẫn sau: https://docs.python.org/3/library/logging.handlers.html Để tìm hiểu về các đối tượng này, chúng ta sẽ đi đến ví dụ dưới đây Các thông tin mới: 0: Class thực hiện đưa log vào file đặt log. 1: Class thực hiện đưa log ra màn hình console. 2 --> Khởi tạo một đối tượng đại diện cho module logging trong module (file .py) hiện tại.Đoạn script trên sẽ có output ra cả file và màn hình console. Theo như log-level thì trên file log sẽ in ra từ cụm 3, trên màn hình console sẽ in ra cụm 4Như đã nêu ở trên, trong phần log có thêm cụm thông tin tên file - dòng bao nhiêu [in .\handlers.py:26], có được đoạn dữ liệu này là do có đoạn cấu hình 3. Rotate log file.Sau một quãng thời gian làm việc, file log lớn quá gây khó khăn cho việc đọc/ghi/theo dõi log. Logging module cung cấp việc thực hiện tách file log thành nhiều file khác nhau theo kích thước hoặc thời gian. Thực hiện tách log file theo dung lượng.
Sau khi thực thi, log file sẽ bung ra dưới dạng: 7 --> lưu trữ backup tối đa thêm 10 file 8 --> một file log có dung lượng tối đa 2000B, sau khi đạt dung lượng này, sẽ thực hiện rotate log sang dạng file backup, file ban đầu sẽ tiếp tục được ghi log vào.Như ví dụ trên file log_filename.log sẽ chứa dữ liệu log mới nhất, log_filename.log.1 sẽ chứa dữ liệu log phía trước của log_filename.log. 8 --> một file log có dung lượng tối đa 2000B, sau khi đạt dung lượng này, sẽ thực hiện rotate log sang dạng file backup, file ban đầu sẽ tiếp tục được ghi log vào.Như ví dụ trên file log_filename.log sẽ chứa dữ liệu log mới nhất, log_filename.log.1 sẽ chứa dữ liệu log phía trước của log_filename.log. Đoạn tiếp theo của log: Tách log file theo thời gian
9 trong TimedRotatingFileHandler có thể nhận các giá trị sau:second (s)minute (m)hour (h)day (d)w0-w6 (weekday, 0=Monday)midnightsecond (s) minute (m) hour (h) day (d) w0-w6 (weekday, 0=Monday) midnight Bật tắt logging.Nếu không cần đến logging –> tắt chế độ ghi log: 0 0Khi cần bật lại: 1 1Kết luậnTrong nội dung bài viết này, tôi vừa trình bày với các bạn một số vấn đề liên quan đến tầm quan trọng việc ghi log trong xây dựng ứng dụng phần mềm. Đi kèm với phần lý thuyết là phần thực hành liên quan đến hướng dẫn sử dụng module logging trong ngôn ngữ lập trình Python. Với các bạn đang sử dụng ngôn ngữ lập trình Java hoặc .NET các bạn có thể tìm hiểu cách sử dụng của 2 thư viện 2 và 3 để tự xây dựng cách chức năng ghi log theo ý của mình. Cảm ơn các bạn đã đọc bài viết. |