日志框架 - 基于spring-boot - 使用入门

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 日志框架系列讲解文章日志框架 - 基于spring-boot - 使用入门日志框架 - 基于spring-boot - 设计日志框架 - 基于spring-boot - 实现1 - 配置文件日志框架 - 基于spring-boot - 实现2 - 消...

日志框架系列讲解文章
日志框架 - 基于spring-boot - 使用入门
日志框架 - 基于spring-boot - 设计
日志框架 - 基于spring-boot - 实现1 - 配置文件
日志框架 - 基于spring-boot - 实现2 - 消息定义及消息日志打印
日志框架 - 基于spring-boot - 实现3 - 关键字与三种消息解析器
日志框架 - 基于spring-boot - 实现4 - HTTP请求拦截
日志框架 - 基于spring-boot - 实现5 - 线程切换
日志框架 - 基于spring-boot - 实现6 - 自动装配

前言

为什么要开发日志框架? logbacklog4j 之类日志框架的还不够用吗?是的!

生产系统上有一套日志规范,对日志打印的内容与格式都有一定的要求。每个业务系统都自行实现,但实现的方式千奇百怪。好一点的能顺利用上日志框架,差一点就完全硬编码。

不仅团队各自为战,将接口与实现变的非常不整齐;还浪费每个团队大量的时间来调试与测试,避免错误的发生;最可恨是连累日志采集系统,不得不适应各生产系统出现的不一致。这些终都导致不可维护的代码。

一切框架的目的都是为了解放开发人员的生产力,本日志框架也不例外。

正文

本框架致力于为公司所有系统提供通用的日志解决方案,主要解决以下痛点:

  1. 日志内容与格式约束很强,多字段拼接容易出错。
  2. 日志要求打印的内容,包含实时处理过程中的信息,为了在不同层次打印日志的完整性,而频繁传参。
  3. 为了将含义相同但格式不同的日志,交给不同系统采集,而对同一内容写多个log输出语包,导致代码中充斥大量的日志代码,使业务代码支离破碎。

基本概念

  • 消息,指在应用进程间(同个系统或不同系统)通信的内容,包含多种协议,如HTTP,JMS等,通常是进程间调用携带的文本内容。
  • 消息类型,框架支持三种消息类型,分别是XML、Json与KeyValue。
  • 日志类型,日志类型分为三种,分别是系统运行日志,告警日志,消息日志。
    • 系统运行日志,系统运行时正常输出的日志。
    • 告警日志,输出系统执行遇到问题时的相关信息,通常是捕获到异常或错误时打印。
    • 消息日志,记录应用进程相互调用与返回的文本内容
  • 关键字,消息中包含的重要信息,特别是在打印日志时需要填充到日志中的字段。

重要特性

  1. 消息中搜索关键字对应的信息并保存到线程的上下文中,可以自动搜索Json、XML、KeyValue三种格式的消息,默认自动处理HTTP请求中这些格式的内容。
  2. 通过spring的配置指定日志打印格式,线程上下文中的关键字对应信息会自动填充到指定位置。
  3. 处理线程切换时,通过关键字提取的信息会自动转存到下一个执行线程,直到请求结束时信息才被销毁。
  4. 自动打印HTTP请求消息消息日志文件,目前支持HTTP请求的任意文本格式。
  5. 随spring-boot启动全自动加载,但可以通过修改配置停用此框架功能。
  6. 与spring-boot的其它配置均兼容,spring-boot针对日志的的配置可以同时使用,不会产生冲突。甚至于spring对于logger级别的动态修改功能也可以正常使用。
  7. 对开发人员透明,开发人员只需要使用slf4j的方式打印日志。
  8. 异步输出日志的方式,log操作不会阻塞业务线程执行。

框架使用

版本要求

本框架基于spring-boot-1.5.10.RELEASEJDK-1.8版本开发,应用必须兼容此版本,能正常添加此依赖,日志框架功能才能正常使用。

第一步,添加maven依赖。

