ApiBoot Logging
会为每个请求都对应建立链路编号(TraceID
)以及单元编号(SpanID
),用于归类每一次请求日志,经过一个链路下日志单元的Parent SpanID
能够进行上下级关系的梳理。html
在每一次请求中链路编号(traceId
)、单元编号(spanId)
都是经过HttpHeader
的方式进行传递,日志的起始位置会主动生成traceId
、spanId
,而起始位置的Parent SpanId
则是不存在的,值为null
。github
这样每次经过restTemplate
、Openfeign
的形式访问其余服务的接口时,就会携带起始位置生成的traceId
、spanId
到下一个服务单元。json
ApiBoot Logging
内部提供了默认的编号格式,默认为通用格式,没有区分性,没法从编号上进行区分日志的具体归类。api
ApiBoot Logging
内部经过集成minbox-logging
日志组件来完成日志的采集等基本功能,每一次生成采集的日志时都会经过LoggingTraceGenerator接口进行生成链路编号(TraceID
),该接口源码以下所示:架构
/** * ApiBoot Logging Tracer * Create new traceId * * @author:恒宇少年 - 于起宇 * <p> * DateTime:2019-07-10 17:01 * Blog:http://blog.yuqiyu.com * WebSite:http://www.jianshu.com/u/092df3f77bca * Gitee:https://gitee.com/hengboy * GitHub:https://github.com/hengboy */
public interface LoggingTraceGenerator {
/** * create new traceId * * @return traceId * @throws MinBoxLoggingException exception */
String createTraceId() throws MinBoxLoggingException;
}
复制代码
ApiBoot Logging
默认的链路编号(TraceID
)采用的是UUID随机字符串的方式生成的,内部实现是经过LoggingTraceGenerator接口的默认实现类LoggingDefaultTraceGenerator进行生成,生成类源码以下所示:框架
/** * ApiBoot Logging Tracer Default Support Instance * * @author:恒宇少年 - 于起宇 * <p> * DateTime:2019-07-10 17:28 * Blog:http://blog.yuqiyu.com * WebSite:http://www.jianshu.com/u/092df3f77bca * Gitee:https://gitee.com/hengboy * GitHub:https://github.com/hengboy */
public class LoggingDefaultTraceGenerator implements LoggingTraceGenerator {
/** * Use UUID as the default traceId * * @return traceId * @throws MinBoxLoggingException Exception */
@Override
public String createTraceId() throws MinBoxLoggingException {
return UUID.randomUUID().toString();
}
}
复制代码
单元编号
是一条链路下通过的每个业务单元的惟一标识,在SpringCloud
微服务的场景下每发起一个请求内部经过Openfeign
可能会通过多个服务
,这样每通过的一个服务称之为单元,而当前这条链路下的单元惟一标识字符串就称为单元编号
。dom
minbox-logging
提供了生成单元编号
的接口LoggingSpanGenerator,源码以下所示:curl
/** * ApiBoot Logging Span * Create new spanId * * @author:恒宇少年 - 于起宇 * <p> * DateTime:2019-07-10 17:02 * Blog:http://blog.yuqiyu.com * WebSite:http://www.jianshu.com/u/092df3f77bca * Gitee:https://gitee.com/hengboy * GitHub:https://github.com/hengboy */
public interface LoggingSpanGenerator {
/** * create new spanId * * @return span id * @throws MinBoxLoggingException exception */
String createSpanId() throws MinBoxLoggingException;
}
复制代码
spanId
默认采用的跟traceId
生成方式一致,都是UUID
随机字符串,minbox-logging
提供了LoggingSpanGenerator接口默认的实现LoggingDefaultSpanGenerator,源码以下所示:
/** * ApiBoot Logging Default Span * Use By Create New SpanId * * @author:恒宇少年 - 于起宇 * <p> * DateTime:2019-07-15 17:24 * Blog:http://blog.yuqiyu.com * WebSite:http://www.jianshu.com/u/092df3f77bca * Gitee:https://gitee.com/hengboy * GitHub:https://github.com/hengboy */
public class LoggingDefaultSpanGenerator implements LoggingSpanGenerator {
/** * Create New SpanId * * @return SpanId * @throws MinBoxLoggingException Exception */
@Override
public String createSpanId() throws MinBoxLoggingException {
return UUID.randomUUID().toString();
}
}
复制代码
咱们能够根据本身的业务进行自定义traceId
、spanId
,能够加入一些本身业务的元素,只须要提供minbox-logging
提供的生成traceId
的接口LoggingTraceGenerator、生成spanId
的接口LoggingSpanGenerator对应的实现类,并将实现类交给LoggingFaceBean
管理便可。
/** * 自定义traceId生成策略 * * @author 恒宇少年 */
public class CustomTraceIdGenerator implements LoggingTraceGenerator {
/** * 链路编号前缀 */
private static final String TRACE_ID_PREFIX = "local";
@Override
public String createTraceId() throws MinBoxLoggingException {
return TRACE_ID_PREFIX + UUID.randomUUID().toString().hashCode();
}
}
复制代码
咱们建立名为CustomTraceIdGenerator
的类并实现LoggingTraceGenerator
接口,实现createTraceId()
方法的返回值根据local-
做为前缀,拼接UUID
随机字符串的hashCode
值做为后缀。
/** * 自定义单元编号生成策略 * * @author 恒宇少年 */
public class CustomSpanIdGenerator implements LoggingSpanGenerator {
/** * 单元编号前缀 */
private static final String SPAN_ID_PREFIX = "group";
@Override
public String createSpanId() throws MinBoxLoggingException {
return SPAN_ID_PREFIX + UUID.randomUUID().toString().hashCode();
}
}
复制代码
咱们建立名为CustomSpanIdGenerator
的类并实现LoggingSpanGenerator
接口,在createSpanId()
方法的返回值根据group-
做为前缀,使用UUID
随机字符串的hashCode
值做为后缀。
在上面咱们已经建立了自定义traceId
以及spanId
的实现类,咱们须要将实现类的实例交给LoggingFactoryBean
管理,这样咱们才能够实现自定义编号。
ApiBoot Logging
提供了一个自定义设置LoggingFactoryBean
的接口LoggingFactoryBeanCustomizer,经过该接口能够修改LoggingFactoryBean
内容许修改的任意值。
咱们建立名为CustomCreateTraceAndSpanId类并实现LoggingFactoryBeanCustomizer
接口,源码以下所示:
/** * 自定义建立链路以及单元编号 * * @author 恒宇少年 * @see LoggingFactoryBeanCustomizer * @see LoggingFactoryBean * @see org.minbox.framework.logging.client.tracer.LoggingTraceGenerator * @see org.minbox.framework.logging.client.span.LoggingSpanGenerator */
@Component
public class CustomCreateTraceAndSpanId implements LoggingFactoryBeanCustomizer {
/** * {@link CustomTraceIdGenerator} 自定义链路编号生成策略 * {@link CustomSpanIdGenerator} 自定义单元编号生成策略 * * @param factoryBean {@link LoggingFactoryBean} */
@Override
public void customize(LoggingFactoryBean factoryBean) {
CustomTraceIdGenerator traceIdGenerator = new CustomTraceIdGenerator();
factoryBean.setTraceGenerator(traceIdGenerator);
CustomSpanIdGenerator spanIdGenerator = new CustomSpanIdGenerator();
factoryBean.setSpanGenerator(spanIdGenerator);
}
}
复制代码
customize
这种设计方式是在SpringBoot
中比较常见的,ApiBoot
也沿用了这种设计方式,customize()
方法提供了LoggingFactoryBean
对象实例做为参数,咱们能够直接经过setXxx
方法进行修改内定义的默认配置。
经过facetory.setTraceGenerator
方法能够修改默认的traceId
生成策略。
经过facetory.setSpanGenerator
方法能够修改默认的spanId
生成策略。
启动项目后咱们来查看控制台打印的日志内容,确认是否修改为功。
{
"endTime":1571711067664,
"httpStatus":200,
"requestBody":"",
"requestHeaders":{
"accept":"*/*",
"host":"localhost:8080",
"user-agent":"curl/7.64.1"
},
"requestIp":"0:0:0:0:0:0:0:1",
"requestMethod":"GET",
"requestParam":"{}",
"requestUri":"/index",
"responseBody":"this is index.",
"responseHeaders":{},
"serviceId":"apiboot-custom-logging-traceid",
"serviceIp":"127.0.0.1",
"servicePort":"8080",
"spanId":"group-1780993769",
"startTime":1571711067643,
"timeConsuming":21,
"traceId":"local1111437283"
}
复制代码
traceId
、spanId
已经修改为咱们自定义的编号生成策略方式。
本章节主要是讲到了如何自定义traceId
以及spanId
,咱们能够经过LoggingFactoryBeanCustomizer
对LoggingFactoryBean
对象进行深度的自定义配置,有关ApiBoot Logging
使用的正确姿式还有不少,敬请期待。