【Java架构:基础技术】一篇文章搞掂:Spring Boot 官方文档解读

时间:2024-06-07 17:06:02

本文篇幅较长,建议合理利用右上角目录进行查看(如果没有目录请刷新)。

本文内容大部分是翻译和总结官方文档,可以到https://docs.spring.io/spring-boot/docs查看(此地址默认为最新版本的Spring Boot的文档,需要其他版本也可以在官网上查找)

此版本来自于https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/

26、日志

简介:

Spring Boot所有内部日志使用Apache的Commons Logging组件,同时也开放了底层的日志实现。

Spring Boot为3种日志组件Java Util Logging,Log4J2,Logback提供了默认配置,而且为每一种预设了控制台输出,并提供文件输出可选。

如果使用Spring Boot的starters组件,默认使用Logback组件。

Spring Boot提供了适当的Logback路由,以保证依赖库使用Java Util Logging, Commons Logging, Log4J, or SLF4J的时候,能正常运作。

26.1、日志格式

默认日志格式如下

2014-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

其中内容包含:

日期和时间

日志等级:ERROR, WARN, INFO, DEBUG, or TRACE.

进程ID

---:分隔符

线程名称: 包含在方括号中

日志器名:通常是来源类

日志信息

26.2、控制台输出

默认日志配置会在写入消息时将消息回传给控制台。

默认情况下,将记录ERROR级别,WARN级别和INFO级别的消息。您还可以通过使用--debug标志启动应用程序来启用“调试”模式。

运行时:

$ java -jar myapp.jar --debug

也可以在application.properties文件中设置

debug=true

当启用调试模式,是指让一些内部日志器(如嵌入式容器,Hibernate和Spring Boot)把Debug日志也输出出来。

是否启动调试模式,并不会影响用户自定义的Debug日志是否显示。

同样,可以通过--trace或者trace=true的形式,让系统中一些内部日志器输出跟踪信息。

控制颜色输出

如果终端支持ANSI,则可以通过输出带颜色的文字提高可读性。

增加设置

#输出彩色日志
spring.output.ansi.enabled=ALWAYS

[这部分未细看]

You can set spring.output.ansi.enabled to a supported value to override the auto detection.

Color coding is configured by using the %clr conversion word. In its simplest form, the converter colors the output according to the log level, as shown in the following example:

%clr(%5p)

The following table describes the mapping of log levels to colors:

Level Color

FATAL

Red

ERROR

Red

WARN

Yellow

INFO

Green

DEBUG

Green

TRACE

Green

Alternatively, you can specify the color or style that should be used by providing it as an option to the conversion. For example, to make the text yellow, use the following setting:

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}

The following colors and styles are supported:

  • blue
  • cyan
  • faint
  • green
  • magenta
  • red
  • yellow

26.3、文件输出

默认情况下,Spring Boot只会在控制台输出日志信息。我们可以设置让Spring Boot把日志信息输出到文件中。

可以在application.properties文件中设置logging.filelogging.path属性

  • 2个属性都不设置时,则只在控制台输出日志
  • logging.file=my.log:写到特定文件中,可以是相对路径或者绝对路径(注意,地址不能是盘符下,如c:/my.log,这样会无效)
  • logging.path=/var/log:写到特定文件夹中,可以是相对路径或者绝对路径

默认情况下当文件达到10MB,会重新创建一个文件继续记录,默认记录ERRORWARN, INFO等级的日志。

  • 设置logging.file.max-size可以改变文件的大小限制
  • 默认下,之前的日志文件会一直保存,可以通过logging.file.max-history属性来设置保存多少的历史日志

注意2点:

  • 日志记录系统在应用程序生命周期的很早期就进行了初始化。因此,不能在属性文件中通过@PropertySource注释设置日志属性。
  • Spring Boot的日志属性是独立于基础组件的(如logback),所以组件的属性(如logback的logback.configurationFile)不被Spring Boot所管理,Spring Boot只管理自己的日志属性(上限讨论的属性)

26.4、日志等级

可以在Spring环境(例如application.properties)中为所有支持的日志系统设置日志记录等级。

通过logging.level.<logger-name>=<level> 进行设置,其中logger-name是调用logger-name时传入的名称(下面实例中了解),level是日志等级

level日志等级包括:TRACE, DEBUG, INFO, WARN, ERROR, FATAL, or OFF

可以通过logging.level.root=<level> 来进行统一配置

一个使用实例

logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

26.5、自定义日志配置