<dependency>
    <groupId>com.cmsz</groupId>
    <artifactId>xpay-framework</artifactId>
    <version>1.1.2</version>
</dependency>

第二步,在spring-boot的配置文件(properties或yaml)中增加以下配置

#关键字定义,用逗号进行分隔
xpay.framework.logging.keywords=Order-No,Activity-Code,Req-Sys,Province
#定义系统日志的格式,使用logback的语法
xpay.framework.logging.logback.system.encoder.pattern=\
  %level#%date{yyyy-MM-dd HH:mm:ss.SSS}#\
  %mdc{APPLICATION_NAME}_%mdc{IP}_%mdc{PORT}#%mdc{Order-No}#\
  %mdc{Activity-Code}#%mdc{Req-Sys}#%mdc{Province}#%logger{5}:%msg%n%wEx

xpay.framework.logging.keywords 用于定义关键字, 系统会根据关键字自动搜索请求消息中的对应内容信息。

针对XML格式与Json格式的信息,关键字可以是处于任意层级的元素。

定义关键字时,注间在单词间使用减号,即可以享受spring-boot提供的的Relaxed binding特性。

Relaxed binding允许进行单词的模糊匹配,例如Req-Sys可以指定模糊查找消息中可能包含的Req-Sys, Req_Sys, ReqSys, reqSys, req-sys, req_sys, reqsys, REQ-SYS, REQ_SYS, REQSYS等10种情况的内容。

xpay.framework.logging.logback.system.encoder.pattern 定义的是系统运行日志的格式,用的是logback的语法,但不支持${}, 因为与spring的转义符相冲突。

如logback一样,本框架也为用户提供了默认关键字供用户使用,包括

  1. APPLICATION_NAME(取spring.application.name配置的值)
  2. IP(本机网卡IP)
  3. PORT(取server.port配置的值)
  4. HOSTNAME(主机名)。

第三步,添加slf4j日志代印的logger,并在需要的地方打印代码。

private Logger logger = LoggerFactory.getLogger(getClass());

logger.info("some infomation")
logger.error("this is an error")

框架约定,info级别的日志只会被打印到系统日志文件(system-log)中,warn及error级别的日志除了在系统日志文件中打印,还会再被打印到告警日志文件(alarm-log)中。

第四步(可选),在需要的地方添加 @MessageToLog 注解

@RequestMapping(path = "/get", method = RequestMethod.GET)
@MessageToLog(addition = "返回消息")
public @ResponseBody OrderInfo orderGet(OrderInfo info) {
    service.doService(info);
    return info;
}

添加 @MessageToLog 注解表示此方法的返回值被视作消息打印到消息日志文件中,返回的对象可以不实现 toString() 方法,框架会自动转换为Json格式打印。

样例代码

由于种种原因,本框架暂时还没有打算共享到开源社区,因此,样例代码不是对所有人开放的。
如果你是我们内部成员,那么你可以在本框架的同个 GIT 库中找到日志框架使用的样例代码,这对使用这个框架有一定帮助。
如果你是外部人员想使用类似的功能,可以仔细阅读最前面的系列文章,根据其中的设计与部分的关键实现重新实现一个完整的日志框架。

附录

完整配置

日志完整配置项及默认配置如下:

#spring-boot自带配置,指定日志文件的所在目录。
logging.path=./log
#spring-boot自带配置,指定日志文件名,但此日志在
logging.file=spring.log

#是否使用此log框架,默认为true
xpay.framework.logging.enabled=true
#是否将打印到文件的日志在console输出,此配置项是为方便开发人员调试,设置为true时,打印到文件的日志会同时打印到控制台。
xpay.framework.logging.log-to-console=false

#由于logback日志名称是根据包名来命名,必须确定第一个非root logger的名称,以保证logger被正常管理。
#此配置项默认项目使用com作为包名的起始名称,可以相应的修改为org,cn等值
xpay.framework.logging.package.root=com

#此executor线程池用于保证上下文在父子线程间传递,应作为默认的TaskExecutor使用,此处配置其最大并发线程数
xpay.framework.executor.max-pool-size=16

