老蒋的知识库

  • 首页
  • 文章归档
  • 关于页面

  • 搜索

Java Spring Logging 使用技巧

发表于 2023-09-23 | 分类于 Java | 0 | 阅读次数 45

动态修改日志等级

代码修改日志等级(不建议自己写)

@Slf4j
public class DemoTests {
    @Test
    public void test2(){
        log.debug("debug");
        log.info("info");
        log.warn("warn");
        log.error("error");
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        // 这里一定不要写 `com.demo.*` 带上 .* 匹配不到
        Logger logger = loggerContext.getLogger("com.demo");
        logger.setLevel(Level.WARN);
        log.debug("debug");
        log.info("info");
        log.warn("warn");
        log.error("error");
    }
}

Nacos配置中心动态变更日志等级(建议使用)

文档:https://halo.ljdzsk.com/archives/nacos-xiao-ji-qiao

logback.xml 编写自定义输出配置

编写完成后放置resources中,Spring Boot 读取顺序(后读取覆盖前面配置): logback.xml -> application.yml -> logback-spring.xml 。

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 日志存放路径 -->
    <property name="log.path" value="logs"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern"
              value="%d{MMdd HH:mm:ss.SSS,Asia/Shanghai} [%thread] %-5level %logger{5} - [%method,%line] - %msg%n"/>

    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 只会打印INFO不会有DEBUG、ERROR其他级别日志-->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 只会打印ERROR日志-->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- ruoyi模块日志控制  -->
    <logger name="com.ruoyi" level="info"/>

    <!-- Spring日志控制  -->
    <logger name="org.springframework" level="warn"/>

    <!-- 阿里组件日志控制  -->
    <logger name="com.alibaba" level="info"/>

    <!-- 抖音日志控制  -->
    <logger name="com.douyin" level="info"/>

    <!--全局配置-->
    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file_info"/>
        <appender-ref ref="file_error"/>
    </root>
</configuration>

字段contextName

每个logger都有默认上下文名称为default(如果不设置)。可以设置成其他名字用于区分不同应用程序的记录。一旦设置不能(动态)修改。
如果同时存在logback.xml和logback-spring.xml,但这两个配置文件的contextName不同,就会报错。

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>default</contextName>
</configuration>

字段property

用来定义变量值的标签, 有两个属性name是变量的名称,value是变量的值,通过“${}”来使用变量。

字段appender

appender的是日志的渲染器,可以定义不同的渲染(输出)格式、输出位置。

  • 过滤方式、输出到不同文件或控制台、日志文件保留时间等。
  • appender的过滤的级别,只会打印单一级别日志,例如:定义DEBUG级别日志,不会输出INFO、ERROR等其他级别日志。

字段 root、logger

root定义全局,比如:使用哪种渲染器,监听日志等级。

<!-- root作用于全局,添加哪个appender就会使用哪个appender输出一次日志 -->
<root level="DEBUG">
  <appender-ref ref="CONSOLE" />
  <appender-ref ref="DEBUG_FILE" />
  <appender-ref ref="INFO_FILE" />
  <appender-ref ref="WARN_FILE" />
  <appender-ref ref="ERROR_FILE" />
</root>

logger对单个包或类添加配置,相当于局部配置,logger覆盖root的配置。

  • 日志向上传递配置additivity="true"(默认true),此时logger输出日志同时root也会接受传递的日志通过自身的appender再输出一遍日志。如果root和logger同时作用于一个包,建议添加additivity="false"
  • logger同时作用父子包时,子包的level会覆盖父包,子包如果不添加additivity="false",子包输出日志后会传递给父包再输出一遍日志。(root和logger的关系就像,logger的父子包的关系)
	# com.test.task 控制台输出一遍日志
    <logger name="com.test" level="info">
        <appender-ref ref="console"/>
    </logger>
    <logger name="com.test.task" level="info" additivity="false">
        <appender-ref ref="console"/>
    </logger>

	# com.test.task 控制台输出两遍日志
    <logger name="com.test" level="info">
        <appender-ref ref="console"/>
    </logger>
    <logger name="com.test.task" level="info" additivity="true">
        <appender-ref ref="console"/>
    </logger>

	# com.test.task 控制台输出两遍日志
    <logger name="com.test" level="info">
        <appender-ref ref="console"/>
    </logger>
    <logger name="com.test.task" level="info">
        <appender-ref ref="console"/>
    </logger>

	# com.test.task 控制台输出一遍日志
    <logger name="com.test" level="info">
        <appender-ref ref="console"/>
    </logger>
    <logger name="com.test.task" level="info">
    </logger>

