浅谈spring 后端项目配置logback日志

news/2024/9/24 10:16:48/

日志

Java boy 后端项目日志一般用 logback or Log4j & Log4j2,spring 默认集成logback,本文主要以logback 展开例子说明。
对于日志系统有什么样的需求?
1、本地环境需要打印Console日志。
2、测试环境最好实时打印日志。
3、生产环境打印日志不要阻塞系统(日志阻塞导致很多故障,特别是流量大的场景,小流量可以忽略)
4、可以实时修改,有些日志不关注,需要隔离一下。
5、分离日志…ERROR  ALL  not care…
… 等等信息。

日志需求分析

“小小”《环境》

现实开发场景中,很多都需要有环境的概念,redis 预发和生产 prefix key 不同.
test 环境和生产环境的调用的接口不同…  env=test env=prod 等等配置标识。

但是这些都不是非常的规范,在Spring Boot中,spring.profiles.active是一个非常重要的配置属性,它用于指定当前激活的配置文件(profiles)。通过这个属性,你可以控制应用程序在不同环境下的行为,例如开发、测试和生产环境。 SpringBoot激活profiles你知道几种方式?

  • application.properties
spring.profiles.active=dev
  • 系统参数
export SPRING_PROFILES_ACTIVE=dev
  • 命令行参数
java -jar your-application.jar --spring.profiles.active=prod

通过配置中心注入系统环境或者属性进行配置(放在公共配置,多应用统一使用),或者统一运维的部署脚本中指定,通过标准化的路径实现环境标准化,无需自定义。

环境隔离日志配置

这个是 logback-spring.xml 里面的配置
非生产、非预发、非测试 非开发环境打印console

springProfile 灵活的配置,可以让开发处理多环境的配置信息非常easy

 <springProfile name="!prod,!pre"><root level="INFO"><appender-ref ref="APPLICATION"/><appender-ref ref="FILE_ERROR"/><!--本地环境打印console 日志--><springProfile name="!test,!dev"><appender-ref ref="CONSOLE"/></springProfile></root></springProfile>

日志阻塞

之前见过很多系统由于日志阻塞导致系统功能受影响,响应耗时增加,这样的例子非常多。常见的场景的处理方式是配置为异步日志。 logback之 AsyncAppender 的原理、源码及避坑建议
在普通的日志RollingFileAppender 基础上包装一个异步日志 ,如下配置。

<appender name="APPLICATION" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>logs/application.log</file><encoder><pattern>${PATTERN}</pattern></encoder><!-- 滚动策略 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 路径 --><fileNamePattern>logs/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>1GB</maxFileSize><maxHistory>30</maxHistory><totalSizeCap>10GB</totalSizeCap></rollingPolicy>
</appender>
<appender name="ASYNC_APPLICATION" class="ch.qos.logback.classic.AsyncAppender"><neverBlock>true</neverBlock><queueSize>5120</queueSize><discardingThreshold>20</discardingThreshold><includeCallerData>true</includeCallerData><appender-ref ref="APPLICATION"/>
</appender>

异步日志,由于打印日志是异步的,导致测试环境跟踪的时候查看日志非实时写文件的,用起来非常恼火,特别是调试的时候,测试环境是否可以非异步的?
通过上面介绍的spring环境隔离即可完成,如下配置。

   <!--    prod 和 pre 进行异步日志--><springProfile name="prod,pre"><appender name="ASYNC_APPLICATION" class="ch.qos.logback.classic.AsyncAppender"><neverBlock>true</neverBlock><queueSize>5120</queueSize><discardingThreshold>20</discardingThreshold><includeCallerData>true</includeCallerData><appender-ref ref="APPLICATION"/></appender><root level="INFO"><appender-ref ref="ASYNC_APPLICATION"/></root></springProfile><!--test 环境和本地 不进行异步日志--><springProfile name="!prod,!pre"><root level="INFO"><appender-ref ref="APPLICATION"/><!--本地环境打印console 日志--><springProfile name="!test,!dev"><appender-ref ref="CONSOLE"/></springProfile></root></springProfile>

怎么判断异步日志是否配置OK? debug ?arthas 也行?
查看一下异步日志的实例是否存在

[arthas@34932]$ vmtool -x  1 --action getInstances --className ch.qos.logback.classic.AsyncAppender  --limit 5
@AsyncAppender[][@AsyncAppender[ch.qos.logback.classic.AsyncAppender[ASYNC_LOG_FILE_OKHTTP]],@AsyncAppender[ch.qos.logback.classic.AsyncAppender[ASYNC_LOG_FILE_MIDDLEWARE]],@AsyncAppender[ch.qos.logback.classic.AsyncAppender[ASYNC_ERROR]],@AsyncAppender[ch.qos.logback.classic.AsyncAppender[ASYNC_APPLICATION]],
]