各种日志系统,可以通过以下方式进行自定义配置:

  • 将适当的依赖类放置到类路径下
  • 然后创建一个对应的配置文件放在类路径根目录下;或使用Spring环境属性logging.config指明对应配置文件

可以通过org.springframework.boot.logging.LoggingSystem属性,强制Spring Boot使用特定的一个日志系统;

这个值必须是一个日志系统实现的全限定类名;

也可以设置为none,完全禁止Spring Boot的日志配置。

注意!因为日志系统在ApplicationContext之前创建,所以日志属性只能通过properties文件进行设置,无法通过Sprint@Configuration文件中使用@PropertySources设置。

根据指定的系统,回加载对应的配置文件

  • Logback:logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy

  • Log4j2:log4j2-spring.xml or log4j2.xml

  • JDK (Java Util Logging):logging.properties

建议使用-spring的命名方式

当使用Java Util Logging时,如果运行一个外部可执行jar,会产生类加载问题;所以推荐使用外部可执行jar时,禁止这个日志系统

为了实现自定义,Spring Boot将一些配置从Spring环境中转移到系统properties中去

Spring Environment System Property Comments

logging.exception-conversion-word

LOG_EXCEPTION_CONVERSION_WORD

The conversion word used when logging exceptions.

logging.file

LOG_FILE

If defined, it is used in the default log configuration.

logging.file.max-size

LOG_FILE_MAX_SIZE

Maximum log file size (if LOG_FILE enabled). (Only supported with the default Logback setup.)

logging.file.max-history

LOG_FILE_MAX_HISTORY

Maximum number of archive log files to keep (if LOG_FILE enabled). (Only supported with the default Logback setup.)

logging.path

LOG_PATH

If defined, it is used in the default log configuration.

logging.pattern.console

CONSOLE_LOG_PATTERN

The log pattern to use on the console (stdout). (Only supported with the default Logback setup.)

logging.pattern.dateformat

LOG_DATEFORMAT_PATTERN

Appender pattern for log date format. (Only supported with the default Logback setup.)

logging.pattern.file

FILE_LOG_PATTERN

The log pattern to use in a file (if LOG_FILE is enabled). (Only supported with the default Logback setup.)

logging.pattern.level

LOG_LEVEL_PATTERN

The format to use when rendering the log level (default %5p). (Only supported with the default Logback setup.)

PID

PID

The current process ID (discovered if possible and when not already defined as an OS environment variable).

如果想在日志记录属性中使用占位符,则应该使用Spring Boot的语法,而不是基础框架的语法。值得注意的是,如果你使用Logback,你应该使用:作为属性名和默认值之间的分隔符,而不是使用:- 。

[这段不太明白]

You can add MDC and other ad-hoc content to log lines by overriding only the LOG_LEVEL_PATTERN (or logging.pattern.level with Logback). For example, if you use logging.pattern.level=user:%X{user} %5p, then the default log format contains an MDC entry for "user", if it exists, as shown in the following example.

2015-09-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request

26.6、Logback扩展

这部分略,需要的自行查看Spring Boot官方文档

26.7、实际应用

例子:

希望可以输出各种等级的日志,并写到文件中方便查看

在application.properties文件中设置

#启动调试模式(一般不需要,因为只是输出内部组件的debug信息,不影响用户自行输出的日志)
debug=true
#输出彩色日志(不建议使用,IDE会很卡)
spring.output.ansi.enabled=ALWAYS
#设置文件输出(注意,地址不能是盘符下,如c:/my.log,这样会无效)
logging.file=c:/var/my.log

看spring-boot-starter包结构中日志部分

【Java架构:基础技术】一篇文章搞掂:Spring Boot 官方文档解读

方框中分别是包含了3个日志系统的实现,分别是Java Util Logging,Log4J2,Logback

3者都是用了slf4j这个包,这是一个日志系统的门面抽象,这3个日志系统都实现了这个门面,所以我们可以使用这个门面进行日志编程

写法1:创建一个Logger对象

public class Class1 {
private static final Logger logger = LoggerFactory.getLogger(Class1.class);
public void hello() {
logger.info("hello");
}
}

写法2:使用lombok的@Slf4j注解简化代码

待补充

31、缓存

首先,必须先熟悉Spring下的缓存设置,可以参考我的这篇文章的第十三条https://www.cnblogs.com/LiveYourLife/p/9249321.html

在Spring的缓存核心技术中,通过为方法标注注解,对方法应用缓存,将数据放到缓存中,可以减少查询和计算操作。

