最常用的slf4j+logback日志框架介绍

最常用的slf4j+logback日志框架介绍日志概念 日志 在计算机领域 日志文件 logfile 是一个记录了发生在运行中的操作系统或其他软件中的事件的文件 或者记录了在网络聊天软件的用户之间发送的消息 1 日志记录 Logging 是指保存日志的行为

大家好,我是讯享网,很高兴认识大家。

日志概念

日志:在计算机领域,日志文件(logfile)是一个记录了发生在运行中的操作系统或其他软件中的事件的文件,或者记录了在网络聊天软件的用户之间发送的消息1。

日志记录(Logging):是指保存日志的行为。最简单的做法是将日志写入单个存放日志的文件。

日志级别2:

  • FATAL — 表示需要立即被处理的系统级错误。当该错误发生时,表示服务已经出现了某种程度的不可用,系统管理员需要立即介入。这属于最严重的日志级别,因此该日志级别必须慎用,如果这种级别的日志经常出现,则该日志也失去了意义。通常情况下,一个进程的生命周期中应该只记录一次FATAL级别的日志,即该进程遇到无法恢复的错误而退出时。当然,如果某个系统的子系统遇到了不可恢复的错误,那该子系统的调用方也可以记入FATAL级别日志,以便通过日志报警提醒系统管理员修复;
  • ERROR — 该级别的错误也需要马上被处理,但是紧急程度要低于FATAL级别。当ERROR错误发生时,已经影响了用户的正常访问。从该意义上来说,实际上ERROR错误和FATAL错误对用户的影响是相当的。FATAL相当于服务已经挂了,而ERROR相当于好死不如赖活着,然而活着却无法提供正常的服务,只能不断地打印ERROR日志。特别需要注意的是,ERROR和FATAL都属于服务器自己的异常,是需要马上得到人工介入并处理的。而对于用户自己操作不当,如请求参数错误等等,是绝对不应该记为ERROR日志的;
  • WARN — 该日志表示系统可能出现问题,也可能没有,这种情况如网络的波动等。对于那些目前还不是错误,然而不及时处理也会变为错误的情况,也可以记为WARN日志,例如一个存储系统的磁盘使用量超过阀值,或者系统中某个用户的存储配额快用完等等。对于WARN级别的日志,虽然不需要系统管理员马上处理,也是需要及时查看并处理的。因此此种级别的日志也不应太多,能不打WARN级别的日志,就尽量不要打;
  • INFO — 该种日志记录系统的正常运行状态,例如某个子系统的初始化,某个请求的成功执行等等。通过查看INFO级别的日志,可以很快地对系统中出现的 WARN,ERROR,FATAL错误进行定位。INFO日志不宜过多,通常情况下,INFO级别的日志应该不大于TRACE日志的10%;
  • DEBUG or TRACE — 这两种日志具体的规范应该由项目组自己定义,该级别日志的主要作用是对系统每一步的运行状态进行精确的记录。通过该种日志,可以查看某一个操作每一步的执 行过程,可以准确定位是何种操作,何种参数,何种顺序导致了某种错误的发生。可以保证在不重现错误的情况下,也可以通过DEBUG(或TRACE)级别的日志对问题进行诊断。需要注意的是,DEBUG日志也需要规范日志格式,应该保证除了记录日志的开发人员自己外,其他的如运维,测试人员等也可以通过 DEBUG(或TRACE)日志来定位问题;

日志级别优先级:

ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF

日志作用

日志记录了系统行为的时间、地点、状态等相关信息,能够帮助我们了解并监控系统状态,在发生错误或者接近某种危险状态时能够及时提醒我们处理,同时在系统产生问题时,能够帮助我们快速的定位、诊断并解决问题。

Java中常用日志框架

在Java程序中常用日志框架可以分为两类:

  • 无具体实现的抽象门面框架,如:Commons Logging、SLF4J
  • 具体实现的框架,如:Log4j,Log4j 2,Logback,Jul