#关键字配置,前文有说明。
xpay.framework.logging.keywords=

#自动打印消息日志开关,false表示不自动打印接收的消息日志
xpay.framework.logging.print-message=true
#消息日志的文件名配置,采用logback语法,会按文件大小滚动输出
xpay.framework.logging.logback.message.filename.pattern=%d{yyyy-MM-dd}/message.log.%d{yyyy-MM-dd}
#消息日志的内容格式,采用logback语法
xpay.framework.logging.logback.message.encoder.pattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n
#消息日志会按文件名及大小滚动输出,每个文件大小等于此处配置时触发滚动
#xpay.framework.logging.logback.message.max-file-size=200MB

#系统日志的文件名配置,采用logback语法,会按文件大小滚动输出
xpay.framework.logging.logback.system.filename.pattern=\
        %d{yyyy-MM-dd}/info.log.%d{yyyy-MM-dd}
#系统息日志的内容格式,采用logback语法
xpay.framework.logging.logback.system.encoder.pattern=\
        %d{yyyy-MM-dd HH:mm:ss.SSS} -%5p %X{PID:- } --- [%t] %-40.40logger{39} : %m%n%wEx
#系统日志会按文件名及大小滚动输出,每个文件大小等于此处配置时触发滚动
xpay.framework.logging.logback.system.max-file-size=200MB

#告警日志的文件名配置,采用logback语法,告警日志每天只产生一个文件,只按时间滚动输出
xpay.framework.logging.logback.alarm.filename.pattern=alarm/alarm.log.%d{yyyy-MM-dd}
#告警息日志的内容格式,采用logback语法
xpay.framework.logging.logback.alarm.encoder.pattern=\
        %d{yyyy-MM-dd HH:mm:ss.SSS} -%5p %X{PID:- } --- [%t] %-40.40logger{39} : %m%n%wEx

写在最后

相信聪明的你一定在这里发现了一点蛛丝马迹,什么是 xpay

在这里我不好明说,但是网上有一个开源项目叫 Xxpay,嘿嘿 ;-),相信大家有点明白,都是差不多的东西呢!不过这命名我在两年前就取了,大家真是巧合哈。

以后我一定搞个newXpay,盖过它!哈哈:-D,立字为证。

