日志链路追踪

Posted supingemail

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日志链路追踪相关的知识,希望对你有一定的参考价值。

好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受。

目录

一、前言

二、思路

三、定位问题

四、开源方案


一、前言

在日常工作中,我们需要经常处理业务的各种异常,而日志成了我们定位问题,解决问题最有效的绝佳手段。那么如何快速定位问题,并且解决问题呐?
下面说一下:针对链路上问题的排查,采用的一些方法和手段,供参考。

在日志输出上,现在最常用的是:logback(spring-boot 自带的日志体系) 和 log4j2两种日志的实现方式 ,不管采用那种实现手段,都是实现了Slf4j定义的日志接口,这里不做赘述。

在业务系统中,打印日志通常是使用@Slf4j注解的方式来操作(简单易用,方便维护),而不采用new XXX的方式来实现。

二、思路

如何快准精的在日志文件中,找到我们需要的日志信息呐? 做法是:规范日志,即:定义一个日志对象 LogObject,在也业务中打印日志通过构建 LogObject,然后将 LogObject 进行输出,进而得到日志的详细信息。

LogObject 的定义如下:
 


import com.fasterxml.jackson.annotation.JsonProperty;


public final class LogObject {
	/**
	 * 系统的ID
	 */
	@JsonProperty(index = 1)
	private String sysId;
	/**
	 * 系统的名称
	 */
	@JsonProperty(index = 2)
	private String sysName;
	/**
	 * 事件名称,一般就是业务方法名称
	 */
	@JsonProperty(index = 3)
	private String eventName;
	/**
	 * 调用链ID
	 */
	@JsonProperty(index = 4)
	private String traceId;
	/**
	 * 结果消息
	 */
	@JsonProperty(index = 5)
	private String message;
	/**
	 * 接口响应时间
	 */
	@JsonProperty(index = 6)
	private long costTime;
	/**
	 * C端用户id
	 */
	@JsonProperty(index = 7)
	private Integer userId;
	/**
	 * 其他业务参数
	 */
	@JsonProperty(index = 8)
	private Object others;
	/**
	 * 请求参数
	 */
	@JsonProperty(index = 9)
	private Object request;
	/**
	 * 相应结果
	 */
	@JsonProperty(index = 10)
	private Object response;
	
	public LogObject() {
	}
	
	public LogObject(String sysId, String sysName, String eventName, String traceId, String message, long costTime, Integer userId, Object others, Object request, Object response) {
		this.sysId = sysId;
		this.sysName = sysName;
		this.eventName = eventName;
		this.traceId = traceId;
		this.message = message;
		this.costTime = costTime;
		this.userId = userId;
		this.others = others;
		this.request = request;
		this.response = response;
	}
	
	public String getSysId() {
		return sysId;
	}
	
	public void setSysId(String sysId) {
		this.sysId = sysId;
	}
	
	public String getSysName() {
		return sysName;
	}
	
	public void setSysName(String sysName) {
		this.sysName = sysName;
	}
	
	public String getEventName() {
		return eventName;
	}
	
	public void setEventName(String eventName) {
		this.eventName = eventName;
	}
	
	public String getTraceId() {
		return traceId;
	}
	
	public void setTraceId(String traceId) {
		this.traceId = traceId;
	}
	
	public String getMessage() {
		return message;
	}
	
	public void setMessage(String message) {
		this.message = message;
	}
	
	public long getCostTime() {
		return costTime;
	}
	
	public void setCostTime(long costTime) {
		this.costTime = costTime;
	}
	
	public Integer getUserId() {
		return userId;
	}
	
	public void setUserId(Integer userId) {
		this.userId = userId;
	}
	
	public Object getOthers() {
		return others;
	}
	
	public void setOthers(Object others) {
		this.others = others;
	}
	
	public Object getRequest() {
		return request;
	}
	
	public void setRequest(Object request) {
		this.request = request;
	}
	
	public Object getResponse() {
		return response;
	}
	
	public void setResponse(Object response) {
		this.response = response;
	}
}

在业务中,通过给对象复杂而后进行输出,就可以将链上的每一步业务操作追踪清楚。

此处实例,调用省略。

三、定位问题

发生异常之后,如何解决问题?
1.最原始的方式是:在服务器上去查看日志,找到出错的根源,然后根据根源,进而去人为处理调用链上的异常。

优点:实现难道低,
缺点:自动化程度低,人力成本高,不易维护

2. 升级方式是:将日志的信息收集起来,存在日志表中,做个管理台,根据链上日志的不同异常阶段和异常情况,去定制自动的补偿机制,只需要人工敲击鼠标,完成链上异常的处理

优点:界面化,自动化,方便快捷
缺点:实现成本高,实现难度大(需要根据链上的不同异常,处理各种不同的情况)

四、开源方案

开源方案是介于原始方案和升级方案之间的一种方案,目前apache开源的,中国人华为人写的skywalking,它是一款比较强大APM工具,可以让你使用最少的成本去定位问题,找到链路上出现问题的根源。进而在人为的采取处理异常的各种策略和方案。

优点:开源,免费,功能齐全

缺点:目前在处理消息时候,不能准确将traceId传递出去,不能将MQ调用链的信息进行串联管理。

 

综合来看,在spring-cloud 体系中,使用skywalking 作为链路追踪是一个不二之选。
当然,如果条件允许,对数据的精准性,完整性,一致性要求高(金融行业),那么还是建议在复杂业务操作时候,使用日志入库,自建日志管理台,并在各个节点设置半自动的补偿措施。

 

更多精彩,可关注:码出精彩(codingba) 公众号

 

以上是关于日志链路追踪的主要内容,如果未能解决你的问题,请参考以下文章

利用SpringBoot+Logback手写一个简单的链路追踪

利用SpringBoot+Logback手写一个简单的链路追踪

可视化全链路日志追踪

监控链路追踪日志的区别,傻傻分不清?

Monolog 自动填充 RequestId / TraceId 请求链路追踪标识

如何让日志打印更加优雅和实现数据链路追踪?