Java常用日志框架历史:

  • 1996年早期,欧洲安全电子市场项目组决定编写它自己的程序跟踪API(Tracing API)。经过不断的完善,这个API终于成为一个十分受欢迎的Java日志软件包,即Log4j。后来Log4j成为Apache基金会项目中的一员。
  • 期间Log4j近乎成了Java社区的日志标准。据说Apache基金会还曾经建议sun引入Log4j到java的标准库中,但Sun拒绝了。
  • 2002年Java1.4发布,Sun推出了自己的日志库JUL(Java Util Logging),其实现基本模仿了Log4j的实现。在JUL出来以前,log4j就已经成为一项成熟的技术,使得log4j在选择上占据了一定的优势。
  • 接着,Apache推出了Jakarta Commons Logging,JCL只是定义了一套日志接口(其内部也提供一个Simple Log的简单实现),支持运行时动态加载日志组件的实现,也就是说,在你应用代码里,只需调用Commons Logging的接口,底层实现可以是log4j,也可以是Java Util Logging。
  • 后来(2006年),Ceki Gülcü不适应Apache的工作方式,离开了Apache。然后先后创建了slf4j(日志门面接口,类似于Commons Logging)和Logback(Slf4j的实现)两个项目,并回瑞典创建了QOS公司,QOS官网上是这样描述Logback的:The Generic,Reliable Fast&Flexible Logging Framework(一个通用,可靠,快速且灵活的日志框架)。
  • 现今,Java日志领域被划分为两大阵营:Commons Logging阵营和SLF4J阵营。
    Commons Logging在Apache大树的笼罩下,有很大的用户基数。但有证据表明,形式正在发生变化。2013年底有人分析了GitHub上30000个项目,统计出了最流行的100个Libraries,可以看出slf4j的发展趋势更好:
  • Apache眼看有被Logback反超的势头,于2012-07重写了log4j 1.x,成立了新的项目Log4j 2。Log4j 2具有logback的所有特性。

Java常用日志框架之间的关系

  • Log4j2与Log4j1发生了很大的变化,log4j2不兼容log4j1。
  • Commons Logging和Slf4j是日志门面(门面模式是软件工程中常用的一种软件设计模式,也被称为正面模式、外观模式。它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用)。log4j和Logback则是具体的日志实现方案。可以简单的理解为接口与接口的实现,调用这只需要关注接口而无需关注具体的实现,做到解耦。
  • 比较常用的组合使用方式是Slf4j与Logback组合使用,Commons Logging与Log4j组合使用。
  • Logback必须配合Slf4j使用。由于Logback和Slf4j是同一个作者,其兼容性不言而喻。

日志门面框架

日志门面:是门面模式的一个典型的应用,门面模式,也称外观模式,请参照我的博文设计模式之外观模式,日志门面框架就使一套提供了日志相关功能的接口而无具体实现的框架,其调用具体的实现框架来进行日志记录。也就是说日志门面天然的兼容日志实现框架。典型的日志门面就是Commons Logging、SLF4J。

日志门面的优点:

日志门面是介于具体的日志框架与系统之间的桥梁,通过日志门面框架的应用实现了系统与具体实现日志框架的解耦。无论具体实现的日志框架如何变化,都不会影响系统日志的记录功能,更无须更改系统代码,符合“开放-闭合原则”。

Commons Logging

Apache Commons Logging是一个基于Java的日志记录实用程序,是用于日志记录和其他工具包的编程模型。它通过其他一些工具提供API,日志实现和包装器实现。

SLF4J

Java简易日志门面(Simple Logging Facade for Java,缩写SLF4J),是一套包装Logging 框架的界面程式,以外观模式实现。可以在软件部署的时候决定要使用的 Logging 框架,目前主要支援的有Java Logging API、Log4j及logback等框架。以MIT 授权方式发布。SLF4J 的作者就是 Log4j和Logback 的作者 Ceki Gülcü.

详细请参考我的博文日志框架门面之SLF4J

Commons Logging和SLF4J实现机制