日志框架系列讲解文章
日志框架 - 基于spring-boot - 使用入门
日志框架 - 基于spring-boot - 设计
日志框架 - 基于spring-boot - 实现1 - 配置文件
日志框架 - 基于spring-boot - 实现2 - 消息定义及消息日志打印
日志框架 - 基于spring-boot - 实现3 - 关键字与三种消息解析器
日志框架 - 基于spring-boot - 实现4 - HTTP请求拦截
日志框架 - 基于spring-boot - 实现5 - 线程切换
日志框架 - 基于spring-boot - 实现6 - 自动装配

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2天前
|
运维 NoSQL Java
SpringBoot接入轻量级分布式日志框架GrayLog技术分享
在当今的软件开发环境中,日志管理扮演着至关重要的角色,尤其是在微服务架构下,分布式日志的统一收集、分析和展示成为了开发者和运维人员必须面对的问题。GrayLog作为一个轻量级的分布式日志框架,以其简洁、高效和易部署的特性,逐渐受到广大开发者的青睐。本文将详细介绍如何在SpringBoot项目中接入GrayLog,以实现日志的集中管理和分析。
16 1
|
6天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
27 2
|
7天前
|
Cloud Native 安全 Java
Micronaut对决Spring Boot:谁是微服务领域的王者?揭秘两者优劣,选对框架至关重要!
【9月更文挑战第5天】近年来,微服务架构备受关注,Micronaut和Spring Boot成为热门选择。Micronaut由OCI开发,基于注解的依赖注入,内置多种特性,轻量级且启动迅速;Spring Boot则简化了Spring应用开发,拥有丰富的生态支持。选择框架需考虑项目需求、团队经验、性能要求及社区支持等因素。希望本文能帮助您选择合适的微服务框架,助力您的软件开发项目取得成功!
35 2
|
8天前
|
JavaScript 前端开发 Java
【颠覆传统】Spring框架如何用WebSocket技术重塑实时通信格局?揭秘背后的故事与技术细节!
【9月更文挑战第4天】随着Web应用对实时交互需求的增长,传统的HTTP模型已无法满足现代应用的要求,特别是在需要持续、双向通信的场景下。WebSocket协议由此诞生,提供全双工通信渠道,使服务器与客户端能实时互发消息。作为Java开发中最受欢迎的框架之一,Spring通过其WebSocket模块支持这一协议,简化了WebSocket在Spring应用中的集成。
28 0
|
11天前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
16 0
|
11天前
|
消息中间件 Kafka Java
Spring 框架与 Kafka 联姻,竟引发软件世界的革命风暴!事件驱动架构震撼登场!
【8月更文挑战第31天】《Spring 框架与 Kafka 集成:实现事件驱动架构》介绍如何利用 Spring 框架的强大功能与 Kafka 分布式流平台结合,构建灵活且可扩展的事件驱动系统。通过添加 Spring Kafka 依赖并配置 Kafka 连接信息,可以轻松实现消息的生产和消费。文中详细展示了如何设置 `KafkaTemplate`、`ProducerFactory` 和 `ConsumerFactory`,并通过示例代码说明了生产者发送消息及消费者接收消息的具体实现。这一组合为构建高效可靠的分布式应用程序提供了有力支持。
38 0
|
11天前
|
Java Spring 人工智能
AI 时代浪潮下,Spring 框架异步编程点亮高效开发之路,你还在等什么?
【8月更文挑战第31天】在快节奏的软件开发中,Spring框架通过@Async注解和异步执行器提供了强大的异步编程工具,提升应用性能与用户体验。异步编程如同魔法,使任务在后台执行而不阻塞主线程,保持界面流畅。只需添加@Async注解即可实现方法的异步执行,或通过配置异步执行器来管理线程池,提高系统吞吐量和资源利用率。尽管存在线程安全等问题,但异步编程能显著增强应用的响应性和效率。
23 0
|
11天前
|
测试技术 Java Spring
Spring 框架中的测试之道:揭秘单元测试与集成测试的双重保障,你的应用真的安全了吗?
【8月更文挑战第31天】本文以问答形式深入探讨了Spring框架中的测试策略,包括单元测试与集成测试的有效编写方法,及其对提升代码质量和可靠性的重要性。通过具体示例,展示了如何使用`@MockBean`、`@SpringBootTest`等注解来进行服务和控制器的测试,同时介绍了Spring Boot提供的测试工具,如`@DataJpaTest`,以简化数据库测试流程。合理运用这些测试策略和工具,将助力开发者构建更为稳健的软件系统。
21 0
|
11天前
|
缓存 Java Spring
Spring缓存实践指南:从入门到精通的全方位攻略!
【8月更文挑战第31天】在现代Web应用开发中,性能优化至关重要。Spring框架提供的缓存机制可以帮助开发者轻松实现数据缓存,提升应用响应速度并减少服务器负载。通过简单的配置和注解,如`@Cacheable`、`@CachePut`和`@CacheEvict`,可以将缓存功能无缝集成到Spring应用中。例如,在配置文件中启用缓存支持并通过`@Cacheable`注解标记方法即可实现缓存。此外,合理设计缓存策略也很重要,需考虑数据变动频率及缓存大小等因素。总之,Spring缓存机制为提升应用性能提供了一种简便快捷的方式。
21 0
|
11天前
|
容器 Java Spring
Spring框架遇上Docker:传统与现代的碰撞,谁将重塑应用部署的未来?
【8月更文挑战第31天】Spring框架凭借其强大的企业级特性和便捷的开发模式,在Java开发中占据重要地位。Docker作为容器化技术的代表,提供了轻量级、可移植的应用部署解决方案。两者结合,尤其在微服务架构中,能显著提升开发效率、部署速度和环境一致性。
28 0