Spring Boot Logging 开发指南

1. Spring Boot Logging 开发指南

1.1. 版本说明

构件 版本
spring-boot 2.7.18

1.2. Spring Boot Logging 介绍

从 Spring Framework 5.0 开始,Spring 附带了自己的 Commons Logging 日志门面,在spring-jcl模块中实现。该实现检查 classpath 中是否存在 Log4j 2.x API 和 SLF4J 1.7 API,并使用第一个找到的 API 作为日志记录实现,如果 Log4j 2.x 和 SLF4J 都不可用,则使用 Java 平台的核心日志记录工具(也称为 JUL 或 java.util.logging)。

Spring Boot 所有内部日志使用 Commons Logging 来记录,但使底层日志实现是开放的。并且为 Java Util Logging、Log4J2 和 Logback 提供默认配置。每种日志实现都预先配置为使用控制台输出,并且还提供文件输出可选选项。

spring-boot-starter 默认引入 Logback 来记录日志。Logback 路由也被包含进来,以确保 Java Util Logging、Commons Logging、Log4J 或 SLF4J 等都能正常工作。

注意:
spring-jcl 仅用于核心框架和扩展中的基础设施日志记录。
对于应用程序代码中的日志记录需求,最好直接使用 Log4j 2.x、SLF4J 或 JUL。

各日志框架的对应关系:

block-beta columns 10 top_note[["顶层"]] right_top_note<[" "]>(right) block:top:8 sbl["Spring Boot Logging"] end space:10 bridge_note[["门面"]] right_bridge_note<[" "]>(right) block:bridge:8 jcl["Commons Logging"] slf4j["SLF4J"] end space:10 bottom_note[["底层"]] right_bottom_note<[" "]>(right) block:bottom:8 logback["Logback"] log4j["Log4j 2.x"] jul["java.util.logging"] other["Other..."] end sbl --> jcl sbl --> slf4j jcl --> logback jcl --> log4j jcl --> jul jcl --> other slf4j --> logback slf4j --> log4j slf4j --> jul slf4j --> other

spring-boot-starter-logging模块及其依赖:

+- org.springframework.boot:spring-boot-starter-logging:jar:2.7.18:compile
|  +- ch.qos.logback:logback-classic:jar:1.2.12:compile
|  |  +- ch.qos.logback:logback-core:jar:1.2.12:compile
|  |  \- org.slf4j:slf4j-api:jar:1.7.36:compile
|  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.2:compile
|  |  \- org.apache.logging.log4j:log4j-api:jar:2.17.2:compile
|  \- org.slf4j:jul-to-slf4j:jar:1.7.36:compile

1.3. 控制台日志颜色

控制台日志颜色由%clr转换字符配置的。最简单的形式是根据日志级别对日志着色。示例:

%clr(%5p)

日志等级和对应的颜色映射:

日志等级 颜色
FATAL Red
ERROR Red
WARN Yellow
INFO Green
DEBUG Green
TRACE Green

注意:
Logback 没有 FATAL 日志等级,它被映射到 ERROR 日志等级

也可以通过转换参数指定日志颜色。示例:

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

支持以下颜色样式:

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

1.4. 日志组

将多个 logger 分成一组可以很方便的对多个 logger 统一管理,设置日志级别。

Spring Boot 内置日志组:

日志组 logger
web org.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans
sql org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener

1.4.1. 日志组示例

application.yml 配置:

logging:
  group:
    my-logging-group:
      - com.logging.demo.LoggingGroupOne
      - com.logging.demo.LoggingGroupTwo
  level:
    my-logging-group: info

第一个日志打印代码:

package com.logging.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class LoggingGroupOne implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        log.trace("trace");
        log.debug("debug");
        log.info("info");
        log.warn("warn");
        log.error("error");
    }
}

第二个日志打印代码:

package com.logging.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class LoggingGroupTwo implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        log.trace("trace");
        log.debug("debug");
        log.info("info");
        log.warn("warn");
        log.error("error");
    }
}

运行程序,将打印出info等级以上的日志:

