引入pom依赖,slf4j为日志门面,简单理解为一个日志接口,本身没有实现不会输出什么,常用的实现有logback、log4j等,这里也引入了它们的依赖
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <!-- 日志实现 logback 依赖 --> <!-- <dependency>--> <!-- <groupId>ch.qos.logback</groupId>--> <!-- <artifactId>logback-classic</artifactId>--> <!-- <version>1.1.8</version>--> <!-- </dependency>--> <!-- 日志实现 log4j 依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency>
logback.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 定义参数常量 --> <!-- 日志级别 TRACE<DEBUG<INFO<WARN<ERROR --> <!-- logger.trace("msg") logger.debug... --> <property name="log.level" value="INFO"/> <property name="log.maxHistory" value="60"/> <property name="log.filePath" value="logs"/> <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/> <!-- 控制台输出设置 --> <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${log.pattern}</pattern> </encoder> </appender> <!-- DEBUG级别文件记录 --> <appender name="debugAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 文件路径 --> <file>${log.filePath}/sys-debug.log</file> <!-- 循环策略:基于时间创建日志文件 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志文件名称 .gz表示压缩 --> <fileNamePattern>${log.filePath}/debug/sys-debug.%d{yyyy-MMdd}.log.gz</fileNamePattern> <!-- 日志文件最大保存历史 60天--> <maxHistory>${log.maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>${log.pattern}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 过滤的级别 --> <level>DEBUG</level> <!-- 匹配时的操作:接收(记录) --> <onMatch>ACCEPT</onMatch> <!-- 不匹配时的操作:拒绝(不记录) --> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- INFO --> <appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 文件路径 --> <file>${log.filePath}/sys-info.log</file> <!-- 循环策略:基于时间创建日志文件 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志文件名称 --> <fileNamePattern>${log.filePath}/info/sys-info.%d{yyyy-MM-dd}.log.gz</fileNamePattern> <!-- 日志文件最大保存历史 60天--> <maxHistory>${log.maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>${log.pattern}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 过滤的级别 --> <level>INFO</level> <!-- 匹配时的操作:接收(记录) --> <onMatch>ACCEPT</onMatch> <!-- 不匹配时的操作:拒绝(不记录) --> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- WARN --> <appender name="warnAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 文件路径 --> <file>${log.filePath}/sys-warn.log</file> <!-- 循环策略:基于时间创建日志文件 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志文件名格式 --> <fileNamePattern>${log.filePath}/warn/sys-error.%d{yyyy-MM-dd}.log.gz</fileNamePattern> <!-- 日志最大的历史 60天 --> <maxHistory>${log.maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>${log.pattern}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 过滤的级别 --> <level>WARN</level> <!-- 匹配时的操作:接收(记录) --> <onMatch>ACCEPT</onMatch> <!-- 不匹配时的操作:拒绝(不记录) --> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- ERRO --> <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 文件路径 --> <file>${log.filePath}/sys-error.log</file> <!-- 循环策略:基于时间创建日志文件 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志文件名格式 --> <fileNamePattern>${log.filePath}/error/sys-error.%d{yyyy-MM-dd}.log.gz</fileNamePattern> <!-- 日志最大的历史 60天 --> <maxHistory>${log.maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>${log.pattern}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 过滤的级别 --> <level>ERROR</level> <!-- 匹配时的操作:接收(记录) --> <onMatch>ACCEPT</onMatch> <!-- 不匹配时的操作:拒绝(不记录) --> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 项目包开头的日志对应形式 level表示日志接收级别,如果不设置则继承上级即root的级别 additivity="true" 表示将日志信息向上级传递,即传递给root,默认值就是true 不配置appender表示不打印日志,将日志交给上级处理 --> <logger name="top.lyylzt" level="${log.level}" additivity="true"> <appender-ref ref="debugAppender"/> </logger> <!-- Spring日志级别控制 --> <logger name="org.springframework" level="warn" additivity="true"/> <!-- <root> 是必选节点,用来指定最基础的日志输出级别,只有一个level属性 --> <root level="info"> <appender-ref ref="consoleAppender"/> </root> <root level="info"> <appender-ref ref="infoAppender"/> <appender-ref ref="warnAppender"/> <appender-ref ref="errorAppender"/> </root> <!-- MyBatis sql日志 --> <appender name="MyBatis" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.filePath}/sql_log/mybatis-sql.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>${log.filePath}/sql_log/mybatis-sql.%d{yyyy-MM-dd}.log</FileNamePattern> <maxHistory>${log.maxHistory}</maxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%thread|%d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%logger{36}|%m%n </pattern> </encoder> </appender> <!-- 捕捉sql-log开头的日志,默认info级别表示不打印sql日志,需要在mybatis配置文件中给打印的日志添加 sql-log. 前缀(注意这个点一定要加)--> <logger name="sql-log" level="INFO" additivity="true"> <appender-ref ref="MyBatis"/> </logger> </configuration>
如果是SpringBoot工程,则在 application.properties 中可以用配置修改logger的输出级别:
logging.level.top.lyylzt=debug logging.level.org.springframework=warn logging.level.sql-log=debug logging.level.root=info
log4j.properties配置:
# 全局日志配置 log4j.rootLogger=ERROR, stdout # 指定包下的日志输出级别 log4j.logger.xyz.lyuan=INFO log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] %l - %m %n
在代码中要使用slf4j的api,通过切换pom依赖项就可以切换实际的日志实现了
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class App { private static Logger logger = LoggerFactory.getLogger(App.class); public static void main(String[] args) { logger.trace("TRACE----"); logger.debug("debug----"); logger.info("info----"); logger.warn("warn----"); logger.error("error----"); new Thread(() -> { logger.trace("TRACE----"); logger.debug("debug----"); logger.info("info----"); logger.warn("warn----"); logger.error("error----"); }, "thread-name3423423432423423").start(); } }