常用组合

  • Commons Logging和Log4j
  • SLF4J和Logback

参考

SLF4J不同的日志实现选择
https://blog.csdn.net/u010825931/article/details/106167241
使用SLF4J和Logback
https://www.liaoxuefeng.com/wiki/1252599548343744/1264739155914176
SpringBoot系列(6):SpringBoot集成slf4j日志配置
https://blog.csdn.net/qq_27706119/article/details/104977666
SpringBoot优雅地配置日志
https://www.cnblogs.com/coderxx/p/11390341.html

Log4j2配置

输出格式化详解

<Properties>
	<property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss}] [%-8p][%-30thread][%-54c][%-20M][%-6L]-> %m%n" />
</Properties>
[2021-10-11 12:01:15] [INFO    ][main                          ][com.gzhuiqun.adapter.Application                      ][run                 ][166   ]-> [初始化] 获取redis常用变量
[2021-10-11 12:01:15] [INFO    ][main                          ][com.gzhuiqun.adapter.Application                      ][run                 ][350   ]-> 程序加载完毕

输出的字段对应的值:

  • %p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
  • %d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
  • %r:输出自应用程序启动到输出该log信息耗费的毫秒数。
  • %t:输出产生该日志事件的线程名。
  • %l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。
  • %c:输出日志信息所属的类目,通常就是所在类的全名。
  • %M:输出产生日志信息的方法名。
  • %F:输出日志消息产生时所在的文件名称。
  • %L:输出代码中的行号。
  • %m:输出代码中指定的具体日志信息。
  • %n:输出一个回车换行符,Windows平台为"rn",Unix平台为"n"。
  • %x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
  • %%:输出一个"%"字符。

对齐:
比如%c输出的是类的全名,我们要让输出的时候保证输出的长度为50,为空自动补空格,则可以改成%50c;
默认是右对齐,如果要左对齐则%-50c;
如果超出50的自动截取掉不显示,则%.50c,注意小于50不会自动补的;
如果要小于20补齐,大于30截取,右对齐,则%20.30c;

对齐问题:
在控制台或者用记事本打开时,可以看到还是不对齐的,这时候用VSCode工具看就能对齐了。

不会打印日志问题

在SpringBoot中,在main函数中使用slf4j打印日志会出现没有输出的情况。
这得看是使用什么实现,如果是SpringBoot自带的Logback,还是能够输出的。
如果是Log4j,则会出现输出不了的情况。
这种情况分析,应该是如果SpringBoot启动之前,还没有依据resources中的日志配置/自带的默认配置进行注入,所以在启动之前打印,由于Log4j还没有对应的配置文件所以输出不了日志;而Logback之所以能输出,猜测可能它自身会判断没有配置会使用自己的配置,所以还是能输出的。

SpringBoot项目自带的SLF4J和Logback进行实验

ApplicationRunnerTest:

package com.example.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class ApplicationRunnerTest implements ApplicationRunner {

    private static final Logger logger = LoggerFactory.getLogger(ApplicationRunnerTest.class);


    @Override
    public void run(ApplicationArguments args) throws Exception {
        logger.error("SpringBoot启动之后输出");
    }
}

DemoApplication :

package com.example.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    private static final Logger logger = LoggerFactory.getLogger(DemoApplication.class);

    public static void main(String[] args) {
        logger.debug("SpringBoot启动之前输出");
        SpringApplication.run(DemoApplication.class, args);
    }

}

打印结果:

10:58:11.070 [main] DEBUG com.example.demo.DemoApplication - SpringBoot启动之前输出
. ____ _ __ _ _
/\ / ' __ _ () __ __ _ \ \ \
( ( )_
_ | '_ | '| | ' / ` | \ \ \
\/ __)| |)| | | | | || (
| | ) ) ) )
' || .__|| ||| |_, | / / / /
=========|
|==============|
/=////
:: Spring Boot :: (v2.3.7.RELEASE)
2021-10-11 10:58:12.479 INFO 15044 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication on heawill with PID 15044 (C:\Users\Heawill\Desktop\demo\target\classes started by Heawill in C:\Users\Heawill\Desktop\demo)
2021-10-11 10:58:12.480 INFO 15044 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-10-11 10:58:13.229 INFO 15044 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.937 seconds (JVM running for 3.099)
2021-10-11 10:58:13.232 ERROR 15044 --- [ main] com.example.demo.ApplicationRunnerTest : SpringBoot启动之后输出

可以看到,"SpringBoot启动之前输出"这句话是可以打印出来,唯一差别就是它打印的样式和"SpringBoot启动之后输出"的打印样式不同,这是因为SpringBoot还没启动,它对应的日志配置还没生效,所以Logback使用了自带默认的配置导致的。
此外,如果把"SpringBoot启动之后输出"的输出级别从error改成跟"SpringBoot启动之前输出"一样的debug级别,我们会发现"SpringBoot启动之后输出"不能输出,而"SpringBoot启动之前输出"可以输出,这是由于Logback自带默认的配置debug是可以输出的,而SpringBoot启动后,日志配置变了,SpringBoot默认的日志配置debug级别是不能输出的。