2024-07-11 15:36:24.013  INFO 42357 --- [           main] com.logging.demo.LoggingGroupOne         : info
2024-07-11 15:36:24.013  WARN 42357 --- [           main] com.logging.demo.LoggingGroupOne         : warn
2024-07-11 15:36:24.013 ERROR 42357 --- [           main] com.logging.demo.LoggingGroupOne         : error
2024-07-11 15:36:24.013  INFO 42357 --- [           main] com.logging.demo.LoggingGroupTwo         : info
2024-07-11 15:36:24.013  WARN 42357 --- [           main] com.logging.demo.LoggingGroupTwo         : warn
2024-07-11 15:36:24.013 ERROR 42357 --- [           main] com.logging.demo.LoggingGroupTwo         : error

1.5. 自定义日志配置文件

1.5.1. 手动指定配置文件

application.yml文件中通过logging.config来指定配置文件,示例:

logging:
  config: classpath:my-logback.xml

1.5.2. 自动加载配置文件

根据日志系统不同,Spring Boot 将自动加载以下配置文件:

日志系统 配置文件
Logback logback-spring.xmllogback-spring.groovylogback.xmllogback.groovy
Log4j2 log4j2-spring.xmllog4j2.xml
JDK (Java Util Logging) logging.properties

注意:
建议使用 -spring 变体作为日志记录配置(例如,logback-spring.xml 而不是 logback.xml)。如果使用标准配置 logback.xml,Spring 无法完全控制日志初始化。

警告:
从可执行 jar 包运行时,Java Util Logging 存在类加载问题。建议在可执行 jar 包中避免使用 JUL。

1.6. Logback 扩展

Spring Boot 包含许多 Logback 扩展,可以帮助进行高级配置。可以在 logback-spring.xml 配置文件中使用这些扩展。

注意:
由于标准 logback.xml 配置文件加载得太早,因此无法在其中使用扩展。需要使用 logback-spring.xml 或定义 logging.config 属性。

1.6.1. 特定 Profile 配置

<springProfile> 标签可以指定一个 Profile 名称或者表达式,标签内的配置内容将在特定的 Profile 下生效。示例:

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

1.6.2. 访问 Spring 环境变量

<springProperty> 标签可以读取 Spring 环境变量给 Logback 使用。示例:

<!--应用名-->
<springProperty scope="context" name="APPLICATION_NAME" source="spring.application.name"/>
<!--日志文件名-->
<property name="LOG_FILE" value="logs/${APPLICATION_NAME}.log"/>

1.7. 最佳实践

1.7.1. 基于 Spring Boot 默认配置文件自定义 Logback 配置

Spring Boot 内置了 org/springframework/boot/logging/logback/base.xmlorg/springframework/boot/logging/logback/defaults.xmlorg/springframework/boot/logging/logback/console-appender.xmlorg/springframework/boot/logging/logback/file-appender.xml 等默认配置,可以 include 这些配置文件来改造自己项目的日志配置。

logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--应用名-->
    <springProperty scope="context" name="APPLICATION_NAME" source="spring.application.name"/>
    <!--控制台日志模式-->
    <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} - %clr(%p) - [%t] %clr(%logger{39}){cyan} %clr(%X{TRACE}){red}: %m%n"/>
    <!--文件日志模式-->
    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} - %p - [%t] %logger{39} %X{TRACE}: %m%n"/>
    <!--日志文件名-->
    <property name="LOG_FILE" value="logs/${APPLICATION_NAME}.log"/>
    <!--滚动日志名模式-->
    <property name="LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN" value="${LOG_FILE}.%d{yyyy-MM-dd}.%i"/>
    <!--滚动日志最大文件大小-->
    <property name="LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE" value="100MB"/>
    <!--滚动日志最大历史记录-->
    <property name="LOGBACK_ROLLINGPOLICY_MAX_HISTORY" value="30"/>
    <!--引入 Spring Boot Logback 配置模板-->
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <!--开发环境配置-->
    <springProfile name="dev">
        <root level="debug"/>
        <logger name="org.springframework" level="DEBUG"/>
    </springProfile>
    <!--测试、生产环境配置-->
    <springProfile name="test|prod">
        <root level="INFO"/>
    </springProfile>
</configuration>

1.7.2. 日志链路追踪

在典型的多线程应用程序中,如 Web 系统,不同的线程处理来自不同客户端的请求并打印日志,如何区分哪些日志是来自哪个请求的呢?一个轻量级的技术是为每个请求日志添加唯一标识,MDC(Mapped Diagnostic Context)正是这种技术的实现,在 SLF4J 中,MDC 通过 ThreadLocal 把唯一标识的 Key 和 Value 存入 HashMap 中,从而实现线程和唯一标识的绑定。