logback__126">logback 配置文件不推荐放在配置中心

配置文件和源码放在一起,通过环境变量区分不同环境的处理方式比较好,方便修改
某些场景需要隐藏某些日志,放在配置中心非常不方便,修改起来也非常麻烦,修改错误了也不知道,只有发布的时候才能感知。
eg: kafka的日志不要放在all 日志里面,需要在线日志系统订阅关键的业务日志信息,减少费用。

<logger name="org.apache.kafka" level="INFO" additivity="false"><appender-ref ref="LOG_FILE_MIDDLEWARE"/>
</logger>

eg: 我要禁用日志 ,这种想法可能跟随者业务需求进行变化。

 <logger name="org.redisson.connection.DNSMonitor" level="OFF"/>

分离日志

  • additivity=“false”  不加入总日志信息
  • error 日志分离
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>logs/application_error.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><encoder><pattern>${PATTERN}</pattern></encoder><!-- 滚动策略 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 路径 --><fileNamePattern>logs/application_error.%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>1GB</maxFileSize><maxHistory>3</maxHistory><totalSizeCap>3GB</totalSizeCap></rollingPolicy>
</appender>

总结

日志系统平常开发过程中经常遇到,日志打印刷屏、日志太多、日志治理等发生在日常的开发过程中,养成一个好的习惯,好的日志更快速的排查到问题。
线上环境error日志重点关注,前提是error日志要少,如果一个error一天几百个G,会有人看?

附上完整日志配置

<?xml version="1.0" encoding="UTF-8" ?>
<configuration><include resource="org/springframework/boot/logging/logback/defaults.xml"/><property name="PATTERN"value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}]  %X{method} %-5level [%thread] [%logger:%line] :%m %n"/><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!-- 采用Spring boot中默认的控制台彩色日志输出模板 --><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern></encoder></appender><appender name="APPLICATION" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>logs/application.log</file><encoder><pattern>${PATTERN}</pattern></encoder><!-- 滚动策略 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 路径 --><fileNamePattern>logs/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>1GB</maxFileSize><maxHistory>30</maxHistory><totalSizeCap>10GB</totalSizeCap></rollingPolicy></appender><appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>logs/application_error.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><encoder><pattern>${PATTERN}</pattern></encoder><!-- 滚动策略 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 路径 --><fileNamePattern>logs/application_error.%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>1GB</maxFileSize><maxHistory>3</maxHistory><totalSizeCap>3GB</totalSizeCap></rollingPolicy></appender><appender name="LOG_FILE_OKHTTP" class="ch.qos.logback.core.rolling.RollingFileAppender" additivity="false"><file>logs/application_okhttp.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>logs/application_okhttp.%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>1GB</maxFileSize><maxHistory>2</maxHistory><totalSizeCap>2GB</totalSizeCap></rollingPolicy><!-- 格式化输出 --><encoder><pattern>${PATTERN}</pattern><charset>UTF-8</charset></encoder></appender><appender name="LOG_FILE_MIDDLEWARE" class="ch.qos.logback.core.rolling.RollingFileAppender" additivity="false"><immediateFlush>false</immediateFlush><file>logs/application_middleware_client.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>logs/application_middleware_client.%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>1GB</maxFileSize><maxHistory>2</maxHistory><totalSizeCap>2GB</totalSizeCap></rollingPolicy><!-- 格式化输出 --><encoder><pattern>${PATTERN}</pattern><charset>UTF-8</charset></encoder></appender><logger name="okhttp3.OkHttpClient" level="INFO" additivity="false"><appender-ref ref="LOG_FILE_OKHTTP"/></logger><logger name="org.apache.kafka" level="INFO" additivity="false"><appender-ref ref="LOG_FILE_MIDDLEWARE"/></logger><logger name="org.apache.zookeeper" level="INFO" additivity="false"><appender-ref ref="LOG_FILE_MIDDLEWARE"/></logger><logger name="org.apache.curator" level="INFO" additivity="false"><appender-ref ref="LOG_FILE_MIDDLEWARE"/></logger><!--    prod 和 pre 进行异步日志--><springProfile name="prod,pre"><appender name="ASYNC_APPLICATION" class="ch.qos.logback.classic.AsyncAppender"><neverBlock>true</neverBlock><queueSize>5120</queueSize><discardingThreshold>20</discardingThreshold><includeCallerData>true</includeCallerData><appender-ref ref="APPLICATION"/></appender><appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender"><neverBlock>true</neverBlock><queueSize>5120</queueSize><discardingThreshold>20</discardingThreshold><includeCallerData>true</includeCallerData><appender-ref ref="FILE_ERROR"/></appender><appender name="ASYNC_LOG_FILE_MIDDLEWARE" class="ch.qos.logback.classic.AsyncAppender"><neverBlock>true</neverBlock><queueSize>1024</queueSize><discardingThreshold>20</discardingThreshold><includeCallerData>false</includeCallerData><appender-ref ref="LOG_FILE_MIDDLEWARE"/></appender><appender name="ASYNC_LOG_FILE_OKHTTP" class="ch.qos.logback.classic.AsyncAppender"><queueSize>1024</queueSize><discardingThreshold>20</discardingThreshold><neverBlock>true</neverBlock><includeCallerData>false</includeCallerData><appender-ref ref="LOG_FILE_OKHTTP"/></appender><root level="INFO"><appender-ref ref="ASYNC_APPLICATION"/><appender-ref ref="ASYNC_ERROR"/></root></springProfile><!--test 环境和本地 不进行异步日志--><springProfile name="!prod,!pre"><root level="INFO"><appender-ref ref="APPLICATION"/><appender-ref ref="FILE_ERROR"/><!--本地环境打印console 日志--><springProfile name="!test,!dev"><appender-ref ref="CONSOLE"/></springProfile></root></springProfile><!-- 日志通过系统环境变量配置spring active: export SPRING_PROFILES_ACTIVE=devhttps://blog.csdn.net/weixin_42033269/article/details/102805546 --></configuration>

