现在微服务大行其道,一些问题也暴露出来了,比如大规模集群如何排查线上问题
究竟是哪台机器抛了异常?
有问题的订单是什么原因导致的?
全链路哪里耗时最长?
如果没有全链路跟踪,这些问题还是很难排查的。
鉴于生产上的一些实际问题,搞了一个超轻量级的小框架,提供traceId && 全链路日志跟踪能力,对业务无侵入,配置即可用,单独输出不污染业务日志
性能方面本人测试日志模块耗时每次请求平均RT 1-2ms(总RT - 空控制器RT)可以忽略不计
采用spring boot自动装配,只需要两步配置即可使用,引入框架5分钟即可完成trace链路跟踪,功能专注,无污染无公害
偷个懒,下面是从github里markdown里粘过来的
链接: smile-boot-starter.
smile-boot-starter
超轻量级微服务基本支持框架
TRACE ID
引入smile-boot-starter
后,自动支持traceId,可由前端带入traceId
到后端(不建议前段生成,无法保证全局唯一性),也可由首个接收到请求的服务自动生成
支持spring cloud feign
和dubbo
spring cloud feign
是由SpringCloudFeignInterceptor
支持,由config类控制注入
dubbo
是由CloudRpcFilter
,注入依赖于dubbo
的Filter SPI支持
提供全链路traceId支持,前端或者首个被访问的服务生成,全链路业务任意位置可以通过LocalDataUtils.getTraceId()
获取traceId
Environment
项目启动自动激活Environment对象,获取当前工程的环境和应用名称,取值{spring.profiles.active} 和 {spring.profiles.name}
可以用来屏蔽预发环境一些接口,Environment
Environment.getInstance().isDaily()
Environment.getInstance().isStaging()
Environment.getInstance().isProd()
if(Environment.getInstance().isProd()) {
return "cant`t use in prod env";
}
// do something
EVENT LOGGER
概念: 微服务架构下,一个请求可能会有多个应用来承载,每个应用又有多个主机来集群部署,假设一次请求出现问题,我们需要跟踪一次请求,如果没有全局统一的一个ID,问题排查起来可能比较困难
smile-boot-starter提供极简模式快速让项目拥有traceId的跟踪能力
(一次请求全局拥有一个ID,聚合日志后可以通过该id查询本次请求的全埋点路径报告)
QUICK START
两步快速实现:
- 引入依赖
<dependency>
<groupId>com.el</groupId>
<artifactId>smile-boot-starter</artifactId>
<version>${smile-boot-starter.last-version}</version>
</dependency>
- application.yml配置
spring:
profiles:
# 配置运行环境 可选DAILY|STAGING|PROD,与application.yml多环境配置不冲突
active: STAGING
application:
# 应用名称
name: trace-test
smile-boot:
trace-logger:
# 日志路径配置,两种配置方式: 例如fatjar位置在/root/admin/runtime/trace-test
# absolute - 取绝对路径,absolute: /root/admin/runtime/trace-test/log
# relative - 取项目运行的相对路径,relative: log -> /root/admin/runtime/trace-test/log
log-path: relative:log
# 日志文件名 event -> /root/admin/runtime/trace-test/log/event.log
log-file-name: event
# 2020-07-12 00:33:32 - msg
pattern: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
- 对要埋点的方法添加注解
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SmsSenderController {
private final TraceIdServiceProvider traceIdServiceProvider;
@GetMapping("/test/api")
@EventTrace(event = "测试", loggerType = LoggerType.JSON)
public String test() {
log.info(LocalDataUtils.getTraceId());
LocalDataUtils.setIsSucess(true);
return traceIdServiceProvider.test();
}
}
即可获取到日志,默认情况下,日志打在spring boot jar目录下的event.log
FORMAT:
2020-07-12 00:30:16 - TRACE LOG -
traceId [20200712003016-b20bc50af8824d988d025a5a17124dd8],
appName [trace-test],
env [STAGING],
ip [115.220.204.114],
event [test - /provider/test/api],
method [com.landscape.user.repository.TraceIdServiceProvider.test()],
success [true],
costTime [4],
parameter [without parameter],
response ["success 20200712003016-b20bc50af8824d988d025a5a17124dd8"],
features [{LOGGER_IS_SUCCESS=true}]
JSON:
2020-07-12 00:30:16 - {
"appName":"landscape-user",
"costTime":4,
"env":"STAGING",
"event":"测试",
"features":{
"LOGGER_IS_SUCCESS":"true"
},
"ip":"115.220.204.114",
"method":"com.landscape.user.repository.TraceIdServiceProvider.test()",
"parameter":"without parameter",
"result":"\"success 20200712003332-419cdb0d285e433daac7bebbfb88fca3\"",
"success":true,
"traceId":"20200712003332-419cdb0d285e433daac7bebbfb88fca3"
}
TODO:
- 日志参数可配置
- 日志文件位置及滚动策略
日志聚合可以使用ELK,或者Loki
ELK比较重,上手有难度,但功能齐全
Loki最近新出的,好多人在推,我没有尝试过,看介绍感觉还可以,可以尝试
技术支持
项目个人维护,有使用问题,或者想共同开发都可以issues里留问题或者微信,周末会看
更新记录
2020-07-11 --------- 0.0.1-SNAPSHOT
- 日志输出可配置
- 获取公网IP
- 增加日志类型控制 FORMAT | JSON
PS:最近更新了Mac 10.16(BIG SUR)系统,各种问题,又懒得退回,就慢点搞吧