什么是logback
logback 继承自 log4j,它建立在有十年工业经验的日志系统之上。它比其它所有的日志系统更快并且更小,包含了许多独特并且有用的特性。
logback.xml
首先直接上配置,我在项目过程中发现一些同时遇到需要logback文件的时候就去其他项目copy一个,改吧改吧名字就直接完事。完全不了解其中标签的含义以及需要单独将日志打入一个文件怎么使用都不清楚,如果你需要一个logback可以把底下的copy走,但是我建议看看后续的标签含义。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 每隔20S扫描1次配置文件,如果配置文件被修改自动加载 -->
<configuration scan="true" scanPeriod="20 seconds"><!-- Windows操作系统 --><if condition='property("os.name").contains("Windows")'><then><property name="LOG_FILE_ROOT" value="D://opt/applog/logs"/><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></then></if><!-- MAC操作系统 --><if condition='property("os.name").toUpperCase().contains("MAC")'><then><property name="LOG_FILE_ROOT" value=".log/logs" /><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></then></if><!-- Linux操作系统 --><if condition='property("os.name").contains("Linux")'><then><property name="LOG_FILE_ROOT" value="/opt/applog/-logs"/><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></then></if><springProfile name="dev"><appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-debug.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-debug-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>7</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></springProfile><!-- 时间滚动输出 level为 INFO 日志 --><appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-info.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-info-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>20</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender><!-- 时间滚动输出 level为 WARN 日志 --><appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-warn.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-warn-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>7</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender><!-- 时间滚动输出 level为 ERROR 日志 --><appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-error.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-error-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>30</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender><!-- root Logger 分环境进行配置,本地环境需要用的DEBUG --><springProfile name="dev"><root level="DEBUG"><appender-ref ref="STDOUT"/><appender-ref ref="DEBUG"/><appender-ref ref="INFO"/><appender-ref ref="WARN"/><appender-ref ref="ERROR"/></root></springProfile><springProfile name="pro"><root level="INFO"><appender-ref ref="STDOUT"/><appender-ref ref="INFO"/><appender-ref ref="WARN"/><appender-ref ref="ERROR"/></root></springProfile></configuration>
<root>标签
在 Logback 日志框架中,<root level> 标签用于定义根日志级别。根日志级别是指所有日志记录器的默认级别,如果没有为特定的日志记录器指定级别,则会使用根日志级别。
根日志级别通过<root> 元素来表示,其语法如下:
<root level="级别"><!-- appender 配置 -->
</root>
在这里,level 属性用于指定根日志级别。根日志级别可以是以下之一:TRACE、DEBUG、INFO、WARN、ERROR 或 OFF。级别由低到高,TRACE 是最详细的级别,而 OFF 表示禁用日志记录。
当一个日志事件发送到 Logback 时,它将首先检查根日志级别。如果事件的级别高于或等于根日志级别,那么该事件将被记录下来。如果事件的级别低于根日志级别,那么它将被忽略。
因此,通过设置 <root level> 标签,您可以为整个应用程序指定默认的日志记录级别。您还可以在其他地方针对特定的日志记录器设置级别,以覆盖根日志级别的默认设置。
<appender-ref>标签
<appender-ref> 标签用于将日志事件附加器(appender)与特定的日志记录器相关联。在 Logback 配置文件中,可以使用 <appender-ref> 标签将一个或多个附加器与日志记录器关联起来。
<appender-ref> 元素的语法如下:
<appender-ref ref="附加器名称" />
在这里,ref 属性用于指定要关联的附加器的名称。附加器名称应与配置文件中定义的附加器的名称匹配。
通过使用 <appender-ref> 标签,您可以将一个或多个附加器(例如文件附加器、控制台附加器等)与日志记录器相关联。这意味着当日志事件到达该日志记录器时,它将被传递给与之关联的附加器进行处理。这样可以根据需要将日志事件输出到不同的目标,例如文件、控制台、远程服务器等。
以下是一个示例,展示如何使用 <appender-ref> 标签将附加器与日志记录器关联:
<configuration><!-- 定义附加器 --><appender name="ConsoleAppender" class="ch.qos.logback.core.ConsoleAppender"><!-- 附加器配置 --></appender><!-- 定义日志记录器 --><logger name="com.example.MyClass" level="DEBUG"><!-- 关联附加器 --><appender-ref ref="ConsoleAppender" /></logger>
</configuration>
在上面的示例中,ConsoleAppender 是一个控制台附加器,它被定义在 <appender> 元素中。然后,通过使用 <appender-ref> 标签,将该附加器与名为 com.example.MyClass 的日志记录器关联起来。这意味着 com.example.MyClass 日志记录器的日志事件将被发送到 ConsoleAppender 进行处理。
通过适当配置 <appender-ref> 标签,您可以将多个附加器关联到同一个日志记录器,或者将同一个附加器关联到多个日志记录器,以满足您的日志输出需求。
简单的说:上述的示例就可以为我们输出日志到自定义的文件夹中。
输出日志到自定义文件
在开发的过程中,难免会要在info日志和error日志中排查问题,那么一个应用部署在测试环境或者uat环境的时候,会产生大量的日志在日志文件中,如果我们需要查询相关的日志记录通常linux会使用grep来进行搜索来满足需求。如果你的功能会被大量调用,并且需要详细记录前后流转的参数;又或者在测试阶段需要把用户所有的权限和角色在日志文件中打印观察。此时你可能需要把你这部分的功能开发日志打印到一个单独的日志文件中。
<!-- root Logger 分环境进行配置,本地环境需要用的DEBUG --><springProfile name="dev"><root level="DEBUG"><appender-ref ref="STDOUT"/><appender-ref ref="DEBUG"/><appender-ref ref="INFO"/><appender-ref ref="WARN"/><appender-ref ref="ERROR"/></root></springProfile><springProfile name="pro"><root level="INFO"><appender-ref ref="STDOUT"/><appender-ref ref="INFO"/><appender-ref ref="WARN"/><appender-ref ref="ERROR"/></root></springProfile>
根据springProfile标签,我们可以分环境配置,dev环境的root级别改为DEBUG级别,pro环境使用INFO级别。所以如果你需要观察用户权限问题打的日志可以使用log.debug()来记录在debug的日志文件中。
那么如果想要新建一个日志文件(非info、error、warn、debug)的日志,例如支付相关的日志都放入paylog文件中。不管是DEBUG INFO WARN ERROR都直接放一起,那么我们需要自定义一个附加器appender和一个日志记录器logger。
附加器定义如下:
<appender name="pay" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/qhyu.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/qhyu-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>20</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender>
在 Logback 的过滤器配置中,<onMatch>
和 <onMismatch>
标签用于指定过滤器匹配和不匹配时的行为。它们需要配套使用。
-
<onMatch>
:该标签定义了当日志事件与过滤器匹配时的操作。它有以下参数:-
ACCEPT
:表示接受(通过)匹配的日志事件,将其传递给后续的附加器或日志记录器进行处理。 -
NEUTRAL
:表示中立,不对匹配的日志事件进行特殊处理,继续按照日志处理流程进行传递。 -
DENY
:表示拒绝(拦截)匹配的日志事件,不将其传递给后续的附加器或日志记录器。
-
-
<onMismatch>
:该标签定义了当日志事件与过滤器不匹配时的操作。它有以下参数: -
ACCEPT
:表示接受(通过)不匹配的日志事件,将其传递给后续的附加器或日志记录器进行处理。 -
NEUTRAL
:表示中立,不对不匹配的日志事件进行特殊处理,继续按照日志处理流程进行传递。 -
DENY
:表示拒绝(拦截)不匹配的日志事件,不将其传递给后续的附加器或日志记录器。
通常情况下,应该将 <onMatch>
和 <onMismatch>
标签配对使用,以明确指定匹配和不匹配时的操作。例如,可以将匹配时的操作设置为 ACCEPT
,表示允许通过匹配的日志事件,而将不匹配时的操作设置为 DENY
,表示拒绝不匹配的日志事件。
以下是一个示例配置:
<filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch>
</filter>
在上述示例中,过滤器的配置指定了当日志事件的级别为 INFO
时,执行匹配操作为 ACCEPT
,而当日志事件的级别不是 INFO
时,执行不匹配操作为 DENY
。这意味着只有级别为 INFO
的日志事件才会通过过滤器,其他级别的日志事件将被拒绝。
因为我想把所有的日志都打到一个文件中,不区分info error还是warn所以我将四个过滤器放在同一个附加器中,如果你想为这个文件拆分的话可以配合日志记录器一起使用,也就是接下来要说的内容。
日志记录器如下:
<logger name="PAYLOGGER" level="DEBUG" additivity="false"><appender-ref ref="pay"/></logger>
如果使用的是自定义name,那么自己使用的时候需要定义Logger logger = LoggerFactory.getLogger(“PAYLOGGER”);这样可以在任意的类中直接使用。
<logger>
标签用于配置特定包或类的日志记录器。它允许您为特定的包或类设置不同于根日志记录器的日志级别、附加器和其他属性。
<logger>
标签有以下常用的属性:
-
name
:指定要配置的包或类的名称。可以使用包名或类的全限定名。例如,com.swcares.eupsi.airplaneSale
。 -
level
:设置该日志记录器的日志级别。可以是TRACE
、DEBUG
、INFO
、WARN
或ERROR
等级别。例如,INFO
。 -
additivity
:指定是否继承父级日志记录器的附加器。如果设置为true
,则该日志记录器将继承父级日志记录器的附加器;如果设置为false
,则该日志记录器将仅使用自己配置的附加器。默认值为true
。
除了上述常用属性外,<logger>
标签还可以配置其他属性,如 <appender-ref>
标签引用的附加器、<filter>
标签设置的过滤器等。这些属性可以根据您的需求进行配置和调整。
以下是一个示例 <logger>
标签的配置:
<logger name="com.qhyu.pay.modules.test" level="INFO" additivity="false"><appender-ref ref="SOME_APPENDER"/>
</logger>
在上述示例中,<logger>
标签配置了名为 com.qhyu.pay.modules.test
的日志记录器,将日志级别设置为 INFO
,并指定了一个名为 SOME_APPENDER
的附加器。此外,additivity
属性被设置为 false
,表示该日志记录器不会继承父级日志记录器的附加器。
这种配置就是可以在这个类中直接使用,不需要定义Logger了。
通过使用 <logger>
标签,您可以对特定的包或类进行精细化的日志配置,以满足不同部分的日志记录需求。
完整xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 每隔20S扫描1次配置文件,如果配置文件被修改自动加载 -->
<configuration scan="true" scanPeriod="20 seconds"><!-- Windows操作系统 --><if condition='property("os.name").contains("Windows")'><then><property name="LOG_FILE_ROOT" value="D://opt/applog/logs"/><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></then></if><!-- MAC操作系统 --><if condition='property("os.name").toUpperCase().contains("MAC")'><then><property name="LOG_FILE_ROOT" value=".log/logs"/><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></then></if><!-- Linux操作系统 --><if condition='property("os.name").contains("Linux")'><then><property name="LOG_FILE_ROOT" value="/opt/applog/-logs"/><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></then></if><springProfile name="dev"><appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-debug.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-debug-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>7</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender></springProfile><!-- 时间滚动输出 level为 INFO 日志 --><appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-info.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-info-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>20</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender><!-- 时间滚动输出 level为 INFO 日志 --><appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-warn.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-warn-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>7</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender><!-- 时间滚动输出 level为 ERROR 日志 --><appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/web-error.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/web-error-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>30</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender><!-- 时间滚动输出 所有级别的日志到预计的文件中 --><appender name="pay" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE_ROOT}/pay.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch></filter><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_ROOT}/pay-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>100MB</maxFileSize><maxHistory>20</maxHistory><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS}[%level][%thread][%logger.java:%line] - %msg%n</pattern></encoder></appender><!--<logger name="com.qhyu.pay.modules.test" level="DEBUG" additivity="false"><appender-ref ref="pay"/></logger>--><logger name="PAYLOGGER" level="DEBUG" additivity="false"><appender-ref ref="pay"/></logger><!-- root Logger 分环境进行配置,本地环境需要用的DEBUG --><springProfile name="dev"><root level="DEBUG"><appender-ref ref="STDOUT"/><appender-ref ref="DEBUG"/><appender-ref ref="INFO"/><appender-ref ref="WARN"/><appender-ref ref="ERROR"/></root></springProfile><springProfile name="pro"><root level="INFO"><appender-ref ref="STDOUT"/><appender-ref ref="INFO"/><appender-ref ref="WARN"/><appender-ref ref="ERROR"/></root></springProfile>
</configuration>