接下来基于 Spring Boot、SLF4J 和 Logback 来自定义 MDC 注解和切面来实现日志链路追踪。

  1. 自定义 MDC 注解
package com.logging.demo;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MDC {
}
  1. 编写 MDC 切面,在被拦截的方法执行前设置 MDC,key 为“TRACE”,value 为 UUID,在方法执行结束移除这个 key。
package com.logging.demo;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import java.util.UUID;

@Aspect
@Component
public class MdcAspect {

    private static final String TRACE = "TRACE";

    @Pointcut("@annotation(com.logging.demo.MDC)")
    public void mdcPointCut() {
    }

    @Around("mdcPointCut()")
    public Object doMdc(ProceedingJoinPoint joinPoint) throws Throwable {
        MDC.put(TRACE, UUID.randomUUID().toString());
        try {
            return joinPoint.proceed();
        } finally {
            MDC.remove(TRACE);
        }
    }
}
  1. 在 Logback 配置文件中配置日志模式,%X{TRACE} 可以将切面中设置好的 MDC value 打印到日志中。Logback 配置文件参考 1.7.1. 基于 Spring Boot 默认配置文件自定义 Logback 配置

  2. 编写测试代码

package com.logging.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class MdcDemo {
    @MDC
    public void log() {
        log.info("Hello MDC!");
    }
}
  1. 日志输出结果
2024-07-12 08:51:18.650 - INFO - [main] com.logging.demo.MdcDemo 5b99a9cf-7a36-4976-a63e-b4d4fb901a16: Hello MDC!

1.8. Spring Boot Logging 所有配置

  1. debug: Enable debug logs. Default: false.
  2. trace: Enable trace logs. Default: false.
  3. logging.charset.console: Charset to use for console output.
  4. logging.charset.file: Charset to use for file output.
  5. logging.config: Location of the logging configuration file. For instance, classpath:logback.xml for Logback.
  6. logging.exception-conversion-word: Conversion word used when logging exceptions. Default: %wEx.
  7. logging.file.name: Log file name (for instance, myapp.log). Names can be an exact location or relative to the current directory.
  8. logging.file.path: Location of the log file. For instance, /var/log.
  9. logging.group.*: Log groups to quickly change multiple loggers at the same time. For instance, logging.group.db=org.hibernate,org.springframework.jdbc.
  10. logging.level.*: Log levels severity mapping. For instance, logging.level.org.springframework=DEBUG.
  11. logging.log4j2.config.override: Overriding configuration files used to create a composite configuration.
  12. logging.logback.rollingpolicy.clean-history-on-start: Whether to clean the archive log files on startup. Default: false.
  13. logging.logback.rollingpolicy.file-name-pattern: Pattern for rolled-over log file names. Default: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
  14. logging.logback.rollingpolicy.max-file-size: Maximum log file size. Default: 10MB.
  15. logging.logback.rollingpolicy.max-history: Maximum number of archive log files to keep. Default: 7.
  16. logging.logback.rollingpolicy.total-size-cap: Total size of log backups to be kept. Default: 0B.
  17. logging.pattern.console: Appender pattern for output to the console. Supported only with the default Logback setup. Default: %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}.
  18. logging.pattern.dateformat: Appender pattern for log date format. Supported only with the default Logback setup. Default: yyyy-MM-dd HH:mm:ss.SSS.
  19. logging.pattern.file: Appender pattern for output to a file. Supported only with the default Logback setup. Default: %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}.
  20. logging.pattern.level: Appender pattern for log level. Supported only with the default Logback setup. Default: %5p.
  21. logging.register-shutdown-hook: Register a shutdown hook for the logging system when it is initialized. Disabled automatically when deployed as a war file. Default: true.

1.9. Logback 所有转换字符

1.9.1. c{length}

c{length} or lo{length} or logger{length}

Outputs the name of the logger at the origin of the logging event.

This conversion word takes an integer as its first and only option. The converter's abbreviation algorithm will shorten the logger name, usually without significant loss of meaning. Setting the value of length option to zero constitutes an exception. It will cause the conversion word to return the sub-string right to the rightmost dot character in the logger name. The next table provides examples of the abbreviation algorithm in action.