注意:在Spring中,你可以使用Spring Cache注解和标准的JSR-107 (JCache)注解,但建议不要混用。

31.1、Spring Boot中对缓存的默认配置

在Spring中,我们启用Spring缓存,一般有以下几个步骤

  • 使用@EnableCaching注解或XML文件启用缓存
  • 配置一个缓存管理器,选择一个或多个缓存实现

在Spring Boot中,我们使用@EnableCaching启用了Spring缓存,Spring Boot默认为我们配置了基于内存的ConcurrentMapCacheManager缓存管理器

我们无需要任何配置即可使用@Cacheable、@CachePut、@CacheEvict注解进行缓存,此时的缓存数据是放到程序所在系统的内存中

当然一般我们不会这么使用,基于系统内存的缓存一般只用于测试等。

Spring Boot支持了很多缓存提供商的实现,有一些可以通过spring.cache.cache-names这个属性来配置相关属性

31.2、支持的缓存提供商

Spring Boot的缓存抽象并没有提供实际的实现,而是依赖于org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,也就是使用的是Spring中的缓存技术

如果你没有自行创建一个CacheManager的bean,或者名为cacheResolver的CacheResolver,Spring Boot会自动检测以下提供商并自行配置(默认是Simple即使用ConcurrentMapCacheManager)

检测顺序如下面列出的顺序

  • Generic
  • JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
  • EhCache 2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine
  • Simple

可以使用spring.cache.type属性来强制指定提供商,或者使用spring.cache.type=none来关闭缓存

使用spring-boot-starter-cache依赖可以快速添加基础的缓存依赖,这个依赖里面包含了spring-context-support;如果是手动添加依赖,如果想要支持JCache, EhCache 2.x, or Guava,必须手动引入spring-context-support依赖

如果CacheManager不是你自行创建的,是由Spring Boot管理配置的,那么你可以通过实现CacheManagerCustomizer这个接口来优化配置对应的CacheManager

@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setAllowNullValues(false);
}
};
}

如果你自行提供CacheManager或者Spring Boot自动配置是使用其它的缓存提供商,那么这个设置不会生效。

你也可以设置多个配置,使用@Order或Ordered设置顺序

31.2.1、Generic

代表使用自行设置的CacheManager。当自行配置一个CacheManager的时候,会使用这种形式;如果指定使用这种形式,又没有对应的CacheManager的bean,则会报错。

31.2.2、JCache (JSR-107)【暂时略过】

31.2.3、EhCache 2.x【暂时略过】

31.2.4、Hazelcast【暂时略过】

31.2.5、Infinispan【暂时略过】

31.2.6、Couchbase【暂时略过】

31.2.7、Redis

在POM文件中引入

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

那么Spring Boot会自动配置一个RedisCacheManager

使用spring.cache.cache-names在启动的时候添加附加缓存(不知道是不是这个意思,实测无效)

使用spring.cache.redis.*参数可以设置redis相关参数

spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=600000

默认情况下,Spring Boot会根据注解的Value值一个键前缀,如果两个单独的缓存使用相同的键,Redis也不会有重叠的键,不会返回错误数据。即使您创建自己的RedisCacheManager,我们强烈建议您保持启用此设置。

例如

@Cacheable("cache1")
public String Test(String name) {
return "abc";
}

缓存到Redis的键值是

【Java架构:基础技术】一篇文章搞掂:Spring Boot 官方文档解读

另外,可以通过设置一个RedisCacheConfiguration的bean来获取RedisCacheManager的完全控制

例如设置值的序列化方式(默认是字节码,改成字符串)

@EnableCaching
@Configuration
public class CacheConfig {
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
configuration = configuration
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.entryTtl(Duration.ofDays(30));
return configuration;
}
}

31.2.8、Caffeine【暂时略过】

31.2.9、Simple

在开启@EnableCaching缓存时,又没有找到以上的供应商时,会使用这种形式。这种形式使用ConcurrentMapCacheManager这种实现来进行基于系统内存的缓存

此时,可以通过

spring.cache.cache-names=cache1,cache2

来设置支持的缓存名称,例如:

@Cacheable("cache1")
public void Test(int i) {
// TODO Auto-generated method stub
logger.info("执行方法了!");
}

如果cache-names设置了cache1,则程序正常进行;如果没有设置,则程序会报错。

31.2.10、None

在开启@EnableCaching缓存时,可以通过spring.cache.type=none来设置关闭缓存