springboot本身内置了日志功能,然而想要输入想要的日志,并且输出到磁盘。
依赖
springboot的pom文件会引一个parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
点进去这个parent,会有这个dependency
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
再点进去
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.0.0.RELEASE</version>
<scope>compile</scope>
</dependency>
再点,这些都是原有的日志包,所以,不必再引依赖了,直接用就ok了。
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.10.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.25</version>
<scope>compile</scope>
</dependency>
配置
1、官方推荐使用的xml名字的格式是:logback-spring.xml而不是logback.xml,因为带spring后缀的可以使用<springProfile>这个标签。
通过Profile可以针对不同运行时Profile使用不同的日志配置。
2、在resource下创建logback-spring.xml文件。
(1)Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
(2)Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
(3)Log4j2: log4j2-spring.xml, log4j2.xml
(4)JDK(Java Util Logging):logging.properties
如果你不想使用上面推荐的名字,可以在application.yml中通过logging.config属性来指定自定义的名字
3、configuration根节点
(1)scan,默认值为true,当配置文件发生改变时,是否重新加载
(2)scanPeriod,设置监测配置文件是否修改的时间间隔,当scan为true时,此属性生效,默认时间单位是ms,默认的时间间隔是1分钟。
(3)debug,默认值为false,是否打印logback内部日志信息,用于实时查看logback运行状态。
4、子节点root
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。
level用来设置打印级别,大小写无关,trace->debug->info->warn->error->all->off,默认debug
可以包含零个或多个元素,标识这个appender将会添加到这个logger
<root level="debug">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
5、子节点<contextName>
每个logger都关联到logger上下文,默认上下文名称为“default",但可以使用设置成其他名字,用于区分不同的应用程序的记录。一旦设置,不能修改,保以通过%contextName来打印日志上下文名称,一般来说我们不用这个属性,可有可无。
6、子节点<property>
用来定义变量值的标签,有两个属性,name和value,其中name的值是变量的名称,value的值是变量定义的值,通过定义的值会被插入到logger上下文件中,定义变量后,可以使用${}来使用变量。
<property name="logback.logdir" value="/Users/inke/dev/log/tomcat"/>
<property name="logback.appname" value="app"/>
7、子节点<appender>
appender用来格式化日志输出节点,有两个属性name和class,class用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。
(1)%d{HH: mm:ss.SSS} 日志输出时间
(2)%thread 输出日志的进程名字,这个Web应用以及异步任务处理中很有用。
(3)%-5level 日志级别,并且使用5个字符左对齐
(4)%logger{36} 日志输出者的名字
(5)%msg 日志消息
(6)%n 平台的换行符
(7)RollingFileAppender
用于切分文件日志
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,
所以我们使用下面的策略,可以避免输出 Error 的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤 Error-->
<level>ERROR</level>
<!--匹配到就禁止-->
<onMatch>DENY</onMatch>
<!--没有匹配到就允许-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${logback.logdir}/info.${logback.appname}.log</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${logback.logdir}/info.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--只保留最近90天的日志-->
<maxHistory>90</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<!--<totalSizeCap>1GB</totalSizeCap>-->
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
</encoder>
</appender>
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>Error</level>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${logback.logdir}/error.${logback.appname}.log</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${logback.logdir}/error.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--只保留最近90天的日志-->
<maxHistory>90</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<!--<totalSizeCap>1GB</totalSizeCap>-->
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
</encoder>
</appender>
8、子节点<logger>
用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>
(1)name:用来指定受此logger约束的某一个包或者具体的某一个类。
(2)level:用来设置打印级别,大小写无关。还有一个特殊的值inherited或同义词null,代表强制执行上级的级别,如果未设置此属性,那么当前logger将会继承上级的级别。
(3)additivity:是否向上级logger传递打印信息,默认true。
例子:
<logger name="com.dudu.controller" />
没有设置addtivity,默认为true,将此logger的打印信息向上级传递,没有appender,此logger本身不打印任何信息,所以会将日志信息传递给上级,一般为root,再交给root配置好的appender处理。
(4)多环境的日志输出
<configuration>
...
<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
<logger name="com.example.demo.controller" level="DEBUG" additivity="false">
<appender-ref ref="consoleLog"/>
</logger>
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
<logger name="com.example.demo.controller" level="INFO" additivity="false">
<appender-ref ref="consoleLog"/>
</logger>
</springProfile>
</configuration>
完整示例
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" debug="false">
<property name="application.name" value="module-organizat-configure" />
<property name="log.path" value="/home/logs" />
<!--输出到控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] %c - %m%n</pattern>
</encoder>
</appender>
<!-- info级别日志控制 -->
<appender name="info_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 文件路径 -->
<file>${log.path}/${application.name}/info.log</file>
<!-- 是否追加 默认为true -->
<append>true</append>
<!-- 滚动策略 日期+大小 策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${application.name}/%d{yyyy-MM-dd}/info/info-%i.zip</fileNamePattern>
<!-- 单个日志大小 -->
<maxFileSize>50MB</maxFileSize>
<!-- 日志保存周期 -->
<maxHistory>7</maxHistory>
<!-- 总大小 -->
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<!-- 格式化 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] %c - %m%n</pattern>
</encoder>
<!-- 级别过滤 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- warn级别日志控制 -->
<appender name="warn_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 文件路径 -->
<file>${log.path}/${application.name}/warn.log</file>
<!-- 是否追加 默认为true -->
<append>true</append>
<!-- 滚动策略 日期+大小 策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${application.name}/%d{yyyy-MM-dd}/warn/warn-%i.zip</fileNamePattern>
<!-- 单个日志大小 -->
<maxFileSize>50MB</maxFileSize>
<!-- 日志保存周期 -->
<maxHistory>15</maxHistory>
<!-- 总大小 -->
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<!-- 格式化 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] %c - %m%n</pattern>
</encoder>
<!-- 级别过滤 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- error级别日志控制 -->
<appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 文件路径 -->
<file>${log.path}/${application.name}/error.log</file>
<!-- 是否追加 默认为true -->
<append>true</append>
<!-- 滚动策略 日期+大小 策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${application.name}/%d{yyyy-MM-dd}/error/error-%i.zip</fileNamePattern>
<!-- 单个日志大小 -->
<maxFileSize>50MB</maxFileSize>
<!-- 日志保存周期 -->
<maxHistory>15</maxHistory>
<!-- 总大小 -->
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<!-- 格式化 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] %c - %m%n</pattern>
</encoder>
<!-- 级别过滤 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 特殊处理 -->
<logger name="org.xnio.nio" level="warn" />
<logger name="org.springframework" level="warn" />
<logger name="com.netflix.discovery" level="warn" />
<logger name="org.module.organizat.configure" level="info" />
<!-- 开发、默认环境 只输出到控制台 -->
<springProfile name="default,dev">
<root level="info">
<appender-ref ref="console" />
</root>
</springProfile>
<!-- 测试环境 输出info及以上日志 -->
<springProfile name="test">
<root level="info">
<appender-ref ref="info_file" />
<appender-ref ref="warn_file" />
<appender-ref ref="error_file" />
</root>
</springProfile>
<!-- 正式环境 输出warn及以上日志 -->
<springProfile name="prod">
<root level="warn">
<appender-ref ref="info_file" />
<appender-ref ref="warn_file" />
<appender-ref ref="error_file" />
</root>
</springProfile>
</configuration>