Logback旨在作为log4j项目的继承者,由Ceki Gülcü设计。与所有现有的日志系统相比,Logback的速度更快,占地面积更小。在特定的关键执行路径上,Logback的表现比Log4j快十倍左右。
logback-classic中的
Logger
类原生地实现了SLF4J的API,所以当我们以logback-classic作为底层实现来调用SLF4J的记录器时,会产生零开销。使用SLF4J API极大地减少了切换日志框架的工作。
1.Logback的依赖性
要运行logback,需要在应用程序的运行时间中使用三个模块。
- logback-core:提供其他两个模块所需的主要类和接口。
- logback-classic: 原生实现了SLF4J的API。
- slf4j-api: logback-classic的Logger类实现了SLF4J API。所以我们可以随时在logback和其他日志框架之间来回切换。
- logback-access(可选):与Servlet容器集成,如Tomcat和Jetty,以提供远程日志功能。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
注意,logback-classic
会自动拉入logback-core
和slf4j-api
,所以添加 logback-classic 依赖关系即可。
2.开始使用Logback
2.1.创建和使用记录仪
在依赖关系被导入classpath后,我们可以开始在应用程序中记录日志。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
public static void main(final String[] args)
{
Logger logger = LoggerFactory.getLogger(Main.class);
// OR
// Logger logger = LoggerFactory.getLogger("com.howtodoinjava.demo");
logger.info("Info Message Logged !!!");
}
}
18:40:47.392 [main] INFO com.howtodoinjava.demo.slf4j.Main - Info Message Logged !!!
注意上面的类Main
。它导入了SLF4J API中定义的Logger和LoggerFactory类。我们使用静态方法LoggerFactory.getLogger()
,获得Logger实例。然后我们使用logger.info()来记录信息。它支持debug(),info(),*warn()和error()*方法。
getLogger()
方法可以接受两种类型的参数,即一个class
类型和一个String
。这两个方法都会返回一个与参数相对应的命名的记录器。
注意我们没有使用任何logback的特定包或类。这样,我们对logback没有直接的依赖性,可以在不改变代码的情况下被其他日志库所取代。
2.2.参数化的消息
在实际应用中,日志信息并不总是纯字符串。我们需要将上下文数据记录到文件中,如对象ID、自定义错误信息和代码等。
这些复杂的消息一般是通过附加字符串来创建的,这涉及到分配内存、串联操作,最后在消息打印完毕、对象不在使用时进行垃圾回收。
有时,上述的字符串连接操作可能没有必要。例如,如果我们将日志级别设置为INFO,那么给定的调试日志将不会被打印在日志文件中,但无论如何,字符串连接都会发生。这样的字符串连接是开销,应该被避免。
logger.info("Article fecthed for id : " + 1 + " is : " + a.toString());
Logback用参数化的消息消除了不需要的串联。这些消息使用大括号{}
,作为消息中要打印的对象的占位符。
一旦Logback确定需要打印日志消息,它就会通过串联原始消息并将大括号替换为object.toString()
方法的输出来建立日志消息。
logger.info("Article fecthed for id : {} is : {}", 1, article);
我们可以使用参数化的消息来打印任何类型的对象或信息,包括异常堆栈跟踪。
3.Logback配置
现有的log4j用户可以使用我们的PropertiesTranslator网络应用程序将他们的log4j.properties文件转换成logback.xml。
3.1.零配置默认值
默认情况下,当没有找到默认的配置文件时,logback将在根记录器中添加一个ConsoleAppender
,这将在控制台中记录所有的消息。
输出的格式是使用PatternLayoutEncoder设置为’%d{HH:mm:ss.SSS}的模式。[%thread] %-5level %logger{36}。–%msg%n“。另外,默认情况下,根记录器被分配为DEBUG级别。
这是默认使用的等效配置。
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
3.2.加载配置文件
默认的配置足以让我们开始使用并用于POC目的。但对于生产级的应用,我们需要在合适的日志级别上配置不同的文件记录器。
在启动过程中,logback尝试在classpath中找到logback-test.xml
或logback.xml
,顺序相同。如果找到该文件,它将使用提供的配置文件进行自我配置。
如果classpath中没有这样的文件,它就试图通过查找classpath中的META-INF\services\ch.qos.logback.classic.spi.Configurator文件来定位com.qos.logback.classic.spi.Configurator接口的实现,进行程序化配置。
如果没有找到该文件或Configurator的实现,它就会用默认配置进行自我配置,如前所述。
注意,可以用一个名为 “logback.configurationFile
“的系统属性或启动参数指定默认配置文件的位置。这个属性的值可以是一个URL、classpath上的资源或应用程序外部文件的路径。
3.3.检查初始化错误
如果我们在logback初始化过程中面临任何错误,我们可以在configuration
标签中设置debug="true"
。这将在处理配置时向控制台打印状态信息。
请看给定配置文件在控制台打印的状态信息。我们已经创建了appender STDOUT,但在根记录器中,我们把名称定为STDOUT_ONE。打印的日志在控制台中突出了这个配置问题,信息是无法找到名为[STDOUT1]的appender。
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
...
</appender>
<root level="debug">
<appender-ref ref="STDOUT_ONE" />
</root>
</configuration>
18:34:34,556 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
18:34:34,556 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/C:/devsetup/gitrepo/opensource-examples/target/classes/logback.xml]
18:34:34,675 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
18:34:34,679 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
18:34:34,686 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
18:34:34,708 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
18:34:34,708 |-ERROR in ch.qos.logback.core.joran.action.AppenderRefAction - Could not find an appender named [STDOUT1]. Did you define it below instead of above in the configuration file?
18:34:34,708 |-ERROR in ch.qos.logback.core.joran.action.AppenderRefAction - See http://logback.qos.ch/codes.html#appender_order for more details.
18:34:34,708 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
18:34:34,710 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@ec756bd - Registering current configuration as safe fallback point
18:34:34,712 |-WARN in Logger[com.howtodoinjava.demo.slf4j.Main] - No appenders present in context [default] for logger [com.howtodoinjava.demo.slf4j.Main].
3.4.修改后自动重新加载配置文件
将scan="true"
设置为配置标签,让 logback 扫描更改,并在配置文件更改时自动重新配置。
在后台,一个 *ReconfigureOnChangeTask
*在一个单独的线程中运行,并在一个定义的时间间隔内检查配置文件。如果最新版本的配置文件有XML语法错误,它将返回到没有XML语法错误的前一个配置文件。
默认情况下,配置文件将每分钟扫描一次变化。要指定不同的扫描周期,请设置scanPeriod
属性。
<configuration scan="true" scanPeriod="120 seconds" >
...
</configuration>
如果没有指定时间单位,那么时间单位就假定为毫秒。
3.5.条件性配置
与其为不同的需求定义多个配置文件,我们可以把所有的配置放在一个文件中,并借助if
,then
和else
标签在相关部分周围添加条件。
例如,给定的配置将在本地开发环境中配置一个控制台appender,并启用调试日志。否则,根记录器将在提供的文件中附加记录所有错误信息。
<if condition='property("ENV").contains("localhost")'>
<then>
<appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CON" />
</root>
</then>
</if>
<root level="ERROR">
<appender-ref ref="FILE" />
</root>
注意,条件处理需要Janino库。
4.配置应用者
Logback将编写日志事件的任务委托给称为Appenders的组件。Appenders负责将日志事件以合适的格式输出到合适的输出设备上。然而,他们可以将事件的实际格式化委托给Layout或Encoder对象。
logback配置文件的非常基本的结构可以描述为configuration
元素,包含零个或多个appender
元素,后面是零个或多个logger
元素,后面是最多一个root
元素。
配置文件必须是一个格式良好的XML文件,所有开放的标签必须被正确关闭。
与显式规则有关的标签名称是不区分大小写的。很少有与隐式规则相关的标签是区分大小写的,除了第一个字母。因此,如果作为一个最佳实践,只需遵循camelCase惯例,这几乎总是正确的惯例。
4.1.控制台附加器(ConsoleAppender
控制台appender在控制台,或者更准确的说是在System.out或System.err上进行追加。
Logback,默认情况下,将控制台应用程序配置为DEBUG级别。我们可以通过在logback.xml文件中定义appender来配置其属性。
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
4.2.滚动文件Appender
文件附加器将日志事件附加到一个文件中。如果文件已经存在,它要么被追加到,要么被截断,这取决于append
属性的值。
为了记录到滚动文件(基于时间、日志文件大小或两者的组合),我们使用RollingFileAppender。RollingPolicy
负责进行滚动所需的操作,TriggeringPolicy
决定是否发生滚动以及确切的时间。
RollingPolicy实现了TriggeringPolicy接口,所以如果我们只定义rollingPolicy
,那么也将接受配置。
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_ROOT}/app.log</file>
<append>true</append>
<immediateFlush>false</immediateFlush>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Archiving daily -->
<fileNamePattern>${LOG_ROOT}/app-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<!-- Archiving 60 days of logs and max 10GB size limit -->
<maxHistory>60</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
Logback的FileAppender和它的所有子类,包括RollingFileAppender,可以从I/O故障中优雅地恢复。因此,如果一个文件服务器暂时发生故障,我们不再需要重新启动应用程序来使日志记录再次工作。只要文件服务器恢复正常,记录器就会重新工作。
通过RollingFileAppender,压缩总是异步发生的,所以即使是大的日志文件,应用程序也不会在压缩的过程中被阻塞。
默认情况下,每个日志事件都会立即刷新到底层输出流。在日志吞吐量非常高的情况下,我们可以将immediateFlush
属性设置为假。
5.常见问题
5.1.如何在日志中打印Jar文件名
一旦配置好,logback可以在其输出的堆栈跟踪行中的每一行都包括打包数据(jar文件的名称和版本)。它可以帮助调试识别由于classpath中任何库的多个版本的jar而导致的ClassCastException问题。
默认情况下,打包数据是禁用的。
<configuration packagingData="true">
...
</configuration>
5.2.关机时清理资源
在独立的应用程序中,为了正确关闭logback并释放相关资源,请使用shutdown钩子。该钩子将关闭连接到由上下文定义的记录器的所有附加器,并有序地停止任何活动线程。它将允许在后台运行的任何日志文件压缩任务在30秒内完成。
<configuration debug="false">
<shutdownHook/>
....
</configuration>
关闭钩子将被自动安装在Web应用程序中,使这个指令完全是多余的。
6.总结
在这个Logback教程中,我们学习了默认提供的配置,根据要求定制默认值,并对任何初始化错误进行故障排除。我们学会了配置基本的控制台appender和滚动文件appender。我们将在以后的文章中深入学习这两点。
我们还看到了可以帮助最有效地使用Logback的最佳实践。
学习愉快!!
今天的文章log4j 替代品:java Logback 教程分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/17214.html