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:123@127.0.0.1:8080,user:123@127.0.0.1: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
新增依赖如下所示:
<!--ApiBoot 提供的持久化框架 -->
<dependency>
<groupId>org.minbox.framework</groupId>
<artifactId>api-boot-starter-mybatis-enhance</artifactId>
<version>{ApiBoot 最新版本}</version>
</dependency>
<!--MySQL 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!--Hikari 数据源 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.2.0</version>
</dependency>
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
内添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
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);
本文由博客一文多发平台 OpenWrite 发布!