Commons logging实现机制:

Commons logging是通过动态查找机制,在程序运行时,使用自己的ClassLoader寻找和载入本地具体的实现。详细策略可以查看commons-logging-*.jar包中的org.apache.commons.logging.impl.LogFactoryImpl.java文件。由于OSGi不同的插件使用独立的ClassLoader,OSGI的这种机制保证了插件互相独立, 其机制限制了commons logging在OSGi中的正常使用。

Slf4j实现机制:

Slf4j在编译期间,静态绑定本地的LOG库,因此可以在OSGi中正常使用。它是通过查找类路径下org.slf4j.impl.StaticLoggerBinder,然后绑定工作都在这类里面进。

日志实现框架

Jul

Jul:Java Util Logging,自Java1.4以来的官方日志实现。

Log4j

Apache Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的,现在则是Apache软件基金会的一个项目。

Log4j的使用请参考我的博文日志框架之Log4j

Log4j2

Apache Log4j 2是apache开发的一款Log4j的升级产品,并且不兼容Log4j。

Logback

Java 日志框架的选择

  1. 成本考虑:Logback文档免费。Logback的所有文档是全面免费提供的,不象Log4J那样只提供部分免费文档而需要用户去购买付费文档。
  2. 资源开销:Commons Logging相比较与SLF4J开销更高.
  3. 性能:Logback相比Log4j、Log4j2拥有更好的性能。Logback声称:某些关键操作,比如判定是否记录一条日志语句的操作,其性能得到了显著的提高。这个操作在Logback中需要3纳秒,而在Log4J中则需要30纳秒。LogBack创建记录器(logger)的速度也更快:13毫秒,而在Log4J中需要23毫秒。更重要的是,它获取已存在的记录器只需94纳秒,而Log4J需要2234纳秒,时间减少到了1/23。跟JUL相比的性能提高也是显著的。

------------------------------------------------------------------------------------------------------------

Java主流日志工具库 - mingyue1818 - 博客园,下面是这个博客的摘录:

Spring框架内部使用的日志框架是 JCL (Jakarta Commons Logging)

Mybatis框架中使用的是 Log4j

Hibernate框架中使用的是 jboss-logging

Springboot底层使用的是 SLF4j + Logback

因为springboot底层使用的是 SLF4j + Logback,而且平时开发中使用频率最高的也是此组合,所以选择使用此组合进行日志框架的整合。


讯享网

摘自博客:https://www.jb51.net/article/197194.htm

Spring boot 各种日志jar包冲突解决办法(NoClassDefError):

项目中使用logback作为具体的实现,防止其他具体日志框架绑定到slf4j,所以

第一步 排除其他日志框架的具体实现依赖已经其他日志框架到sll4j的关联;

第二步:有些依赖方不使用slf4j门面,直接使用具体的日志实现,需要增加具体实现日志包到slf4j桥接

JAVA日志框架适配/冲突解决方案 - 简书(解决日志冲突问题办法,重点理解此博客)

Java日志框架 - 紫焱luis - 博客园

slf4j兼容非slf4j日志组件

在介绍解决方案前,先提一个概念——桥接
什么是桥接呢
假如你正在开发应用程序所调用的组件当中已经使用了common-logging,这时你需要 jcl-over-slf4j.jar把日志信息输出重定向到 slf4j-api,slf4j-api再去调用slf4j实际依赖的日志组件。这个过程称为桥接。

从图中应该可以看出,无论你的老项目中使用的是common-logging或是直接使用log4j、java.util.logging,都可以使用对应的桥接jar包来解决兼容问题。

slf4j兼容common-logging

<dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.12</version> </dependency>

讯享网

slf4j兼容log4j

讯享网<dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.12</version> </dependency>

slf4j兼容java.util.logging

<dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.12</version> </dependency>

spring 集成 slf4j

讯享网<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>org.logback-extensions</groupId> <artifactId>logback-ext-spring</artifactId> <version>0.1.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.12</version> </dependency>

