Log rất quan trọng trong ứng dụng vậy ghi log thế nào cho đúng?
Overview
1. Log là gì? Tại sao cần thiết ghi log?
Log là những bạn dạng ghi, tài liệu về sự việc khiếu nại xẩy ra trong lúc phần mềm của người tiêu dùng hoạt động và sinh hoạt.
Tại sao cần được ghi log?
Trong quy trình hoạt động và sinh hoạt luôn luôn trực tiếp sở hữu những trường hợp bất ngờ xẩy ra, những nước ngoài lệ chúng ta ko tính cho tới và khi ê log thể hiện nay tầm quan trọng của tớ. Nó giúp đỡ bạn tìm hiểu rời khỏi nguyên vẹn nhân trường hợp bất ngờ giúp đỡ bạn xử lý nó. Trong môi trường xung quanh develop chúng ta trọn vẹn rất có thể dùng những khí cụ tuy nhiên IDE tương hỗ nhằm debug. Nhưng bên trên môi trường xung quanh product các bạn ko thể tái ngắt hiện nay được lỗi xẩy ra. Ví dụ: Khách sản phẩm gửi chi phí ko thành công xuất sắc các bạn ko thể đòi hỏi quý khách gửi lại nhằm các bạn đánh giá được. Vậy nếu như ghi log chính bạn cũng có thể trải qua ê tìm hiểu rời khỏi nguyên vẹn nhân lỗi nhằm xử lý.
Thường là API Enpoint, Controller, Listener(DB, message queue)... tiếp tục ghi lại những vấn đề tương quan cho tới tài liệu nguồn vào và sản phẩm trả ra phía bên ngoài.
Với một API bạn cũng có thể ghi những vấn đề như request/response body toàn thân, header, ip, parameters, url, vấn đề người tiêu dùng, thời hạn xử lý.
Với những input kể từ database, message queue này ê thì bạn cũng có thể ghi input object và output object.
Chú ý: Mỗi một luồng xử lý bạn phải tạo nên cho tới nó một ID nhằm đáp ứng cho tới việc hiểu log đơn giản và dễ dàng rộng lớn.
Ví dụ như sau:
1INFO: Add user with request { "user": "test1", "email": "[email protected]" }
2INFO: Add user with request { "user": "test2", "email": "[email protected]" }
3INFO: Get connection to lớn database successfully.
4INFO: Success
5INFO: Get connection to lớn database successfully
6ERROR: Thư điện tử already exist
Như ví dụ bên trên bản thân sở hữu 2 request tạo nên user đôi khi và 1 request thành công xuất sắc, một request thất bại tuy nhiên các bạn sẽ ko hiểu rằng loại này thành công xuất sắc, loại này thất bại. Nếu lượng request nhiều lên nữa và log bao gồm nhiều vấn đề thì tiếp tục đặc biệt khó khăn nhằm rất có thể hiểu và tìm hiểu rời khỏi lỗi.
Khi tạo nên ID cho từng request và ghi nhập log tất cả chúng ta tiếp tục đơn giản và dễ dàng rất có thể tra cứu vớt được luồng xử lý.
1[00000001] - INFO: Add user with request { "user": "test1", "email": "[email protected]" }
2[00000002] - INFO: Add user with request { "user": "test2", "email": "[email protected]" }
3[00000002] - INFO: Get connection to lớn database successfully.
4[00000002] - INFO: Success
5[00000001] - INFO: Get connection to lớn database successfully.
6[00000001] - ERROR: Thư điện tử already exist
Với những tủ sách ghi log của JAVA (với những framework blocking dùng thread cho tới từng request như Spring) thì khá dễ dàng dàng
1SLF4j:MDC 2LOG4J2:ThreadContext 3 4publicvoidfilter(){ 5StringlogId=generateLogId(); 6MDC.put("log_id",logID); 7/// 8/// Do some things 9///10// Nếu hàm rất có thể văng exception thì cho tới nhập block try finnally11MDC.clear();12}
Với những hàm non-blocking thì những các bạn sẽ nên truyền logId trải qua param và ghi tay chân. (Nếu các bạn tìm kiếm được cách tiếp theo đơn giản và dễ dàng hơn nữa thì báo bản thân nhé).
Đây là 1 trong những hàm helper khi sử dụng vertx, khi request nhập thì tiếp tục mix logId nhập RoutingContext và khi hàm trả lại sản phẩm thì lấy logId rời khỏi và dùng.
1packagecom.truongnq; 2 3importio.vertx.core.AsyncResult; 4importio.vertx.core.Handler; 5importio.vertx.core.buffer.Buffer; 6importio.vertx.ext.web.RoutingContext; 7importlombok.extern.slf4j.Slf4j; 8importcom.truongnq.Constant; 910importjava.util.function.Function;1112/**
13 * @author truongnq
14 * Date: 19/01/2021
15 */16@Slf4j17publicclassResultHandler{1819privateResultHandler(){20}2122/**
23 * This method generates handler for async methods in REST APIs.
24 */25publicstatic<T>Handler<AsyncResult<T>>create(RoutingContextcontext,Function<T,Buffer>converter){26returncreate(context,converter,200);27}2829publicstatic<T>Handler<AsyncResult<T>>create(RoutingContextctx,30Function<T,Buffer>converter,31intstatus){32returnres->{33// Lấy logId và thời hạn request kể từ context34finalStringlogId=ctx.get(Constant.LOG_TOKEN_NAME);35finalLongstartTime=ctx.get(Constant.REQUEST_TIME);36try{37if(res.succeeded()){38Bufferresponse=converter.apply(res.result());39log.info("[{}] - Response: {}",logId,response);40ctx.response().setStatusCode(status).end(response);41}else{42ctx.fail(res.cause());43}44}catch(Throwablecause){45ctx.fail(cause);46}finally{47longprocessTime=System.currentTimeMillis()-startTime;48log.info("[{}] - Request finish in: {}",logId,processTime);49}50};51}52}
Các bước xử lý trong những hàm, những service
Ngoài những đầu tiêu thụ tài liệu kể từ những mối cung cấp bên phía ngoài phần mềm thì những service, những hàm nội cỗ cũng nên ghi log input và output. Thường được ghi với những nấc log thấp hơn hoàn toàn như DEBUG. Nó tiếp tục tương hỗ tìm hiểu và xử lý lỗi tương quan cho tới logic và nhiệm vụ. Ghi rõ rệt quá trình xử lý, và nếu như có tương đối nhiều case trả về nằm trong sản phẩm cần thiết ghi thêm thắt nguyên vẹn nhân.
1// Đây là 1 trong những hàm nhập websocket server dùng Netty. 2// Hàm gửi thông tin cho tới những websocket client 3publicbooleannotify(Set<ChannelId>sessionIds,@NonnullNotify<?>notifyMessage){ 4longlogId=notify.getId(); 5if(null==sessionIds||sessionIds.isEmpty()){ 6// Thành công tuy nhiên đó là case quan trọng đặc biệt vì thế không tồn tại client này được truyền nhập. 7log.debug("[{}] - Empty sessions",logId); 8returntrue; 9}10// Chuẩn bị tài liệu nhằm gửi11log.debug("[{}] - Prepare data to lớn send",logId);12sessionIds.forEach(session::send);13log.debug("[{}] - All message are scheduled to lớn send",logId);14// Thành công gửi thông tin cho tới những client15returntrue;16}
Các vấn đề tương quan cho tới hưởng thụ người tiêu dùng, hoặc tổng hợp cho tới mục tiêu sale.
Khi một tính năng tốn rất nhiều thời hạn nhằm xử lý hoặc thông thường xuyên lỗi tất cả chúng ta cũng cần được ghi lại nhằm tách tác động cho tới cảm biến người tiêu dùng.
Các vấn đề tổng hợp rất có thể dùng cho tới sale như con số thanh toán, lô hàng trong thời gian ngày, con số người tiêu dùng trực tuyến ... cũng rất có thể được ghi lại.
Thông tin cậy tương quan khi thay cho thay đổi dữ liệu
Khi sở hữu những thay cho thay đổi tài liệu (CRUD) tất cả chúng ta cần thiết lưu vấn đề mối cung cấp tạo nên đòi hỏi, rất có thể từ là một người tiêu dùng hoặc từ là một khối hệ thống không giống. Các vấn đề thông thường lưu như userName, serviceId, thời hạn, hành động (Thêm mới mẻ, sửa, xoá, đọc).
Các ngôi trường tài liệu có khả năng sẽ bị thay cho thay đổi và nếu như quan trọng rất có thể lưu cả vấn đề bạn dạng ghi cũ và mới mẻ.
Thông tin cậy tương quan cho tới perfomance
Ví dụ:
Số thứ tự gọi API (Thành công và thất bại)
Tài nguyên vẹn dùng (CPU, Mem)
Thời gian giảo xử lý trung bình
Tỷ lệ lỗi.
Các rủi ro khủng hoảng và lỗ hổng bảo mật
Trước bản thân đã có được nghe anh thaidn(https://vnhacker.blogspot.com/) nói đến việc thực hiện bảo mật thông tin.
Việc thi công một phần mềm bảo mật thông tin chất lượng tốt tương tự xây một bức tường chắn rào thiệt cao. Nhưng cao bao nhiêu rồi cũng rất có thể bị đột nhập. Vậy nên ngoài xây tường cao thì người tớ còn tồn tại thêm thắt những camera, cảm ứng vận động ... nhằm ngăn chặm đột nhập.
Với phần mềm bạn cũng có thể ghi lại log những rủi ro khủng hoảng tiềm ẩn những hành vi xứng đáng ngờ của người tiêu dùng, cũng như các thay cho thay đổi không bình thường của khối hệ thống.
Ví dụ:
Người người sử dụng singin thất bại rất nhiều lần. Các vấn đề rất có thể ghi lại như:
Tuỳ nhiệm vụ tuy nhiên con số và địa điểm ký tự động được hội tụ lại rất có thể thay cho thay đổi.
Thông tin cậy cá thể người tiêu dùng.
Tên
Tuổi
Địa chỉ
Số năng lượng điện thoại
Thông tin cậy thanh toán
Số tài khoản
Số thẻ
Số dư
Các thông tin
Mật khẩu
Auth token
Private key
Secret key
4. Tổng kết
Ghi log nên sở hữu log id cho 1 luồng xử lý
12021-11-06T18:50:49+05:30 - INFO -[fJLKjlkqjCLlqjwerlJKLZ] - GET /user/1
22021-11-06T18:50:49+05:30 - DEBUG -[fJLKjlkqjCLlqjwerlJKLZ] - [201.123.100.103] GET / HTTP/1.1 200 22.415µs Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, lượt thích Gecko) Chrome/78.0.3904.108 Safari/537.36
32021-11-06T18:50:50+05:30 - ERROR -[fJLKjlkqjCLlqjwerlJKLZ] - [201.123.100.103] Can't connect to lớn the database
42021-11-06T18:50:50+05:30 - INFO -[fJLKjlkqjCLlqjwerlJKLZ] - [201.123.100.103] Can't get user info. Response to lớn client { "code": 500, "message": "internal error"
Sử dụng chính log level
Tài liệu tham ô khảo: https://reflectoring.io/logging-levels/
FATAL: Các lỗi rất có thể tạo ra ngừng phần mềm. Thường ghi rời khỏi nguyên vẹn nhân lỗi trước lúc phần mềm bị ngừng. Ví dụ: Tràn bộ nhớ lưu trữ.
ERROR: Thường được dùng khi những yếu tố tương quan cho tới business ko thể tiến hành được bởi nguyên do về chuyên môn và ko thể xử lý.
Ví dụ: Lỗi xẩy ra khi trừ tiền
Không thể trừ chi phí bởi thông tin tài khoản ko đầy đủ hoặc thông tin tài khoản đích ko tồn bên trên -> Đây ko nên lỗi của phần mềm.
Không thể trừ chi phí bởi ko liên kết được cho tới hạ tầng tài liệu -> Đây là lỗi.
Khi vạc hiện nay log ERROR rất có thể developer tiếp tục nên sửa tức thì nhằm đáp ứng phần mềm kế tiếp hoạt động và sinh hoạt đúng đắn.
Vậy các bạn tránh việc sử dụng quá log error nhằm tách có được những chú ý ko quan trọng. Trong Java một vài Exception được các bạn dẫn đến và được xử lý ví dụ khi login không tìm kiếm thấy User các bạn throw rời khỏi UserNotFoundException tình huống này cần thiết suy nghĩ nhằm ko ghi log Error nếu như không các bạn sẽ có được chú ý lỗi thông thường xuyên.
WARN: Các chú ý cũng cần được đánh giá và xử lý tuy nhiên phỏng ưu tiên thấp rộng lớn ERROR. Các chú ý như tỷ trọng lỗi cao, lượng ram to hơn nấc thông số kỹ thuật (ví dụ: 70%). Hoặc với những lỗi liên kết tuy nhiên sở hữu phương án xử lý như demo lại(retry). Ví dụ: Không gửi được bạn dạng tin cậy lên kafka bạn cũng có thể gửi lại và ghi log WARN cho tới việc này, sau một vài thứ tự chắc chắn tuy nhiên ko thành công xuất sắc thì rất có thể Đánh Giá và ghi log ERROR.
INFO: Các bạn dạng tin cậy, sự khiếu nại cần thiết trong lúc phần mềm hoạt động và sinh hoạt.
DEBUG: Thường dùng nhằm log lại cụ thể rộng lớn quá trình xử lý nhập phần mềm nhằm mục đích mục tiêu debug. Thông thông thường những log này tiếp tục dùng bên trên môi trường xung quanh develop và test, nhiều lúc log debug cũng sẽ tiến hành dùng nhập môi trường xung quanh product nhập quá trình đầu dự án công trình hoặc khi có vấn đề cần thiết thêm thắt vấn đề và được tắt lên đường khi phần mềm tiếp tục hoạt động và sinh hoạt ổn định ấn định.
Nên dùng giờ đồng hồ Anh khi ghi log.
Đây là khuyến nghị chứ không cần yêu cầu, thông thường ngôn từ ghi log tiếp tục theo gót quy ấn định doanh nghiệp.
Ghi log ngắn ngủi gọn gàng nhất sở hữu thể
Nếu ghi log vượt lên trước lâu năm rất có thể tác động cho tới vận tốc ghi log, tệp tin log tiếp tục nặng nề rộng lớn và rất có thể thực hiện hạn chế thời hạn rất có thể tàng trữ log. Vậy hãy nỗ lực ghi log ngắn ngủi gọn gàng và rõ rệt nghĩa.
Ghi log source (Vị trí log được ghi nhập code)
Khi hiểu log rất có thể xác lập được log ở hàm này (Class, hàm, loại này ghi rời khỏi log này)
Không trùng những câu thông báo
Nhiều các bạn hoặc copy những câu log dẫn cho tới bị sai sót hàm hoặc những log bị trùng như này.
12021-11-05 23:05:27 INFO - Request {some object}
22021-11-05 23:05:28 INFO - Response {some object}
Và copy cho tới toàn bộ từng hàm. Nếu log source thì vẫn tiếp tục tra cứu vớt được tuy vậy theo gót chủ ý cá thể từng hàm nên sở hữu log riêng rẽ đễ dễ dàng tra cứu vớt và kể từ log rất có thể lấy vấn đề tức thì tuy nhiên ko cần thiết nhập code.
12021-11-05 23:05:27 INFO - [000001] - UserController:23 - Create user with request {some object}
22021-11-05 23:05:28 INFO - [000001] - UserController:28 - Create user successfully. User info {some object}
log.error("Fail to lớn bởi something", ex.getMessage());
12021-11-05 23:05:28 ERROR - [000003] - UserController:28 - Fail to lớn bởi something NullPointerException
Thì tớ tiếp tục ghi rất đầy đủ stacktrace:
log.error("Fail to lớn bởi something", ex);
12021-11-05 23:05:28 ERROR - [000003] - UserController:28 - Fail to lớn bởi something java.lang.NullPointerException
2 at com.truongnq.product.library.ArgumentChecker.nonNull(ArgumentChecker.java:67)
3 at ...
4 at com.truongnq.product.aspects.CheckArgumentsAspect.wrap(CheckArgumentsAspect.java:82)
5 at ...
6 at com.truongq.product.MyTest.test(MyTest.java:37)
Cấu hình cho tới log
Bật level log nào
Dung lượng tối nhiều cho 1 tệp tin log, số tệp tin log tối nhiều tàng trữ ...
Một số mặt mũi nhằm thuận tiện cho tới việc chú ý những tệp tin log Error sẽ tiến hành ghi riêng rẽ.
Viện màu Pantone đã công bố màu sắc lên ngôi năm 2022 là một màu sắc hoàn toàn mới, được đặt cho cái tên tràn đầy lạc quan là “17-3938 Very Peri” - màu tím hoa dừa cạn, với thông điệp đổi mới, lạc quan và hy vọng thế giới sớm vượt qua đại dịch.
Có rất nhiều sự nhầm lẫn trong khi phát âm tiếng Anh, ví dụ: có phải lúc nào các từ có đuôi –ed cũng được phát âm là /id/ như chúng ta thường nghĩ? Hãy khám phá thêm về điều này trong bài viết hôm nay các bạn nhé!
Tổng hợp danh sách 100 logo và các hãng xe hơi nổi tiếng trên thế giới: Toyota, Volkswagen, Nissan, Renault, KIA, Hyundai, Chevrolet, Cadillac, Ford...