如果您对springboot,logback和logging.config属性感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于springboot,logback和loggi
如果您对spring boot,logback和logging.config属性感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于spring boot,logback和logging.config属性的详细内容,我们还将为您解答spring boot logback的相关问题,并且为您提供关于-Dlogback.configurationFile = logback.xml在运行Spring-Boot时被忽略、java – Log4j(通过Spring Boot Logging)logging.level属性是否允许使用通配符?、Java中 SLF4J和Logback和Log4j和Logging的区别与联系、logback logback.xml 常用配置详解(一)
- spring boot,logback和logging.config属性(spring boot logback)
- -Dlogback.configurationFile = logback.xml在运行Spring-Boot时被忽略
- java – Log4j(通过Spring Boot Logging)logging.level属性是否允许使用通配符?
- Java中 SLF4J和Logback和Log4j和Logging的区别与联系
- logback logback.xml 常用配置详解(一)
and
spring boot,logback和logging.config属性(spring boot logback)
如何解决spring boot,logback和logging.config属性?
我找到了解决方案,并且理解了为什么spring不使用application.properties
文件中定义的’logging.config’属性。
解决方案和说明:
初始化日志记录时,spring boot仅查找classpath或环境变量。
我使用的解决方案是包括一个父logback.xml文件,该文件根据spring概要文件包含了正确的日志记录配置文件。
logback.xml:
<configuration>
<include resource="logback-${spring.profiles.active}.xml"/>
</configuration>
logback- [profile] .xml(在本例中为logback-dev.xml):
<included>
<!-- put your appenders -->
<appender name="CONSOLE">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{ISO8601} %p %t %c{0}.%M - %m%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- put your loggers here -->
<logger name="org.springframework.web" additivity="false" level="INFO">
<appender-ref ref="CONSOLE" />
</logger>
<!-- put your root here -->
<root level="warn">
<appender-ref ref="CONSOLE" />
</root>
</included>
注意: 启动应用程序时,必须在命令行参数中设置“ spring.profiles.active”。EG for JVM属性:-Dspring.profiles.active=dev
编辑(多个活动配置文件):为了避免出现多个文件,我们可以使用需要Janino依赖的条件处理(在此处进行设置),请参阅条件文档。使用此方法,我们还可以同时检查多个活动配置文件。EG(我没有测试此解决方案,因此如果无法解决,请发表评论):
<configuration>
<if condition=''"${spring.profiles.active}".contains("profile1")''>
<then>
<!-- do whatever you want for profile1 -->
</then>
</if>
<if condition=''"${spring.profiles.active}".contains("profile2")''>
<then>
<!-- do whatever you want for profile2 -->
</then>
</if>
<!-- common config -->
</configuration>
有关条件处理的另一个示例,请参见javasenior答案。
解决方法
我正在使用logback库在spring boot项目中实现日志记录。我想根据我的spring配置文件(属性“ spring.pofiles.active”)加载不同的日志记录配置文件。我有3个文件:logback-dev.xml,logback-inte.xml和logback-prod.xml。我正在使用Spring Boot版本1.2.2.RELEASE。
如你在Spring Boot文档中所读。它说:
可以通过在类路径中包括适当的库来激活各种日志记录系统,并通过在类路径的根目录中或在Spring Environment属性logging.config指定的位置中提供适当的配置文件来进一步自定义各种日志记录系统。(但是请注意,由于日志记录是在创建ApplicationContext之前初始化的,因此无法从Spring @Configuration文件中的@PropertySources控制日志记录。系统属性和常规的Spring Boot外部配置文件都可以正常工作。)
所以我试图在我的application.properties文件中设置’logging.config’属性:
logging.config=classpath:/logback-${spring.profiles.active}.xml
但是,当我启动应用程序时,未加载我的logback- {profile} .xml …
我认为日志记录是使用Spring Boot的所有项目都遇到的常见问题。我采用上述方法走上正确的路吗?我还有其他可行的解决方案,但我发现它们不那么优雅(在logback.xml文件或命令行属性中使用Janino进行条件解析)。
-Dlogback.configurationFile = logback.xml在运行Spring-Boot时被忽略
我们有一个spring-boot 1.0.RC1应用程序,其中配置了用于日志记录的logback和src / test /
resources中的logback.xml文件。当我们从maven运行spring-
boot时,似乎可以看到并尊重logback文件。(这是我们在spring-boot徽标之后需要的日志记录格式)
D:\Users\myName\My Projects\Work\my-co\my-app\src\my-app\my-app-camel>mvn clean spring-boot:run -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener -Dlogback.configurationFile=src/test/resources/logback.xml
<snip/>
[INFO] --- spring-boot-maven-plugin:0.5.0.M7:run (default-cli) @ my-app-camel ---
06:41:56,011 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [src/test/resources/logback.xml] at [file:/D:/Users/myName/My%20Projects/Work/my-co/my-app/src/my-app/my-app-camel/src/test/resources/logback.xml]
06:41:56,150 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
06:41:56,170 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Setting ReconfigureOnChangeFilter scanning period to 5 seconds
06:41:56,171 |-INFO in ReconfigureOnChangeFilter{invocationCounter=0} - Will scan for changes in [[D:\Users\myName\My Projects\Work\my-co\my-app\src\my-app\my-app-camel\src\test\resources\logback.xml]] every 5 seconds.
06:41:56,172 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Adding ReconfigureOnChangeFilter as a turbo filter
06:41:56,223 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
06:41:56,233 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
06:41:56,276 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
06:41:56,389 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [me.moocar.logbackgelf.GelfAppender]
06:41:56,398 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [GELF]
06:41:56,567 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.my-co.my-app.] to DEBUG
06:41:56,568 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [com.my-co.my-app.] to false
06:41:56,569 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[com.my-co.my-app.]
06:41:56,571 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.] to DEBUG
06:41:56,572 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.] to false
06:41:56,572 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[org.]
06:41:56,573 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
06:41:56,574 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
06:41:56,574 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
06:41:56,578 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@4ffdcca5 - Registering current configuration as safe fallback point
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__,| / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.0.0.RC1)
06:41:57.436 [com.my-co.my-app.Application.main()] INFO com.my-co.my-app.Application - Starting Application on MY-LAPTOP-HOSTNAME with PID 7812 (started by myName)
06:41:57.952 [com.my-co.my-app.Application.main()] INFO o.s.b.f.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [META-INF/spring/camel-server.xml]
<etc./>
但是,当我们删除潜入src / java /
resources的流氓logback.xml文件并在其他所有内容不变的情况下重新运行时(请确保我们也清除了目标中的文件):
D:\Users\myName\My Projects\Work\my-co\my-app\src\my-app\my-app-camel>mvn clean spring-boot:run -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener -Dlogback.configurationFile=src/test/resources/logback.xml
<snip/>
[INFO]
[INFO] <<< spring-boot-maven-plugin:1.0.0.RC1:run (default-cli) @ my-app-camel <<<
[INFO]
[INFO] --- spring-boot-maven-plugin:1.0.0.RC1:run (default-cli) @ my-app-camel ---
06:53:59,598 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [src/test/resources/logback.xml] at [file:/D:/Users/myName/My%20Projects/Work/my-co/my-app/src/my-app/my-app-camel/src/test/resources/logback.xml]
06:53:59,736 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
06:53:59,755 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Setting ReconfigureOnChangeFilter scanning period to 5 seconds
06:53:59,756 |-INFO in ReconfigureOnChangeFilter{invocationCounter=0} - Will scan for changes in [[D:\Users\myName\My Projects\Work\my-co\my-app\src\my-app\my-app-camel\src\test\resources\logback.xml]] every 5 seconds.
06:53:59,757 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Adding ReconfigureOnChangeFilter as a turbo filter
06:53:59,806 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
06:53:59,817 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
06:53:59,858 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
06:53:59,971 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [me.moocar.logbackgelf.GelfAppender]
06:53:59,980 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [GELF]
06:54:00,144 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.my-co.my-app.] to DEBUG
06:54:00,144 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [com.my-co.my-app.] to false
06:54:00,145 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[com.my-co.my-app.]
06:54:00,148 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.] to DEBUG
06:54:00,148 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.] to false
06:54:00,149 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[org.]
06:54:00,150 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
06:54:00,150 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
06:54:00,151 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
06:54:00,154 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@54c1f582 - Registering current configuration as safe fallback point
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__,| / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.0.0.RC1)
2014-02-12 06:54:01.023 INFO 5240 --- [lication.main()] com.my-co.my-app.Application : Starting Application on MY-LAPTOP-HOSTNAME with PID 5240 (started by myName)
2014-02-12 06:54:01.564 INFO 5240 --- [lication.main()] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [META-INF/spring/camel-server.xml]
<etc./>
您会注意到,spring-boot启动后的日志记录格式与第一个输出不同。但是,logback(在Spring-Boot启动之前)报告它在src / test
/ resources中看到了logback.xml,就像第一次一样。
感兴趣的是,我们的logback.xml(位于src / java / resources和src / test / resources中都如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="5 seconds">
<appender name="STDOUT">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n</pattern>
</encoder>
</appender>
<appender name="GELF">
<facility>logback-gelf-test</facility>
<graylog2ServerHost>XXX.XXX.XXX.XXX</graylog2ServerHost>
<graylog2ServerPort>NNNNN</graylog2ServerPort>
<useLoggerName>true</useLoggerName>
<useThreadName>true</useThreadName>
<useMarker>true</useMarker>
<graylog2ServerVersion>0.9.6</graylog2ServerVersion>
<chunkThreshold>1000</chunkThreshold>
<messagePattern>%m%rEx</messagePattern>
<shortMessagePattern>%.-100(%m%rEx)</shortMessagePattern>
<additionalField>ipAddress:_ip_address</additionalField>
<additionalField>requestId:_request_id</additionalField>
<staticAdditionalField>_node_name:www013</staticAdditionalField>
<includeFullMDC>true</includeFullMDC>
</appender>
<logger name="com.my-co.my-app." level="DEBUG" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org." level="DEBUG" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
<!--<appender-ref ref="GELF" />-->
</root>
</configuration>
因此,总而言之,似乎(虽然我可能错了),当logback.xml与spring-boot应用程序捆绑在一起时,就可以看到并使用它(例如,在src /
java / resources中),但是当我们不捆绑时,然后,尽管logback尽了最大努力,却被忽略了。
至于解决这个问题,我们很困惑。我们猜想在我们的spring-boot
jar中有什么地方会优先考虑,或者关闭logback,或者介入并告诉logback忽略刚刚被告知的内容,并使用另一个默认值。
另外,我们很愚蠢,但看不到它。感谢所有的帮助。
java – Log4j(通过Spring Boot Logging)logging.level属性是否允许使用通配符?
当我安装使用Log4j的Java应用程序(通过Spring Boot Logging)时,我被告知我可以通过在application.properties文件中包含以下行来为应用程序中使用的所有包配置日志记录级别:
logging.level.* = ERROR
ERROR可以是我想要使用的任何日志记录级别.
但是,当我将级别从一个值更改为另一个值时,无论我使用什么值,我发现日志消息将显示在日志中.
最后,我发现使用特定的包名称可以控制要记录的最低级别.也就是说,logging.level.org.orgname.appname = ERROR会做我想要的.
日志级别属性是否意味着支持像“*”这样的通配符?
Log4j和Spring Boot Logging都不支持logging.level.*等通配符.有一些文档使用了这个确切的短语,但它们意味着读者用包名替换星号.我的同事们并不理解这一点,并在文档中逐字使用它们的应用程序.
Spring Boot Logging中的等价物是logging.level.root. Log4j配置文件中的等价物是log4j.rootLogger,尽管这需要一个或多个附加参数来提供log appender对象的名称.
Java中 SLF4J和Logback和Log4j和Logging的区别与联系
前言
Java帝国在诞生之初就提供了集合、线程、IO、网络等常用功能,从C和C++领地那里吸引了大量程序员过来加盟,但是却有意无意地忽略了一个重要的功能: 输出日志。
对于这一点,IO大臣其实非常清楚, 日志是个很重要的东西, 因为程序运行起来以后, 基本上就是一个黑盒子,如果程序的行为和预料的不一致,那就是出现Bug了,如何去定位这个Bug 呢?
臣民们能用的工具有两个,第一个就是单步调试,一步步地跟踪,查看代码中变量的值, 这种办法费时费力, 并且只能在程序员的机器上才能用。
第二种就是在特定的地方打印日志, 通过日志的输出,帮助快速定位。尤其是当代码在生产环境上跑起来以后, 日志信息更是必不可少,要不然出了状况两眼一抹黑,上哪儿找问题去? 总不能让臣民们把自己变成一个线程进入系统来执行吧?
但是IO大臣也有自己的小算盘: 日志嘛, 用我的System.out.println(…..) 不就可以了?! 我还提供了System.err.println不是?
在IO大臣的阻挠下, 从帝国的第一代国王到第三代国王, 都没有在JDK中提供日志相关的工具包, 臣民们只好忍受着去使用System.out.println去输出日志,把所有的信息都输出到控制台, 让那里变成一堆垃圾。
张家村
张家村的电子商务系统也不能幸免,自然也遇到了日志的问题。经验丰富的老村长已经烦透了System.out.println所输出的大量难于理解的无用信息,看着村民民整天苦逼地和这些System.out做斗争,他找来了小张,命令他设计一个通用的处理日志的系统。
小张在消息队列和JMS的设计上花了不少功夫, 积累了丰富的经验,从那以后一直都是实现业务代码,一直都是CRUD, 张二妮整天笑话自己是HTML填空人员,这一回一定要让她看看自己的设计功力!
老村长给小张下达的需求是这样的:
1. 日志消息除了能打印到控制台, 还可以输出到文件,甚至可以通过邮件发送出去(例如生成环境出错的消息)
2. 日志内容应该可以做格式化, 例如变成纯文本,XML, HTML格式等等
3. 对于不同的Java class,不同的 package , 还有不同级别的日志,应该可以灵活地输出到不同的文件中。
- 例如对于com.foo 这个package,所有的日志都输出到 foo.log 文件中
- 对于com.bar 这个package ,所有文件都输出到bar. log文件中
- 对于所有的ERROR级别的日志,都输出到 errors.log文件中
4. 能对日志进行分级, 有些日志纯属debug , 在本机或者测试环境使用, 方便程序员的调试, 生产环境完全不需要。有些日志是描述错误(error)的, 在生产环境下出错的话必须要记录下来,帮助后续的分析。
小张仔细看了看,拍着胸脯对老村长说:“没问题, 明天一定让您老看到结果。”
小张的设计
老村长走了以后,小张开始分析需求, 祭出“面向对象设计大法”,试图从村长的需求中抽象出一点概念。
首先要记录日志,肯定需要一个类来表达日志的概念,这个类至少应该有两个属性,一个是时间戳,一个是消息本身,把它叫做 LoggingEvent 吧,记录日志就像记录一个事件嘛。
其次是日志可以输出到不同的地方,控制台、文件、邮件等等, 这个可以抽象一下,不就是写到不同的目的地吗? 可以叫做LogDestination?
嗯, 还是简单一点,叫做 Appender 吧, 暗含了可以不断追加日志的意思。
至于第二条的日志内容可以格式化,完全可以比葫芦画瓢, 定义一个Formatter接口去格式化消息。
对了, Appender 应该引用Formatter ,这样以来就可以对LoggingEvent记录格式化以后再发送。
第三条需求把小张给难住了,不同的class, package 输出的目的地不同? “目的地”这个概念是由Appender来表达的, 难道让不同的class, package 和Appender关联? 不不, 不能这样 !
还需要一个新的概念 , 这个概念是什么?
从用户角度想一下, 村民们要想获取日志,必须得先获取个什么东西,这个东西是不是可以称为Logger啊? 灵感的火花就闪了那么一下就被小张抓住了: 获取Logger的时候要传入类名或者包名!
class, package就区分开了, 然后让Logger 和Appender关联,灵活地设置日志的目的地, 并且一个Logger可以拥有多个Appender,同一条日志消息可以输出到多个地方, 完美!
小张迅速地画出了核心类的类图:
还算漂亮,小张陶醉着自我欣赏了一下。
再接再厉, 把第四条需求也设计一下,日志要分级,这个简单, 定义一个Priority的类,里边定义5个常量DEBUG, INFO, WARN, ERROR, FATAL, 表示5个不同的级别就OK了。当然这我5个级别有高低之分, DEBUG级别最低, FATAL级别最高。
还可以给Logger增加一些辅助编程的方法,如Logger.debug(….) , Logger.info(…) , Logger.warn(…) 等等, 这样村民们将来就可以轻松地输出各种级别的日志了。
等一下, 老村长还说过“对于所有的ERROR级别的日志,都输出到 errors.log文件中” 类似这样的需求, 好像给忽略了。
这也好办嘛, 只要在Appender上增加一个属性,就叫做Priority, 如果用户要输出的日志是DEBUG级别, 但是有个FileAppender的Priority是 ERROR级别,那这个日志就不用在这个FileAppender中输出了 ,因为ERROR级别比DEBUG级别高嘛。
同理, 在Logger类上也可以增加一个Priority的属性,用户可以去设置, 如果一个Logger的Priority是ERROR, 而用户调用了这个Logger的debug方法, 那这个debug 的消息也不会输出。
小张全心全意地投入到设计当中,一看时间, 都快半夜了, 赶紧休息, 明天向村长汇报去。
正交性
第二天, 小张给老村长展示了自己设计的LoggerEvent, Logger , Appender, Formatter, Priority 等类和接口, 老村长捻着胡子满意地点点头:“不错不错,与上一次相比有巨大的进步。你知不知道我在需求中其实给了你引导?”
“引导? 什么引导? ”
“就是让你朝着正交的方向去努力啊”
“正交? ”
“如果你把Logger, Appender, Formatter看成坐标系中的X轴,Y轴,Z轴, 你看看,这三者是不是可以独立变化而不互相影响啊?”
“我赛,果然如此,我可以任意扩展Appender接口而影响不到Logger和Formatter, 无论有多少个Logger 都影响不了Appender和Formatter , 这就是正交了?”
“是啊,当你从系统中提取出正交的概念的时候,那就威力无比了,因为变化被封装在了一个维度上,你可以把这些概念任意组合,而不会变成意大利面条似的代码。 ”
听到村长做了理论的升华, 小张兴奋得直搓手。
“好吧,你把这个设计实现了吧,对了,你打算叫什么名字? ” 村长问道
“我打算把他叫做Log4j , 意思是Log for Java”
“不错,就这么定了吧”
Log4j
小张又花了两个月的时间把Log4j 开发了出来, 由于Log4j有着良好的设计,优异的性能, 不仅仅是张家村的人在用, Java帝国的很多村镇、部落都爱上了它。
后来张家村把Log4j 在Apache部落开源了, 这下子吸引了无数的人无偿帮助测试它,扩展它,改进它, 很快就成了帝国最流行的日志工具。
张家村建议帝国把Log4j 纳入到JDK 中, 帝国那效率低下的官僚机构竟然拒绝了。 消息传到了IO大臣的耳朵里,他不由的扼腕叹息: 唉,失去了一次极好的招安机会啊。 现在唯一的办法就是赶紧上奏皇上,在官方也提供一套,争取让臣民们使用官方版本。
到了第四代国王(JDK1.4),臣民们终于看到了帝国提供的java.util.logging包,也是用来记录日志的,并且其中的核心概念Logger, Formatter, Handler 和 Log4j非常相似,只是为时已晚, Log4j早已深入人心了, 不可撼动了。
最后
Log4j 在Apache开源以后, 小张也逐渐地有点落寞,他闲不住又写了一个工具,叫做logback, 有了之前的经验,这logback 比log4j 还要快。
如今的日志世界有了很多的选择 ,除了java.util.logging, log4j 之外,还有logback,tinylog 等其他工具。
小张想了想, 这么多日志工具,用户如果想切换了怎么办?不想用log4j了,能换到logback吗?
我还是提供一个抽象层吧, 用户用这个抽象层的API来写日志, 底层具体用什么日志工具不用关心,这样就可以移植了。
小张把这抽象层就叫做Simple Logging Facade for Java,简称SLF4J。
对于Log4j , JDK logging, tinylog 等工具, 需要一个适配层, 把SLF4J 的API转化成具体工具的调用接口。
由于Logback这个工具也是出自小张之手, 直接实现了SLF4J的API,所以连适配层都不需要了, 用起来速度飞快,效率最高,SLFJ4+Logback 成为了很多人的最爱, 大有超越Apache Common Logging + Log4j 之势。
后记: 本文主要想讲一下日志工具的历史和现状, 尤其是Log4j核心的设计理念。
文中的小张其实就是Ceki Gülcü,他开发了Log4j , logback,以及slfj4, 为Java的日志事业做出了卓越的贡献。
到此这篇关于Java中 SLF4J和Logback和Log4j和Logging的区别与联系的文章就介绍到这了,更多相关Java SLF4J,Logback,Log4j,Logging内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
- slf4j与jul、log4j1、log4j2、logback的集成原理
- jdk-logging log4j logback日志系统实现机制原理介绍
- jcl与jul log4j1 log4j2 logback日志系统机制及集成原理
- slf4j jcl jul log4j1 log4j2 logback各组件系统日志切换
- Logback与Log4j2日志框架性能对比与调优方式
- 项目为什么引入log4j而不是logback代码
- 浅谈spring boot 集成 log4j 解决与logback冲突的问题
- 如何将应用的log4j替换成logback详解
- 从log4j切换到logback后项目无法启动的问题及解决方法
logback logback.xml 常用配置详解(一) and
转载文章:原文出处:http://aub.iteye.com/blog/1101260
详细整理了 logback 常用配置,
不是官网手册的翻译版,而是使用总结,旨在更快更透彻的理解其配置
根节点 <configuration>
包含的属性
- scan: 当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为 true。
- scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为 1 分钟。
- debug: 当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态。默认值为 false。
例如:
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 其他配置省略-->
</configuration>
根节点 <configuration>
的子节点
设置上下文名称:<contextName>
每个 logger 都关联到 logger 上下文,默认上下文名称为 “default”。但可以使用 <contextName>
设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>myAppName</contextName>
<!-- 其他配置省略-->
</configuration>
设置变量: <property>
用来定义变量值的标签,<property>
有两个属性,name 和 value;其中 name 的值是变量的名称,value 的值时变量定义的值。通过 <property>
定义的值会被插入到 logger 上下文中。定义变量后,可以使 “${}” 来使用变量。
例如使用 <property>
定义上下文名称,然后在 <contentName>
设置 logger 上下文时使用。
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="APP_Name" value="myAppName" />
<contextName>${APP_Name}</contextName>
<!-- 其他配置省略-->
</configuration>
获取时间戳字符串:<timestamp>
两个属性 key: 标识此 <timestamp>
的名字;datePattern:设置将当前时间(解析配置文件的时间)转换为字符串的模式,遵循 java.txt.SimpleDateFormat 的格式。
例如将解析配置文件的时间作为上下文名称:
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<timestamp key="bySecond" datePattern="yyyyMMdd''T''HHmmss"/>
<contextName>${bySecond}</contextName>
<!-- 其他配置省略-->
</configuration>
<appender>
具体见下篇博客《logback logback.xml 常用配置详解(二)<appender>》
<loger>
用来设置某一个包或者具体的某一个类的日志打印级别、以及指定 <appender>
。<loger>
仅有一个 name 属性,一个可选的 level 和一个可选的 addtivity 属性。
name:
用来指定受此 loger 约束的某一个包或者具体的某一个类。
level:
用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值 INHERITED 或者同义词 NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前 loger 将会继承上级的级别。
addtivity:
是否向上级 loger 传递打印信息。默认是 true。
<loger>
可以包含零个或多个 <appender-ref>
元素,标识这个 appender 将会添加到这个 loger。
<root>
也是 <loger>
元素,但是它是根 loger。只有一个 level 属性,应为已经被命名为 "root"。
level:
用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为 INHERITED 或者同义词 NULL。 默认是 DEBUG。
<root>
可以包含零个或多个 <appender-ref>
元素,标识这个 appender 将会添加到这个 loger。
例如:
LogbackDemo.java 类
package logback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogbackDemo {
private static Logger log = LoggerFactory.getLogger(LogbackDemo.class);
public static void main(String[] args) {
log.trace("======trace");
log.debug("======debug");
log.info("======info");
log.warn("======warn");
log.error("======error");
}
}
logback.xml 配置文件
第 1 种:只配置 root
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默认配置为PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
其中 appender 的配置表示打印到控制台 (稍后详细讲解 appender);
<root level="INFO">
将 root 的打印级别设置为 “INFO”,指定了名字为 “STDOUT” 的 appender。
当执行 logback.LogbackDemo 类的 main 方法时,root 将级别为 “INFO” 及大于 “INFO” 的日志信息交给已经配置好的名为 “STDOUT” 的 appender 处理,“STDOUT” appender 将信息打印到控制台;
打印结果如下:
13:30:38.484 [main] INFO logback.LogbackDemo - ======info
13:30:38.500 [main] WARN logback.LogbackDemo - ======warn
13:30:38.500 [main] ERROR logback.LogbackDemo - ======error
第 2 种:带有 loger 的配置,不指定级别,不指定 appender
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默认配置为PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- logback为java中的包 -->
<logger name="logback"/>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
其中 appender 的配置表示打印到控制台 (稍后详细讲解 appender);
<logger name="logback" />
将控制 logback 包下的所有类的日志的打印,但是并没用设置打印级别,所以继承他的上级 <root>
的日志级别 “DEBUG”;
没有设置 addtivity,默认为 true,将此 loger 的打印信息向上级传递;
没有设置 appender,此 loger 本身不打印任何信息。
<root level="DEBUG">
将 root 的打印级别设置为 “DEBUG”,指定了名字为 “STDOUT” 的 appender。
当执行 logback.LogbackDemo 类的 main 方法时,因为 LogbackDemo 在包 logback 中,所以首先执行 <logger name="logback" />
,将级别为 “DEBUG” 及大于 “DEBUG” 的日志信息传递给 root,本身并不打印;
root 接到下级传递的信息,交给已经配置好的名为 “STDOUT” 的 appender 处理,“STDOUT” appender 将信息打印到控制台;
打印结果如下:
13:19:15.406 [main] DEBUG logback.LogbackDemo - ======debug
13:19:15.406 [main] INFO logback.LogbackDemo - ======info
13:19:15.406 [main] WARN logback.LogbackDemo - ======warn
13:19:15.406 [main] ERROR logback.LogbackDemo - ======error
第 3 种:带有多个 loger 的配置,指定级别,指定 appender
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默认配置为PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- logback为java中的包 -->
<logger name="logback"/>
<!--logback.LogbackDemo:类的全路径 -->
<logger name="logback.LogbackDemo" level="INFO" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<root level="ERROR">
<appender-ref ref="STDOUT" />
</root>
</configuration>
其中 appender 的配置表示打印到控制台 (稍后详细讲解 appender);
<logger name="logback" />
将控制 logback 包下的所有类的日志的打印,但是并没用设置打印级别,所以继承他的上级 <root>
的日志级别 “DEBUG”;
没有设置 addtivity,默认为 true,将此 loger 的打印信息向上级传递;
没有设置 appender,此 loger 本身不打印任何信息。
<logger name="logback.LogbackDemo" level="INFO" additivity="false">
控制 logback.LogbackDemo 类的日志打印,打印级别为 “INFO”;
additivity 属性为 false,表示此 loger 的打印信息不再向上级传递,
指定了名字为 “STDOUT” 的 appender。
<root level="ERROR">
将 root 的打印级别设置为 “ERROR”,指定了名字为 “STDOUT” 的 appender。
当执行 logback.LogbackDemo 类的 main 方法时,先执行 <logger name="logback.LogbackDemo" level="INFO" additivity="false">
,将级别为 “INFO” 及大于 “INFO” 的日志信息交给此 loger 指定的名为 “STDOUT” 的 appender 处理,在控制台中打出日志,不再向次 loger 的上级 <logger name="logback"/>
传递打印信息; <logger name="logback"/>
未接到任何打印信息,当然也不会给它的上级 root 传递任何打印信息;
打印结果如下:
14:05:35.937 [main] INFO logback.LogbackDemo - ======info
14:05:35.937 [main] WARN logback.LogbackDemo - ======warn
14:05:35.937 [main] ERROR logback.LogbackDemo - ======error
如果将 <logger name="logback.LogbackDemo" level="INFO" additivity="false">
修改为 <logger name="logback.LogbackDemo" level="INFO" additivity="true">
那打印结果将是什么呢?
没错,日志打印了两次,想必大家都知道原因了,因为打印信息向上级传递,logger 本身打印一次,root 接到后又打印一次
打印结果如下:
14:09:01.531 [main] INFO logback.LogbackDemo - ======info
14:09:01.531 [main] INFO logback.LogbackDemo - ======info
14:09:01.531 [main] WARN logback.LogbackDemo - ======warn
14:09:01.531 [main] WARN logback.LogbackDemo - ======warn
14:09:01.531 [main] ERROR logback.LogbackDemo - ======error
14:09:01.531 [main] ERROR logback.LogbackDemo - ======error
今天的关于spring boot,logback和logging.config属性和spring boot logback的分享已经结束,谢谢您的关注,如果想了解更多关于-Dlogback.configurationFile = logback.xml在运行Spring-Boot时被忽略、java – Log4j(通过Spring Boot Logging)logging.level属性是否允许使用通配符?、Java中 SLF4J和Logback和Log4j和Logging的区别与联系、logback logback.xml 常用配置详解(一)
本文标签: