MinBox Logging
MinBox Logging
是一款分布式、零侵入式的链路日志分析框架,支持SpringCloud
微服务架构下配置使用,内部封装了RestTemplate
、OpenFeign
两种方式透传链路信息。
零侵入式
MinBox Logging
无需使用注解配置采集链路日志,只需要添加依赖
后简单配置Minbox Loggin Admin
的相关地址
或服务名称
即可,每次在收到请求时就会把请求对应的链路日志详细信息自动上报到MinBox Logging Admin
进行后续分析、告警通知等。
源码地址
https://gitee.com/minbox-projects/minbox-logging
I. 概念
1. 链路架构图
在一次请求中,经过的每一个服务(MicroService)
的链路编号(TraceId)
保持一致,通过SpanID
、ParentSpanID
进行链路上下级关系衔接。
2. 提交使用中遇到的问题
遇到你在集成使用过程中遇到了问题,请提交issues,提交地址:创建Issues
3. ApiBoot集成实践示例
ApiBoot
作为MinBox
开源组织的组件最佳集成方案,在第一时间会进行整合minbox-projects开源组织内新发布的组件,MinBox Logging
整合实践请访问ApiBoot
源码,整合源码详见org.minbox.framework.api.boot.autoconfigure.logging
。
II. 配置客户端
4. 启用客户端
在minbox-logging-spring-context
依赖内提供了@EnableLoggingClient
注解来启用客户端,配置使用该注解后通过@Import
自动注册Logging Client
运行时所需要的Bean
。
@EnableLoggingClient使用示例如下所示:
@SpringBootApplication
@EnableLoggingClient
public class ApiBootLoggingApplication {
/**
* logger instance
*/
static Logger logger = LoggerFactory.getLogger(ApiBootLoggingApplication.class);
public static void main(String[] args) {
SpringApplication.run(ApiBootLoggingApplication.class, args);
logger.info("{}服务启动成功.", "ApiBoot Logging Client");
}
}
5. 透传链路信息
每发送一个请求时就会产生一条链路信息,而链路单元(Span)之前的相互访问目前则以http
、rpc
等方式作为主要占比。
链路信息(Trace)的传递,Logging Client
内部提供了提取请求header
内的链路信息编号(TraceID)、上级单元编号(Parent SpanID),整条链路都通过这种方式来进行上下级单元关系、链路关系绑定。
5.1. RestTemplate透传链路信息
RestTemplate
是Spring Web
组件提供的请求封装对象,可用于发送指定方式的请求到目标地址,可携带header
信息进行传递身份认证信息、请求、响应等信息。
Logging Client
则是利用RestTemplate
的拦截器将链路(Trace)信息写入请求的header
进行传递到下一个单元(Span)。
Logging Client
已经提供了RestTemplate
拦截器实现类LoggingRestTemplateInterceptor
,在LoggingFactoryBean#afterPropertiesSet
方法内进行实例化并且已经设置了拦截器,在Logging Client
上报请求日志信息时,都是通过LoggingFactoryBean#restTemplate
来执行发送请求到Admin
,因此只需要实例化LoggingFactoryBean
即可。
5.2. OpenFeign透传链路信息
OpenFeign
是SpringCloud
为服务之间方法相互调用的实现方式,根据接口配置信息来发送请求并获取响应内容。
Logging Client
同样是利用OpenFeign
提供的拦截器将链路(Trace)信息写入服务相互调用的请求header
,进行传递到下一个服务。
Logging Client
内部提供了RequestInterceptor
接口实现类LoggingOpenFeignInterceptor
来完成链路信息透传,OpenFeign
会自动检索Spring IOC
容器内RequestInterceptor
接口的实现类实例,每次通过OpenFeign
发起请求时会调用RequestInterceptor
实现类的apply
方法来完成拦截业务处理。
6. 发现Admin并上报日志
Logging Client
默认本地不进行持久化存储请求日志
信息,而是将本地生成的请求日志
详细信息上报到Logging Admin
,由Admin
进行存储、分析等。
Logging Client
内部提供LoggingAdminDiscovery#lookup
接口方法来进行发现Admin地址。
6.1. 指定地址发现Admin
Logging Client
获取指定Admin
地址是通过LoggingAdminDiscovery
其中一个实现类LoggingAppointAdminDiscovery
来进行获取。
下面是ApiBoot
配置使用LoggingAppointAdminDiscovery实践示例,
详见源码,ApiBootLoggingAdminAppointAutoConfiguration:
/**
* ApiBoot Logging Admin Config Discovery
* Multiple Use "," Separation
*
* @return LoggingAdminDiscovery
*/
@Bean
@ConditionalOnMissingBean
public LoggingAppointAdminDiscovery loggingConfigAdminDiscovery() {
String[] adminAddressArray = apiBootLoggingProperties.getAdmin().getServerAddress().split(",");
LoggingAppointAdminDiscovery appointAdminDiscovery = new LoggingAppointAdminDiscovery(adminAddressArray);
return appointAdminDiscovery;
}
LoggingAppointAdminDiscovery
构造函数需提供Logging Admin
地址数组,格式为:ip(IP地址):port(端口号)
,并不需要添加任何http
、https
前缀。
6.1.1. 多Admin地址负载均衡配置
如果我们在创建LoggingAppointAdminDiscovery
对象时传递了多个Logging Admin
地址,比如:
@Bean
@ConditionalOnMissingBean
public LoggingAppointAdminDiscovery loggingConfigAdminDiscovery() {
// 初始化Logging Admin地址列表
String[] adminAddressArray = {"127.0.0.1:8080,127.0.0.1:9090"};
LoggingAppointAdminDiscovery appointAdminDiscovery = new LoggingAppointAdminDiscovery(adminAddressArray);
return appointAdminDiscovery;
}
如上所示,我启动了两个Logging Admin
来进行接收Logging Client
采集到的请求日志信息后执行存储,而Logging Client
具体使用什么LoadBlanace
(负载均衡)策略来进行选择上报的Logging Admin
节点?
Logging Client
提供了LoadBalanceStrategy
负载均衡策略接口,而内部提供了两种策略的实现,分别是:RandomWeightedStrategy
、SmoothWeightedRoundRobinStrategy
。
Logging Client默认采用SmoothWeightedRoundRobinStrategy(平滑轮询权重)负载均衡策略。
6.1.2. 随机权重负载策略
虽然LoggingAppointAdminDiscovery
在构造函数内默认实例化了平滑轮询负载策略
,我们当然可以通过LoggingAppointAdminDiscovery#setLoadBalanceStrategy
方法来进行设置具体的策略,随机权重策略
设置方式如下所示:
@Bean
@ConditionalOnMissingBean
public LoggingAppointAdminDiscovery loggingConfigAdminDiscovery() {
// 初始化Logging Admin地址列表
String[] adminAddressArray = {"127.0.0.1:8080,127.0.0.1:9090"};
LoggingAppointAdminDiscovery appointAdminDiscovery = new LoggingAppointAdminDiscovery(adminAddressArray);
// 实例化随机权重策略
RandomWeightedStrategy randomWeightedStrategy = new RandomWeightedStrategy();
// 设置负载均衡策略
appointAdminDiscovery.setLoadBalanceStrategy(randomWeightedStrategy);
return appointAdminDiscovery;
}
RandomWeightedStrategy(随机权重负载策略)是随机分配选择指定的Logging Admin
地址,在上面示例中,随机权重的结果可能为:
随机权重获取到的 Logging Admin 地址:
127.0.0.1:8080
127.0.0.1:8080
127.0.0.1:9090
127.0.0.1:8080
127.0.0.1:9090
127.0.0.1:9090
127.0.0.1:9090
6.1.3. 平滑轮询权重负载策略
SmoothWeightedRoundRobinStrategy(平滑轮询权重负载策略)是平滑分配指定的Logging Admin
地址,在上面示例中,平滑轮询权重的结果为:
平滑轮询权重获取到的 Logging Admin 地址:
127.0.0.1:8080
127.0.0.1:9090
127.0.0.1:8080
127.0.0.1:9090
127.0.0.1:8080
127.0.0.1:9090
6.2. 服务注册中心发现Admin
在SpringCloud MicroService
部署方式下使用时,可以将Logging Admin
作为一个单独的服务进行注册到Service Registry Center
(服务注册中心,如:Eureka
、Zookeeper
、Consul
、Nacos Discovery
等),这样在Logging Client
通过服务注册的发现接口即可完成Logging Admin
的发现,获取地址后进行上报请求日志
。
Logging Client
内部提供了集成服务注册中心
的服务发现实现LoggingRegistryCenterAdminDiscovery
,通过配置实例化该类并放入Spring IOC
即可完成自动从服务注册中心
内获取Logging Admin
信息。
ApiBoot
配置使用LoggingRegistryCenterAdminDiscovery实践示例,详见源码,ApiBootLoggingAdminDiscoveryAutoConfiguration。
/**
* ApiBoot Logging Admin Registry Center Discovery
* @param loadBalancerClient LoadBalance Client
* @return LoggingRegistryCenterAdminDiscovery
*/
@Bean
@ConditionalOnMissingBean
public LoggingRegistryCenterAdminDiscovery loggingRegistryCenterAdminDiscovery(LoadBalancerClient loadBalancerClient) {
LoggingRegistryCenterAdminDiscovery registryCenterAdminDiscovery =
new LoggingRegistryCenterAdminDiscovery(apiBootLoggingProperties.getDiscovery().getServiceId(), loadBalancerClient);
return registryCenterAdminDiscovery;
}
LoadBalancerClient是SpringCloud
负载均衡客户端对象,通过SpringCloud
依赖的自动配置并且放入Spring IOC
,注入该对象后即可负载均衡的发现一个可用的指定serviceID
的服务对象ServiceInstance
。
7. 延迟上报日志
Logging Client
默认采用了just
(直接上报)的方式来上报采集到的请求日志
,每产生一条请求日志都会实时上报到Logging Admin
,而有些时候需求往往变化比较大,比如:降低Logging Admin
压力,这时可能每次上报20条请求日志
到Logging Admin
。
针对这种业务情况,Logging Client
提供了定时上报方式。
7.1. 配置上报方式
上报方式
通过LoggingFactoryBean#setReportAway
方法来修改默认值,参数为org.minbox.framework.logging.core.ReportAway
枚举,修改如下所示:
// 设置上报方式为:timing
factoryBean.setReportAway(ReportAway.timing);
7.2. 设置单次上报的日志数量
单次上报请求日志数量默认值为:10
。
通过LoggingFactoryBean#setNumberOfRequestLog
方法来修改默认值,如下所示:
// 设置每次上报的请求日志数量
factoryBean.setNumberOfRequestLog(20);
7.3. 设置上报日志间隔时间
上报日志默认间隔时间为:5秒
。
通过LoggingFactoryBean#setReportIntervalSecond
方法来修改默认值,如下所示:
// 设备上报间隔时间,单位:秒
factoryBean.setReportIntervalSecond(5);
8. 自定义TraceID生成规则
Logging Client
默认使用UUID
生成的字符串作为TraceId
(链路编号),通过LoggingFactoryBean#setTraceGenerator
方法来修改默认的生成规则,自定义策略需要实现LoggingTraceGenerator
接口,如下所示:
/**
* 自定义链路编号(TraceID){@link LoggingTraceGenerator}
*
* @author 恒宇少年
*/
public class CustomerTraceIdGenerator implements LoggingTraceGenerator {
@Override
public String createTraceId() throws MinBoxLoggingException {
return UUID.randomUUID().toString().replace("-", "");
}
}
设置使用自定义的策略如下所示:
// 创建自定义策略对象
CustomerTraceIdGenerator customerTraceIdGenerator = new CustomerTraceIdGenerator();
// 设置使用自定义生成TraceID的策略
factoryBean.setTraceGenerator(customerTraceIdGenerator);
9. 自定义SpanID生成规则
Logging Client
默认使用UUID
生成的字符串作为SpanId
(单元编号),通过LoggingFactoryBean#setSpanGenerator
方法来修改默认的生成规则,自定义策略需要实现LoggingSpanGenerator
接口,如下所示:
/**
* 自定义单元编号(SpanID){@link LoggingSpanGenerator}
*
* @author 恒宇少年
*/
public class CustomerSpanIdGenerator implements LoggingSpanGenerator {
@Override
public String createSpanId() throws MinBoxLoggingException {
String currentTime = String.valueOf(System.currentTimeMillis());
return String.format("%s-%s", "span", currentTime);
}
}
设置使用自定义策略如下所示:
// 创建自定义策略对象
CustomerSpanIdGenerator customerSpanIdGenerator = new CustomerSpanIdGenerator();
// 设置使用自定义生成SpanID的策略
factoryBean.setSpanGenerator(customerSpanIdGenerator);
10. 排除部分路径不进行上报日志
Logging Client
内默认排除了/error
路径不进行上报日志,如果业务服务存在一些访问比较频繁的接口,而且接口并不涉及业务请求,那么建议将这些请求进行排除,比如:集成SpringBootAdmin
后会频繁访问/actuator/health
来检查服务的健康程度。
通过LoggingFactoryBean#setIgnorePaths
方法进行追加排除路径
,这里注意是追加而不是替换,所以/error
始终是在排除的列表内,配置排除路径如下所示:
// 需要排除的路径列表
String[] ignorePaths = new String[]{
"/actuator/health",
"/index",
"/test"
};
// 设置排除的路径列表
factoryBean.setIgnorePaths(ignorePaths);
11. 安全上报日志
分布式的日志采集与日志存储定然会存在安全性问题,那么在Logging Admin
服务端已经解决了这个问题,Logging Admin
通过集成Spring Security
配置用户名、密码来完成Basic Auth
认证。
在Logging Client
发起上报请求时,会提取Logging Admin
路径内的Basic Auth
认证信息,通过header
形式进行传递认证信息。
11.1. 指定Admin地址方式配置
如果采用的是LoggingAppointAdminDiscovery
方式配置Logging Admin
服务地址发现,那么在构造函数初始化Logging Admin
地址时,需要携带Basic Auth
的用户名、密码信息,如下所示:
@Bean
@ConditionalOnMissingBean
public LoggingAppointAdminDiscovery loggingConfigAdminDiscovery() {
// 初始化Logging Admin地址列表
String[] adminAddressArray = {"user:[email protected]:8080,user:[email protected]:9090"};
LoggingAppointAdminDiscovery appointAdminDiscovery = new LoggingAppointAdminDiscovery(adminAddressArray);
return appointAdminDiscovery;
}
在上面示例中可以看到Basic Auth
是通过username:password@IP:Port
格式来进行配置,其中user
为用户名,而123
则是该用户的密码。
11.2. 服务注册中心配置
如果采用LoggingRegistryCenterAdminDiscovery
方式配置Logging Admin
服务地址发现,配置如下所示:
/**
* ApiBoot Logging Admin Registry Center Discovery
* setting basic auth username if not empty {@link LoggingRegistryCenterAdminDiscovery#setUsername(String)}
* setting basic auth password if not empty {@link LoggingRegistryCenterAdminDiscovery#setPassword(String)}
*
* @param loadBalancerClient LoadBalance Client
* @return LoggingRegistryCenterAdminDiscovery
*/
@Bean
@ConditionalOnMissingBean
public LoggingRegistryCenterAdminDiscovery loggingRegistryCenterAdminDiscovery(LoadBalancerClient loadBalancerClient) {
LoggingRegistryCenterAdminDiscovery registryCenterAdminDiscovery =
new LoggingRegistryCenterAdminDiscovery(apiBootLoggingProperties.getDiscovery().getServiceId(), loadBalancerClient);
// 用户名
String basicAuthUserName = apiBootLoggingProperties.getDiscovery().getUsername();
if (ObjectUtils.isEmpty(basicAuthUserName)) {
registryCenterAdminDiscovery.setUsername(basicAuthUserName);
}
// 密码
String basicAuthPassword = apiBootLoggingProperties.getDiscovery().getPassword();
if (!ObjectUtils.isEmpty(basicAuthPassword)) {
registryCenterAdminDiscovery.setPassword(basicAuthPassword);
}
return registryCenterAdminDiscovery;
}
上面示例所示,根据LoggingRegistryCenterAdminDiscovery#setUsername
方法来设置用户名,根据LoggingRegistryCenterAdminDiscovery#setPassword
方法来设置密码。
12. 控制台显示上报日志
Logging Client
默认不会在控制台打印即将要上报的请求日志
信息,可以通过LoggingFactiory#setShowConsoleLog
方法进行设置,如下所示:
// 设置在控制台输出上报的日志
factoryBean.setShowConsoleLog(true);
13. 格式化控制台显示上报日志
Logging Client
在控制台打印上报的请求日志时,默认不进行格式化json
字符串,根据LoggingFactoryBean#setFormatConsoleLog
方法来进行设置,如下所示:
// 设置格式化输出上报的日志
factoryBean.setFormatConsoleLog(true);
14. 自定义日志上报通知
Logging Client
提供日志上报通知功能,只需要实现LoggingNotice
接口即可获取每次上报的请求日志详细对象
,进行日志的自定义处理,如下所示:
/**
* 自定义日志通知
* @author 恒宇少年
*/
@Component
public class CustomerLoggingNotice implements LoggingNotice {
/**
* 通知方法
* 处理自定义的业务逻辑
* @param minBoxLog
*/
@Override
public void notice(MinBoxLog minBoxLog) {
System.out.println(minBoxLog.getTraceId());
// 自定义业务处理...
}
/**
* 通知执行优先级
* {@link #getOrder()}方法返回值值越小优先级越高
*
* @return
*/
@Override
public int getOrder() {
return 1;
}
}
14.1. 内置的日志通知
Logging Client
内部提供了日志通知的具体实现,分别是:LoggingLocalNotice
,LoggingAdminNotice
。
日志通知实现类 | 功能作用 |
---|---|
LoggingLocalNotice | LoggingLocalNotice 日志通知用于在控制台显示、格式化 日志对象详细信息,优先级为Integer.MIN_VALUE ,源码详见org.minbox.framework.logging.client.notice.support.LoggingLocalNotice 。 |
LoggingAdminNotice | LoggingAdminNotice 日志通知用于上报日志 信息到Logging Admin ,优先级为Integer.MIN_VALUE + 1 ,源码详见:org.minbox.framework.logging.client.notice.support.LoggingAdminNotice 。 |
14.2. 自定义多个日志上报通知
Logging Client
内部通过ApplicationContext
从Spring IOC
内获取指定LoggingNotice
类型的实例列表,正因为这样也就支持了多日志通知
的方式。
注意:日志通知实现类的优先级值建议不要重复。
III. 配置服务端
15. 启用服务端
在minbox-logging-spring-context
依赖内提供了@EnableLoggingAdmin
注解来启用服务端,配置使用该注解后通过@Import
自动注册Logging Admin
运行时所需要的Bean
。
@EnableLoggingAdmin使用示例如下所示:
@SpringBootApplication
@EnableLoggingAdmin
public class ApiBootLoggingAdminApplication {
/**
* logger instance
*/
static Logger logger = LoggerFactory.getLogger(ApiBootLoggingAdminApplication.class);
public static void main(String[] args) {
SpringApplication.run(ApiBootLoggingAdminApplication.class, args);
logger.info("{}服务启动成功.", "Logging Admin");
}
}
16. 初始化数据库
Logging Admin
支持将Logging Client
上报的请求日志保存到数据库,而且提供了固定的表结构,如下所示:
SET NAMES utf8mb4 ;
--
-- Table structure for table `logging_service_details`
--
DROP TABLE IF EXISTS `logging_service_details`;
SET character_set_client = utf8mb4 ;
CREATE TABLE `logging_service_details` (
`lsd_id` varchar(36) COLLATE utf8mb4_general_ci NOT NULL,
`lsd_service_id` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上报服务的ID,对应spring.application.name配置值',
`lsd_service_ip` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上报服务的IP地址',
`lsd_service_port` int(11) DEFAULT NULL COMMENT '上报服务的端口号',
`lsd_last_report_time` timestamp NULL DEFAULT NULL COMMENT '最后一次上报时间,每次上报更新',
`lsd_create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '首次上报时创建时间',
PRIMARY KEY (`lsd_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='上报日志的客户端服务详情';
--
-- Table structure for table `logging_request_logs`
--
DROP TABLE IF EXISTS `logging_request_logs`;
SET character_set_client = utf8mb4 ;
CREATE TABLE `logging_request_logs` (
`lrl_id` varchar(36) COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键,UUID',
`lrl_service_detail_id` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '服务详情编号,关联logging_service_details主键',
`lrl_trace_id` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '链路ID',
`lrl_parent_span_id` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上级跨度ID',
`lrl_span_id` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '跨度ID',
`lrl_start_time` mediumtext COLLATE utf8mb4_general_ci COMMENT '请求开始时间',
`lrl_end_time` mediumtext COLLATE utf8mb4_general_ci COMMENT '请求结束时间',
`lrl_http_status` int(11) DEFAULT NULL COMMENT '请求响应状态码',
`lrl_request_body` longtext COLLATE utf8mb4_general_ci COMMENT '请求主体内容',
`lrl_request_headers` text COLLATE utf8mb4_general_ci COMMENT '请求头信息',
`lrl_request_ip` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '发起请求客户端的IP地址',
`lrl_request_method` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请求方式',
`lrl_request_uri` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请求路径',
`lrl_response_body` longtext COLLATE utf8mb4_general_ci COMMENT '响应内容',
`lrl_response_headers` text COLLATE utf8mb4_general_ci COMMENT '响应头信息',
`lrl_time_consuming` int(11) DEFAULT NULL COMMENT '请求耗时',
`lrl_create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '日志保存时间',
`lrl_request_params` text COLLATE utf8mb4_general_ci,
`lrl_exception_stack` text COLLATE utf8mb4_general_ci,
PRIMARY KEY (`lrl_id`),
KEY `logging_request_logs_LRL_SERVICE_DETAIL_ID_index` (`lrl_service_detail_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='请求日志信息表';
16.1. 将日志持久化到数据库
初始化Logging Admin
所需要的表结构之后,我们在集成Logging Admin
的项目中添加数据源
、数据库驱动
、持久化框架
等依赖,然后进行配置数据源相关数据库参数,下面以SpringBoot项目示例。
16.1.1 添加所需依赖
pom.xml
新增依赖如下所示:
org.minbox.framework
api-boot-starter-mybatis-enhance
{ApiBoot最新版本}
mysql
mysql-connector-java
8.0.17
com.zaxxer
HikariCP
3.2.0
Logging Admin
并不固定依赖ApiBoot
提供的持久化框架,可以使用任意框架依赖,Logging Admin
内部只是需要DataSource
的实例,也可以自定义创建DataSource
对象放入Spring IOC
。
16.1.2. 配置数据源参数
spring:
# 数据源参数
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
username: root
password: 123456
url: jdbc:mysql://localhost:3306/test
17. 将Admin注册到SpringCloud
Logging Admin
作为一个依赖添加到SpringBoot
项目内,我们只需要考虑如何将SpringBoot
项目注册到服务注册中心
(SpringCloud Service Register Center),如果你使用的Eureka
作为服务注册中心,请访问我之前编写的文章查看将微服务提供者注册到Eureka服务中心。
18. 启用安全配置
Logging Admin
的安全采用的是Spring Security
提供的Basic Auth
来完成。
18.1. 添加支持Spring Security
在项目的pom.xml
内添加如下依赖:
org.springframework.boot
spring-boot-starter-security
18.2. 配置安全用户
建议采用Spring Security
提供的内存方式
来配置Logging Admin
,application.yml
配置文件如下所示:
spring:
security:
user:
# 用户名
name: user
# 密码
password: 123
19. 监听日志上报事件
Logging Admin
支持自定义处理监听到Logging Client
上报的日志信息,可进行自定义的存储,格式化处理,分组归类等,自定义事件监听沿用了Spring Event/Listener
方式,如下所示:
/**
* 自定义上报日志事件{@link ReportLogEvent}监听
*
* @author 恒宇少年
*/
@Component
public class CustomerReportEventListener implements SmartApplicationListener {
/**
* 判断事件类型为{@link ReportLogEvent}
*
* @param eventType
* @return
*/
@Override
public boolean supportsEventType(Class extends ApplicationEvent> eventType) {
return ReportLogEvent.class == eventType;
}
/**
* 自定义处理业务
*
* @param event
*/
@Override
public void onApplicationEvent(ApplicationEvent event) {
ReportLogEvent reportLogEvent = (ReportLogEvent) event;
LoggingClientNotice loggingClientNotice = reportLogEvent.getLogClientNotice();
System.out.println("上报日志的服务Id:" + loggingClientNotice.getClientServiceId());
// 自定义业务处理...
}
}
19.1. 多监听事件实现
Logging Admin
由于采用的是Spring
内部提供的SmartApplicationListener
方式来监听ReportLogEvent
事件,所以只需要添加多个自定义监听实现SmartApplicationListener
接口即可。
SmartApplicationListener
由于实现了Ordered
接口,所以提供优先级配置方法getOrder
,与LoggingNotice
接口优先级策略一致,值越小优先级越高。
详细了解Spring
提供的Event/Listener
可以访问SpringBoot使用ApplicationEvent&Listener完成业务解耦。
20. LoggingAdminFactoryBean
LoggingAdminFactoryBean
是配置Logging Admin
的必要途径,通过该类可以对Logging Admin
进行全方面的配置。
ApiBoot
集成Logging Admin FactoryBean
示例如下所示:
/**
* instantiation {@link LoggingAdminFactoryBean}
*
* @param dataSource {@link DataSource}
* @return LoggingAdminFactoryBean
*/
@Bean
public LoggingAdminFactoryBean loggingAdminFactoryBean(DataSource dataSource) {
LoggingAdminFactoryBean factoryBean = new LoggingAdminFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setShowConsoleReportLog(apiBootLoggingAdminProperties.isShowConsoleReportLog());
factoryBean.setFormatConsoleLogJson(apiBootLoggingAdminProperties.isFormatConsoleLogJson());
logger.info("【LoggingAdminFactoryBean】init successfully.");
return factoryBean;
}
ApiBoot
集成LoggingAdminFactoryBean
详细源码请访问ApiBootLoggingAdminAutoConfiguration。
20.1. 设置数据源
通过LoggingAdminFactoryBean#setDataSource
方法来设置Logging Admin
所需要操作日志数据的数据源,如下所示:
// 设置数据源
factoryBean.setDataSource(dataSource);
20.2. 控制台输出上报的日志
通过LoggingAdminFactoryBean#setShowConsoleReportLog
方法来控制是否在控制台打印Logging Client
上报的日志信息,如下所示:
// 设置在控制台输出Logging Client 上报的日志
factoryBean.setShowConsoleReportLog(true);
20.3. 格式化控制台输出日志
通过LoggingAdminFactoryBean#setFormatConsoleLogJson
方法来格式化控制台输出的日志,如下所示:
// 格式化控制台输出的日志
factoryBean.setFormatConsoleLogJson(true);