Conversion specifier Logger name Result
%logger mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar
%logger mainPackage.sub.sample.Bar Bar
%logger mainPackage.sub.sample.Bar m.s.s.Bar
%logger mainPackage.sub.sample.Bar m.s.s.Bar
%logger mainPackage.sub.sample.Bar m.s.sample.Bar
%logger mainPackage.sub.sample.Bar m.sub.sample.Bar
%logger mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar

Please note that the rightmost segment in a logger name is never abbreviated, even if its length is longer than the length option. Other segments may be shortened to at most a single character but are never removed.

1.9.2. C{length}

C{length} or class{length}

Outputs the fully-qualified class name of the caller issuing the logging request.

Just like the %logger conversion word above, this conversion takes an integer as an option to shorten the class name. Zero carries special meaning and will cause the simple class name to be printed without the package name prefix. By default the class name is printed in full.

Generating the caller class information is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

1.9.3. contextName

contextName or cn

Outputs the name of the logger context to which the logger at the origin of the event was attached to.

1.9.4. d{pattern}

d{pattern} or date{pattern} or d{pattern, timezone} or date{pattern, timezone} or d{pattern, timezone, locale} or date{pattern, timezone, locale}

Used to output the date of the logging event. The date conversion word admits a pattern string as a parameter. The pattern syntax is compatible with the format accepted by java.text.SimpleDateFormat (in logback 1.2.x) and java.time.format.DateTimeFormatter (in logback 1.3.x).

You can specify the string "ISO8601" for the ISO8601 date format. Note that the %date conversion word defaults to the ISO 8601 date format in the absence of a pattern parameter.

Here are some sample parameter values. They assume that the actual date is Friday 20th of October, 2006 and that the author has returned to working on this document just after lunch.

Conversion Pattern Result
%d 2006-10-20 14:06:49,812
%date 2006-10-20 14:06:49,812
%date 2006-10-20 14:06:49,812
%date 14:06:49.812
%date 20 oct. 2006;14:06:49.812

The second parameter specifies a timezone. For example, the pattern '%date{HH:mm:ss.SSS, Australia/Perth}' would print the time in the time zone of Perth, Australia, the most isolated city on Earth. Note that in the absence of the timezone parameter, the default timezone of the host Java platform is used. If the specified timezone identifier is unknown or misspelled, the GMT timezone is assumed as dictated by the TimeZone.getTimeZone(String) method specification.

Since 1.3.6/1.4.6 The third parameter specifies the locale. For example, writing '%date{HH:mm:ss.SSS, Australia/Perth, en-AU}' would print the date in the time zone of Perth, Australia, using the english australian locale. If the locale parameter is absent, then the system's default locale is used.

If an option includes special characters such as a braces, spaces or commas, you can enclose it between single or double quotes.

COMMON ERROR Given that the comma ',' character is interpreted as the parameter separator, the pattern HH:mm:ss,SSS will be interpreted as the pattern HM:mm:ss and the timezone SSS. If you wish to include a comma in your date pattern, then simply enclose the pattern between single or double quotes. For example, %date{"HH:mm:ss,SSS"} or %date{'HH:mm:ss,SSS'}.

1.9.5. ex{depth}

ex{depth} or exception{depth} or throwable{depth} or ex{depth, evaluator-1, ..., evaluator-n} or exception{depth, evaluator-1, ..., evaluator-n} or throwable{depth, evaluator-1, ..., evaluator-n}

Outputs the stack trace of the exception associated with the logging event, if any. By default the full stack trace will be output.

The throwable conversion word can be followed by one of the following options:

  • short: prints the first line of the stack trace
  • full: prints the full stack trace
  • Any integer: prints the given number of lines of the stack trace

Here are some examples:

  • %ex
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
  at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
  at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)
  • %ex{short}
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
  • %ex{full}
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
  at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
  at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)
  • %ex{2}
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
  at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)

This conversion word can also use evaluators to test logging events against a given criterion before creating the output. For example, using %ex{full, EX_DISPLAY_EVAL} will display the full stack trace of the exception only if the evaluator called EX_DISPLAY_EVAL returns a negative answer. Evaluators are described further down in this document.

If you do not specify %throwable or another throwable-related conversion word in the conversion pattern, PatternLayout will automatically add it as the last conversion word, on account of the importance of stack trace information. The $nopex conversion word can be substituted for %throwable, if you do not wish stack trace information to be displayed. See also the %nopex conversion word.

1.9.6. micros

micros or ms

Since 1.3 Outputs the microseconds of the timestamp included in the event.

