Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the ways of locating bug to log?

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "what are the ways to locate bug to log". In daily operation, I believe that many people have doubts about the way bug logs are located. The editor consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful for you to answer the doubts about "what are the ways to locate bug to log?" Next, please follow the editor to study!

Please unify the log format

The log format had better be uniform, that is, it is convenient to view and locate the problems as well as to collect statistics. I generally like to define a LogObject object that defines the fields of the log. For example:

Import com.fasterxml.jackson.annotation.JsonInclude;import com.fasterxml.jackson.annotation.JsonInclude.Include;import com.fasterxml.jackson.annotation.JsonProperty;public class LogObject {@ JsonProperty (index = 1) private String eventName;@JsonProperty (index = 2) private String traceId; @ JsonProperty (index = 3) private String msg; @ JsonProperty (index = 4) private long costTime; @ JsonProperty (index = 6) private Integer userId; @ JsonProperty (index = 7) private Object others; @ JsonProperty (index = 8) private Object request @ JsonProperty (index = 9) private Object response;public String getEventName () {return eventName;} public LogObject setEventName (String eventName) {this.eventName = eventName;return this;} public Object getRequest () {return request;} public LogObject setRequest (Object request) {this.request = request;return this;} public Object getResponse () {return response;} public LogObject setResponse (Object response) {this.response = response;return this } public String getMsg () {return msg;} public LogObject setMsg (String msg) {this.msg = msg;return this;} public long getCostTime () {return costTime;} public LogObject setCostTime (long costTime) {this.costTime = costTime;return this;} public Integer getUserId () {return userId;} public LogObject setUserId (Integer userId) {this.userId = userId;return this;} public Object getOthers () {return others } public LogObject setOthers (Object others) {this.others = others;return this;} public String getTraceId () {return traceId;} public LogObject setTraceId (String traceId) {this.traceId = traceId;return this;}

TraceId: call chain id

EventName: event name, which is usually the name of the business method

UserId: C-end user id

Msg: result messa

CostTime: interface response time

Request: API request for input parameters

Response: the returned value of API

Others: other business parameters

Use the chained style to easily set the value of the field:

Long endTime = System.currentTimeMillis (); LogObject logObject = new LogObject (); logObject.setEventName (methodName) .setMsg (msg) .setTraceId (traceId) .setUserId (backendId) .setRequest (liveRoomPushOrderReqDto) .setResponse (response). SetCostTime ((endTime-beginTime)); LOGGER.info (JSON.toJSONString (logObject))

Of course, it is best to encapsulate a tool class, such as LogTemplate, as a unified entry.

Alternatively, you can use JsonProperty annotations to specify the order of the fields, such as placing eventName first through index=1.

@ JsonProperty (index = 1) private String eventName; places request and response together

The advantage of putting the request and the return value in the same log is that it is very convenient to view the context log.

If printed in two, the return value may be washed far behind, and another grep operation will have to be done, affecting efficiency.

The specific logs are as follows:

{"eventName": "createOrder", "traceId": "createOrder_1574923602015", "msg": "success", "costTime": 317, "request": {"uId": 111111111, "skuList": [{"skuId": 22222222, "buyNum": 1, "buyPrice": 8800,}]}, "response": {"code": 0 "message": "Operation succeeded", "data": {"bigOrderId": "BIG2019", "m2LOrderIds": {"MID2019": {"22222222": "LIT2019"}

In order to put it together, there are two solutions, one is to compare low, and use try catch finally directly in the code, for example:

PostMapping (value = "/ createOrder") public JsonResult createOrder (@ RequestBody Object request) throws Exception {String methodName = "/ createOrder"; Integer backendId = null; String msg = "success"; long beginTime = System.currentTimeMillis (); String traceId = "createOrder_" + beginTime; JsonResult response = null;try {OrderCreateRsp orderCreateRsp = orderOperateService.createOrder (request, traceId); response = JsonResult.success (orderCreateRsp);} catch (Exception e) {msg = e.getMessage () LOGGER.error (methodName+ ", userId:" + backendId+ ", request:" + JsonHelper.toJson (request), e); throw new BizException (0, "order failed");} finally {long endTime = System.currentTimeMillis (); LogObject logObject = new LogObject (); logObject.setEventName (methodName) .setMsg (msg) .setTraceId (traceId) .setUserId (backendId) .setRequest (request) .setResponse (response) .setCostTime ((endTime-beginTime)) LOGGER.info (JSON.toJSONString (logObject));} return response;}

A disadvantage of this scheme is that every business method has to deal with logs. A better solution is to use aop plus thread local to intercept requests uniformly and string the return value with request parameters. There are many solutions on this network, which will not be described here.

For applications with high performance requirements, the first scheme is recommended, because there is some performance loss when using aop. For example, the commodity aggregation service I participated in before VIPSHOP used the first solution, after all, millions of requests are processed every second.

Add traceId to the log

If the unified call chain monitoring scheme has been used in the application, and the API can be queried according to the call chain id, you do not need to add traceId manually in the code.

If the application has not been connected to the call chain system, it is recommended to add traceId, especially for aggregation services, which need to call various micro-service APIs of CCTV. For example, for an order service issued by the aggregation layer, the micro services that need to be invoked are as follows:

Marketing system

Order system

Payment system

When the order-issuing business calls these interfaces, if traceId is not used for tracking, it is difficult to find which micro-service interface failed when the order was issued. The following example shows how Mini Program calls the aggregation layer API to place an order:

Marketing system:

{"eventName": "pms/getInfo", "traceId": "createOrder_1575270928956", "msg": "success", "costTime": 2, "userId": 1111111111, "request": {"userId": 1111111111, "skuList": [{"skuId": 2222, "skuPrice": 65900, "buyNum": 1, "activityType": 0, "activityId": 0,}],} "response": {"result": 1, "msg": "success", "data": {"realPayFee": 100,}}}

Order system:

{"eventName": "orderservice/createOrder", "traceId": "createOrder_1575270928956", "msg": "success", "costTime": 29, "userId": null, "request": {"skuList": [{"skuId": 2222, "buyNum": 1, "buyPrice": 65900,}],}, "response": {"result": "msg": "successful call", "data": {"bigOrderId": "BIG2019", "m2LOrderIds": {"MID2019": {"88258135": "LIT2019"}

Payment system:

{"eventName": "payservice/pay", "traceId": "createOrder_1575270928956", "msg": "success", "costTime": 301, "request": {"orderId": "BIG2019", "paySubject": "Test", "totalFee": 65900,}, "response": {"requestId": "test", "code": 0, "message": "Operation successful" "data": {"payId": 123, "orderId": "BIG2019", "tradeType": "JSAPI", "perpayId": "test", "nonceStr": "test", "appId": "test", "signType": "MD5", "sign": "test", "timeStamp": "1575270929"}

You can see that the aggregation layer needs to call the interfaces of marketing, order and payment applications. During the call, traceId is used to string createOrder_1575270928956, so that we only need the traceId of grep to find out all the relevant calls and contexts.

A simple way to generate traceId is to use System.currentTimeMillis () plus the name of the business interface, such as:

Long beginTime = System.currentTimeMillis (); String traceId = "createOrder_" + beginTime

Adding traceId will intrude into business methods, such as:

Public void createOrder (Object obj) {long beginTime = System.currentTimeMillis (); String traceId = "createOrder_" + beginTime; pmsService.getInfo (obj,traceId); orderService.createOrder (obj,traceId); payService.getPrepayId (obj,traceId);}

Internal service methods such as pmsService need to add a traceId field. At present, I think it's OK. If you feel invaded, you can also consider the thread local method. When processing a request, store traceId for the current thread, and then take it out of the current thread in the business method to avoid the traceId in the interface method flying all over the place.

At this point, the study of "what are the ways to locate the bug log" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report