common-logging绑定日志组件

<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>

配置

日志配置文件大同小异,需要注意的是:logback.xml和log4j.xml都需要放在classpath路径下。

完整的logback.xml参考示例

在下面的配置文件中,我为自己的项目代码(根目录:org.zp.notes.spring)设置了五种等级:
TRACE、DEBUG、INFO、WARN、ERROR,优先级依次从低到高。
因为关注spring框架本身的一些信息,我增加了专门打印spring WARN及以上等级的日志。

讯享网<?xml version="1.0" encoding="UTF-8" ?> <!-- logback中一共有5种有效级别,分别是TRACE、DEBUG、INFO、WARN、ERROR,优先级依次从低到高 --> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <property name="DIR_NAME" value="spring-helloworld"/> <!-- 将记录日志打印到控制台 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <!-- RollingFileAppender begin --> <appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 根据时间来制定滚动策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${user.dir}/logs/${DIR_NAME}/all.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <!-- 根据文件大小来制定滚动策略 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>30MB</maxFileSize> </triggeringPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 根据时间来制定滚动策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${user.dir}/logs/${DIR_NAME}/error.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <!-- 根据文件大小来制定滚动策略 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10MB</maxFileSize> </triggeringPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 根据时间来制定滚动策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${user.dir}/logs/${DIR_NAME}/warn.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <!-- 根据文件大小来制定滚动策略 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10MB</maxFileSize> </triggeringPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 根据时间来制定滚动策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${user.dir}/logs/${DIR_NAME}/info.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <!-- 根据文件大小来制定滚动策略 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10MB</maxFileSize> </triggeringPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <appendername="DEBUG"class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 根据时间来制定滚动策略 --> <rollingPolicyclass="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${user.dir}/logs/${DIR_NAME}/debug.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <!-- 根据文件大小来制定滚动策略 --> <triggeringPolicyclass="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10MB</maxFileSize> </triggeringPolicy> <filterclass="ch.qos.logback.classic.filter.LevelFilter"> <level>DEBUG</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <appendername="TRACE"class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 根据时间来制定滚动策略 --> <rollingPolicyclass="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${user.dir}/logs/${DIR_NAME}/trace.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <!-- 根据文件大小来制定滚动策略 --> <triggeringPolicyclass="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10MB</maxFileSize> </triggeringPolicy> <filterclass="ch.qos.logback.classic.filter.LevelFilter"> <level>TRACE</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <appendername="SPRING"class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 根据时间来制定滚动策略 --> <rollingPolicyclass="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${user.dir}/logs/${DIR_NAME}/springframework.%d{yyyy-MM-dd}.log </fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <!-- 根据文件大小来制定滚动策略 --> <triggeringPolicyclass="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10MB</maxFileSize> </triggeringPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern> </encoder> </appender> <!-- RollingFileAppender end --> <!-- logger begin --> <!-- 本项目的日志记录,分级打印 --> <loggername="org.zp.notes.spring"level="TRACE"additivity="false"> <appender-refref="STDOUT"/> <appender-refref="ERROR"/> <appender-refref="WARN"/> <appender-refref="INFO"/> <appender-refref="DEBUG"/> <appender-refref="TRACE"/> </logger> <!-- SPRING框架日志 --> <loggername="org.springframework"level="WARN"additivity="false"> <appender-refref="SPRING"/> </logger> <rootlevel="TRACE"> <appender-refref="ALL"/> </root> <!-- logger end --> </configuration>

配置日志文件大小阈值:

 <!-- 系统日志输出 --> <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/info.log</file> <!-- 循环政策:基于文件大小创建日志文件 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <!-- 单个日志文件最大 10MB,总日志量不能超过totalSizeCap--> <maxFileSize>10MB</maxFileSize> <!-- 用来指定日志文件的上限大小,如果到了设置的值,就会删除旧的日志 --> <totalSizeCap>1GB</totalSizeCap> <cleanHistoryOnStart>true</cleanHistoryOnStart> </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> <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/error.log</file> <!-- 循环政策:基于文件大小创建日志文件 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <!-- 单个日志文件最大 10MB,总日志量不能超过totalSizeCap--> <maxFileSize>10MB</maxFileSize> <!-- 用来指定日志文件的上限大小,如果到了设置的值,就会删除旧的日志 --> <totalSizeCap>1GB</totalSizeCap> <cleanHistoryOnStart>true</cleanHistoryOnStart> </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> <!-- 系统模块日志级别控制 --> <logger name="com.oceansite" level="info" /> <!-- Spring日志级别控制 --> <logger name="org.springframework" level="warn" /> <root level="info"> <appender-ref ref="console" /> </root> <!--系统操作日志--> <root level="info"> <appender-ref ref="file_info" /> <appender-ref ref="file_error" /> </root> </configuration>

完整的log4j.xml参考示例

log4j的配置文件一般有xml格式或properties格式。这里为了和logback.xml做个对比,就不介绍properties了,其实也没太大差别。

讯享网<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS\} [%-5p] [%t] %c{36\}.%M - %m%n"/> </layout> <!--过滤器设置输出的级别--> <filter class="org.apache.log4j.varia.LevelRangeFilter"> <param name="levelMin" value="debug"/> <param name="levelMax" value="fatal"/> <param name="AcceptOnMatch" value="true"/> </filter> </appender> <appender name="ALL" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="${user.dir}/logs/spring-common/jcl/all"/> <param name="Append" value="true"/> <!-- 每天重新生成日志文件 --> <param name="DatePattern" value="'-'yyyy-MM-dd'.log'"/> <!-- 每小时重新生成日志文件 --> <!--<param name="DatePattern" value="'-'yyyy-MM-dd-HH'.log'"/>--> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS\} [%-5p] [%t] %c{36\}.%M - %m%n"/> </layout> </appender> <!-- 指定logger的设置,additivity指示是否遵循缺省的继承机制--> <logger name="org.zp.notes.spring" additivity="false"> <level value="error"/> <appender-ref ref="STDOUT"/> <appender-ref ref="ALL"/> </logger> <!-- 根logger的设置--> <root> <level value="warn"/> <appender-ref ref="STDOUT"/> </root> </log4j:configuration>

logback配置参数说明

使用API

1、slf4j用法

使用slf4j的API很简单。使用LoggerFactory初始化一个Logger实例,然后调用Logger对应的打印等级函数就行了。

import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class App { private static final Logger log = LoggerFactory.getLogger(App.class); public static void main(String[] args) { String msg = "print log, current level: {}"; log.trace(msg, "trace"); log.debug(msg, "debug"); log.info(msg, "info"); log.warn(msg, "warn"); log.error(msg, "error"); } }

注解@Slf4j的使用:

声明:如果不想每次都写private  final Logger logger = LoggerFactory.getLogger(当前类名.class); 可以用注解@Slf4j;

1.使用idea在pom文件加入lombok的依赖

2.类上面添加@Sl4j注解,然后使用log打印日志;

 2、common-logging用法

common-logging用法和slf4j几乎一样,但是支持的打印等级多了一个更高级别的:fatal。
此外,common-logging不支持{}替换参数,你只能选择拼接字符串这种方式了。

讯享网import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class JclTest { private static final Log log = LogFactory.getLog(JclTest.class); public static void main(String[] args) { String msg = "print log, current level: "; log.trace(msg + "trace"); log.debug(msg + "debug"); log.info(msg + "info"); log.warn(msg + "warn"); log.error(msg + "error"); log.fatal(msg + "fatal"); } }
优质博客:Spring Boot默认只将日志输出到控制台,不输出到文件,需要配置23、springboot日志使用入门-- SLF4J+Logback 实现(springboot默认的日志实现),日志打印到控制台及日志输出到指定文件_springboot日志配置slf4j-CSDN博客
小讯
上一篇 2025-03-18 14:27
下一篇 2025-03-28 16:17

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/27619.html