For performance reasons, the microseconds have to be specified separately and in addition to %date.

1.9.7. F

F or file

Outputs the file name of the Java source file where the logging request was issued.

Generating the file information is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

1.9.8. caller{depth}

caller{depth} or caller{depthStart..depthEnd} or caller{depth, evaluator-1, ... evaluator-n} or caller{depthStart..depthEnd, evaluator-1, ... evaluator-n}

Outputs location information of the caller which generated the logging event.

The location information depends on the JVM implementation but usually consists of the fully qualified name of the calling method followed by the caller's source, the file name and line number between parentheses.

A integer can be added to the caller conversion specifier's options to configure the depth of the information to be displayed.

For example, %caller{2} would display the following excerpt:

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)

And %caller{3} would display this other excerpt:

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)

A range specifier can be added to the caller conversion specifier's options to configure the depth range of the information to be displayed.

For example, %caller{1..2} would display the following excerpt:

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

This conversion word can also use evaluators to test logging events against a given criterion before computing caller data. For example, using %caller{3, CALLER_DISPLAY_EVAL} will display three lines of stacktrace, only if the evaluator called CALLER_DISPLAY_EVAL returns a positive answer.

Evaluators are described below.

1.9.9. kvp{NONE,SINGLE,DOUBLE}

Outputs the key value pairs contained in the logging event. By default, the value part will be surrounded by double quotes. You can override the default by specifying NONE or SINGLE, for no quote character or the single quote character ' respectively.

The value key pairs {k1, v1} and {k2, v2} contained in the event will be output as follows:

option result
NONE v1=k1 v2=k2
DOUBLE v1="k1" v2="k2"
SINGLE v1='k1' v1='k1'
default same as if DOUBLE were specified

1.9.10. L

L or line

Outputs the line number from where the logging request was issued.

Generating the line number information is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

1.9.11. marker

Outputs the marker associated with the logger request.

In case the marker contains children markers, the converter displays the parent as well as childrens' names according to the format shown below.

parentName [ child1, child2 ]

1.9.12. mdc{key:-defaultVal}

mdc{key:-defaultVal} or X{key:-defaultVal}

Outputs the MDC (mapped diagnostic context) associated with the thread that generated the logging event.

If the mdc conversion word is followed by a key between braces, as in %mdc{userid}, then the MDC value corresponding to the key 'userid' will be output. If the value is null, then the default value specified after the :- operator is output. If no default value is specified than the empty string is output.

If no key is given, then the entire content of the MDC will be output in the format "key1=val1, key2=val2".

1.9.13. m

m or msg or message

Outputs the application-supplied message associated with the logging event.

1.9.14. M

M or method

Outputs the method name where the logging request was issued.

Generating the method name is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

1.9.15. n

Outputs the platform dependent line separator character or characters.

This conversion word offers practically the same performance as using non-portable line separator strings such as "\n", or "\r\n". Thus, it is the preferred way of specifying a line separator.

1.9.16. nopex

nopex or nopexception

Although it pretends to handle stack trace data, this conversion word does not output any data, thus, effectively ignoring exceptions.

The %nopex conversion word allows the user to override PatternLayout's internal safety mechanism which silently adds the %xThrowable conversion keyword in the absence of another conversion word handling exceptions.

1.9.17. p

p or le or level

Outputs the level of the logging event.

1.9.18. prefix(p)

For all the child converters contained in pattern 'p', prefixes the output of each converter with the name of the converter. In environments where log contents need to be analysed, it is often useful to prefix the contents of a pattern with a prefix.

For example, you may wish to use the following pattern to facilitate parsing of log files:

%d thread=%thread level=%level logger=%logger user=%X{user} %message

The %prefix composite converter can take care of the prefixing for you:

%d %prefix(%thread %level %logger %X{user}) %message

The two previous patterns will generate equivalent output. The usefulness of the %prefix converter increases with the number of child converters contained in the pattern 'p'.

1.9.19. property{key}

Outputs the value associated with a property named key. The relevant docs on how to define ion entitled define variables and variable scopes. If key is not a property of the logger context, then key will be looked up in the System properties.

There is no default value for key. If it is omitted, the returned value will be "Property_HAS_NO_KEY", expliciting the error condition.

1.9.20. r

r or relative

Outputs the number of milliseconds elapsed since the start of the application until the creation of the logging event.

1.9.21. rEx{depth}