log.pattern 日志输出格式说明

转换符作用
c {length } 
lo {length } 
logger {length } 
输出日志的logger名,可有一个整形参数,功能是缩短logger名,设置为0表示只输入logger最右边点符号之后的字符串。
Conversion specifierLogger nameResult
%logger mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar
%logger{0} mainPackage.sub.sample.Bar Bar
%logger{5} mainPackage.sub.sample.Bar m.s.s.Bar
%logger{10} mainPackage.sub.sample.Bar m.s.s.Bar
%logger{15} mainPackage.sub.sample.Bar m.s.sample.Bar
%logger{16} mainPackage.sub.sample.Bar m.sub.sample.Bar
%logger{26} mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar

 

C {length } 
class {length } 
输出执行记录请求的调用者的全限定名。参数与上面的一样。尽量避免使用,除非执行速度不造成任何问题。
contextName 
cn 
输出上下文名称。
d {pattern } 
date {pattern } 
输出日志的打印日志,模式语法与java.text.SimpleDateFormat 兼容。
Conversion PatternResult
%d 2006-10-20 14:06:49,812
%date 2006-10-20 14:06:49,812
%date{ISO8601} 2006-10-20 14:06:49,812
%date{HH:mm:ss.SSS} 14:06:49.812
%date{dd MMM yyyy ;HH:mm:ss.SSS} 20 oct. 2006;14:06:49.812
F / file 输出执行记录请求的java源文件名。尽量避免使用,除非执行速度不造成任何问题。
caller{depth} caller{depth, evaluator-1, ... evaluator-n} 输出生成日志的调用者的位置信息,整数选项表示输出信息深度。

例如, %caller{2}   输出为:

0    [main] DEBUG - logging statement 
Caller+0   at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1   at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)

例如, %caller{3}   输出为:

16   [main] DEBUG - logging statement 
Caller+0   at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1   at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
Caller+2   at mainPackage.ConfigTester.main(ConfigTester.java:38)
L / line 输出执行日志请求的行号。尽量避免使用,除非执行速度不造成任何问题。
m / msg / message

输出应用程序提供的信息。

M / method 输出执行日志请求的方法名。尽量避免使用,除非执行速度不造成任何问题。
n 输出平台先关的分行符“\n”或者“\r\n”。
p / le / level 输出日志级别。
r / relative 输出从程序启动到创建日志记录的时间,单位是毫秒
t / thread 输出产生日志的线程名。
replace(p ){r, t}

p 为日志内容,r 是正则表达式,将p 中符合r 的内容替换为t 。

例如, "%replace(%msg){'\s', ''}"

格式修饰符,与转换符共同使用:

可选的格式修饰符位于“%”和转换符之间。

第一个可选修饰符是左对齐 标志,符号是减号“-”;接着是可选的最小宽度 修饰符,用十进制数表示。如果字符小于最小宽度,则左填充或右填充,默认是左填充(即右对齐),填充符为空格。如果字符大于最小宽度,字符永远不会被截断。最大宽度 修饰符,符号是点号"."后面加十进制数。如果字符大于最大宽度,则从前面截断。点符号“.”后面加减号“-”在加数字,表示从尾部截断。

例如:%-4relative 表示,将输出从程序启动到创建日志记录的时间 进行左对齐 且最小宽度为4。

  • 本文作者: jagger
  • 本文链接: /archives/javaspringlogging-ri-zhi-shu-chu-ge-shi-pei-zhi
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
Java Aop 切面编程定制化打印Api接口日志
Java Spring 公共组件开发与自动装配
jagger

jagger

66 日志
31 分类
0 标签
Creative Commons
0%
© 2026 jagger
由 Halo 强力驱动