零侵入式分布式链路日志minbox-logging使用文档v1.0

MinBox Logging

MinBox Logging 是一款分布式、零侵入式的链路日志分析框架,支持 SpringCloud 微服务架构下配置使用,内部封装了 RestTemplate 、 OpenFeign 两种方式透传链路信息。

零侵入式

MinBox Logging 无需使用注解配置采集链路日志,只需要添加 依赖 后简单配置 Minbox Loggin Admin 的相关 地址 或 服务名称 即可,每次在收到请求时就会把请求对应的链路日志详细信息自动上报到 MinBox Logging Admin 进行后续分析、告警通知等。

源码地址

https://gitee.com/minbox-projects/minbox-logging

I. 概念

1. 链路架构图

零侵入式分布式链路日志minbox-logging使用文档v1.0

在一次请求中,经过的每一个 服务(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 。

日志通知实现类功能作用LoggingLocalNoticeLoggingLocalNotice 日志通知用于在 控制台显示、格式化 日志对象详细信息,优先级为 Integer.MIN_VALUE ,源码详见 org.minbox.framework.logging.client.notice.support.LoggingLocalNotice 。LoggingAdminNoticeLoggingAdminNotice 日志通知用于 上报日志 信息到 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);

相关推荐