rEx{depth} or rootException{depth} or rEx{depth, evaluator-1, ..., evaluator-n} or rootException{depth, evaluator-1, ..., evaluator-n}

Outputs the stack trace of the exception associated with the logging event, if any. The root cause will be output first instead of the standard "root cause last". Here is a sample output (edited for space):

java.lang.NullPointerException
  at com.xyz.Wombat(Wombat.;java:57) ~[wombat-1.3.jar:1.3]
  at com.xyz.Wombat(Wombat.;java:76) ~[wombat-1.3.jar:1.3]
Wrapped by: org.springframework.;BeanCreationException: Error creating bean with name 'wombat':
  at org.springframework.;AbstractBeanFactory.;getBean(AbstractBeanFactory.;java:248) [spring-2.0.jar:2.0]
  at org.springframework.;AbstractBeanFactory.;getBean(AbstractBeanFactory.;java:170) [spring-2.0.jar:2.0]
  at org.apache.catalina.;StandardContext.;listenerStart(StandardContext.;java:3934) [tomcat-6.0.26.jar:6.0.26]

The %rootException converter admits the same optional parameters as the %xException converter described above, including depth and evaluators. It outputs also packaging information. In short, %rootException is very similar to %xException, only the order of exception output is reversed.

1.9.22. replace(p){r, t}

Replaces occurrences of 'r', a regex, with its replacement 't' in the string produces by the sub-pattern 'p'. For example, "%replace(%msg){'\s', ''}" will remove all spaces contained in the event message.

The pattern 'p' can be arbitrarily complex and in particular can contain multiple conversion keywords. For instance, "%replace(%logger %msg){'.', '/'}" will replace all dots in the logger or the message of the event with a forward slash.

1.9.23. t

t or thread

Outputs the name of the thread that generated the logging event.

1.9.24. xEx{depth}

xEx{depth} or xException{depth} or xThrowable{depth} or xEx{depth, evaluator-1, ..., evaluator-n} or xException{depth, evaluator-1, ..., evaluator-n} or xThrowable{depth, evaluator-1, ..., evaluator-n}

Same as the %throwable conversion word above with the addition of class packaging information.

At the end of each stack frame of the exception, a string consisting of the jar file containing the relevant class followed by the "Implementation-Version" as found in that jar"s manifest will be added. This innovative technique was originally suggested by James Strachan. If the information is uncertain, then the class packaging data will be preceded by a tilde, i.e. the '~' character.

Here is an example:

java.lang.NullPointerException
  at com.xyz.Wombat(Wombat.;java:57) ~[wombat-1.3.jar:1.3]
  at  com.xyz.Wombat(Wombat.;java:76) ~[wombat-1.3.jar:1.3]
  at sun.reflect.NativeMethodAccessorImpl.;invoke0(Native Method) ~[na:1.5.0_06]
  at sun.reflect.NativeMethodAccessorImpl.;invoke(NativeMethodAccessorImpl.;java:39) ~[na:1.5.0_06]
  at sun.reflect.DelegatingMethodAccessorImpl.;invoke(DelegatingMethodAccessorImpl.;java:25) ~[na:1.5.0_06]
  at java.lang.reflect.;Method.invoke(Method.;java:585) ~[na:1.5.0_06]
  at org.junit.internal.;runners.TestMethod.;invoke(TestMethod.;java:59) [junit-4.4.jar:na]
  at org.junit.internal.;runners.MethodRoadie.;runTestMethod(MethodRoadie.;java:98) [junit-4.4.jar:na]
  ...etc 

Logback goes to great lengths to ensure that the class packaging information it displays is correct, even in arbitrarily complex class loader hierarchies. However, when it is unable to guarantee the absolute correctness of the information, then it will prefix the data with a tilde, i.e. the '~' character. Thus, it is theoretically possible for the printed class packaging information to differ from the real class packaging information. So, in the above example, given that packaging data for the Wombat class is preceded by a tilde, it is possible that the correct packaging data is in reality [wombat.jar:1.7].

Please note that given its potential cost, computation of packaging data is disabled by default. When computation of packaging data is enabled, PatternLayout will automatically assume the %xThrowable suffix instead of %throwable suffix at the end of the pattern string.

1.10. 参考资料

[1] Spring Boot Logging 官方文档
[2] Logback 官方文档

posted @ 2024-07-12 16:53  Jason207010  阅读(778)  评论(0)    收藏  举报