http://www.ppmy.cn/news/1529771.html

相关文章

Mysql删库跑路,如何恢复数据?

问题 删库跑路&#xff0c;数据还能恢复吗&#xff1f; 我们经常听说某某被领导训斥了&#xff0c;对领导心生痛恨&#xff0c;然后登录 Mysql 删库跑路。对于闲聊中经常听说过的一个段子&#xff0c;在现实生活中是否真的发生过&#xff0c;如果发生了&#xff0c;我们该如何解…

Android OpenGLES2.0开发(一):艰难的开始

生而为人&#xff0c;本质上&#xff0c;都是孤独的&#xff01; 引言 我一直觉得OpenGL ES是一块硬骨头&#xff0c;每次用到GLSurfaceView作为Camera的预览视图时&#xff0c;总是去网上找现成的代码。CtrlC和CtrlV之后总有一种沾沾自喜的感觉&#xff0c;但是你要让我改里面…

决策树与随机森林在机器学习中的应用

决策树与随机森林在机器学习中的应用 在机器学习领域&#xff0c;决策树&#xff08;Decision Tree&#xff09;和随机森林&#xff08;Random Forest&#xff09;是两种非常流行且强大的分类和回归算法。它们通过模拟人类决策过程&#xff0c;将复杂的数据集分割成易于理解和…

ES6中JS类实现的解读

在ES5及以前版本&#xff0c;是没有真正意义上类的概念&#xff0c;只是通过构造函数来模拟类的运用。尽管JS脚本语言是一门解释型弱语言&#xff0c;对类的需求意义不大&#xff0c;但ES6还是引入类的实现&#xff0c;让JS真正够上面向对象编程门槛&#xff0c;尽管对类的功能…

Elastic 的 OpenTelemetry PHP 发行版简介

作者&#xff1a;Pawel Filipczak 宣布 OpenTelemetry PHP 的 Elastic 发行版的第一个 alpha 版本。在本篇博文中了解使用 OpenTelemetry 来检测 PHP 应用程序是多么简单。 我们很高兴推出 OpenTelemetry PHP 的 Elastic Distribution 的第一个 alpha 版本。在这篇文章中&…

ELK-01-elasticsearch-8.15.1安装

文章目录 前言一、下载elasticsearch二、将tar包放到服务器三、解压tar包四、更改配置文件五、添加启动用户六、用elasticserch用户启动6.1 报错6.2 解决问题16.3 解决问题26.4 再次用elasticserch用户启动6.5 windows浏览器打开 七、设置开机自动启动7.1 创建启动脚本7.2 在脚…

C++ set 和 map学习

一、set(multiset)的基本知识和使用 set也是一种我们直接可以使用的容器&#xff0c;使用应该包含 #include <set> 这个头文件。此处暂且不讨论其底层&#xff0c;只探讨set如何使用即可。 我们看到&#xff0c;set 的模板参数有三个&#xff0c;第一个就是其存储的数据…

秋招面试准备:《小米2024数字芯片岗面试题》

在数字芯片设计的浪潮中&#xff0c;验证工程师的角色愈发重要。他们如同守门人&#xff0c;确保每一块芯片在投入市场前都能稳定、高效地运行。小米&#xff0c;作为全球知名的智能设备制造商&#xff0c;对数字芯片岗位的人才选拔尤为严格。 本文分享《小米2024数字芯片岗面…