一句话归纳:在java应用开发过程当中,日志输出与记录是重要一环,logback是当前的首选日志框架,本文将对springboot+logback的使用及在企业的实践进行详细描述。
在java应用开发过程当中,日志输出与记录是重要的一环,有了日志,咱们能够定位错误与异常,追踪应用运行状况,记录应用访问时间等等。在学习hello world
时就会使用System.out.println()
来输出内容,当涉及到复杂一点的日志输出,最好是引入成熟的日志框架,曾经log4j是流行的日志框架,如今已被它的继任者logback替代,它更快,更小,更灵活。在springboot的开发中,默认已经自带了logback,可直接使用。本文基本springboot+logback,结合在企业中的实践,对日志的输出及配置进行详细说明,具体有以下内容:html
如需看源码,本文示例工程地址:https://github.com/mianshenglee/my-example/tree/master/springboot-logback-demo
java
logback官网地址: http://logback.qos.ch
,从官网的介绍, logback是log4j框架的做者开发的新一代日志框架,是log4j的继任者,它更快,更小, 效率更高、可以适应各类运行环境,同时自然支持slf4j。 slf4j,即Simple Logging Facade For Java
,它是对各种日志框架的统一抽象,即定义了接口,具体使用哪一个日志 框架由运行时绑定实现。git
logback主要由三个模块构成,分别是 logback-core
, logback-classic
及 logback-access
,其中logback-core
是基础核心,另外两个均依赖它。 logback-classic
实现了简单日志门面 SLF4J
;而 logback-access
主要做为一个与 Servlet
容器交互的模块,如tomcat
或者 jetty
,提供与 HTTP
访问相关的一些功能。github
本章节将使用springboot+logback构建示例工程,并对logback基本配置进行描述。web
(1) 建立项目:经过 Spring Initializr 页面生成一个添加了web模块及lombok模块的 Spring Boot 项目。spring
(2)添加示例功能:tomcat
(3)添加日志输出springboot
@Slf4j
注解,这样可直接在此类中使用log
进行日志输出,避免本身使用LoggerFactory.getLogger
来新建。debug
,info
,warn
,error
等方法输出日志。如log.debug("get user by id:{}", id)
。注意:此处具体代码不列出(详细可看 示例源码)。
至此,示例工程构建完成,可正常运行工程,查看工程的依赖状况,能够发现,springboot已默认支持logback。以下:app
如上所示,默认状况下,springboot使用logback进行日志输出,输出日志为INFO级别,输出位置是控制台。启动示例工程,示例输出以下:框架
控制台日志输出的内容格式很清晰,分别是
yyyy-MM-dd HH:mm:ss.SSS
---
[]
)内在springboot在配置文件application.properties
中,能够设置日志相关的内容,以下:
关于日志的配置有不少,后面咱们主要使用自定义配置,所以不做详细说明,此处主要讲两个,日志级别控制及日志文件输出。
logging.leve.*=LEVEL
,其中*为包名或logger名,LEVEL有: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
。日志输出到文件,默认日志只输出到控制台,不写文件,能够配置logging.file.name
或logging.file.path
来指定日志输出文件。logging.file.name
设置文件, 会在项目的当前路径下生成此文件名的日志文件 。logging.path
设置目录,会在此目录下建立spring.log文件。 默认状况下,日志文件的大小达到10MB时会切分一次,产生新的日志文件
注意: 两者不能同时使用,如若同时使用,则只有logging.file生效
上面在properties文件中对日志进行基本的配置,但配置能力较弱,不够灵活。所以通常都使用自定义配置,经过xml文件对logback的日志输出进行配置。
在springboot应用中,对于logback的配置文件,默认状况下,配置文件放在src/main/resources
下,支持的配置文件名称以下:
Spring Boot官方推荐优先使用带有-spring的文件名配置(若有logback-spring.xml,则不会使用logback.xml) 。固然,若须要对配置文件名进行修改,或者但愿把配置文件放到其它目录下,能够经过logging.config属性指定自定义的名字,如logging.config=classpath:config/log-config.xml
,则使用resources/config
下的log-config.xml配置。
注,通常状况下,按默认规则(在resources目录下,使用logback-spring.xml)便可。另外有了这个配置文件后,前面提到的在properties文件中的logging配置则不须要了。
这里先直接给出配置文件的示例,后面章节将对配置文件内容进行详细说明。以下所示,配置文件主要功能是把日志按格式输出到控制台和文件中,而且文件按日志输出级别分别输出到独立文件,文件按时间滚动(天天一个日志文件,保留30天)。完整配置内容可见源码中的logback-spring.xml
文件。
<configuration scan="true" scanPeriod="1 seconds"> ...//略 <!-- 日志输出格式 --> <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5level [%15thread] [%40.40logger{40}] [%10method,%line] : %msg%n"/> <!-- 控制台输出日志 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>${log.pattern}</pattern> </layout> </appender> <!-- 文件输出日志, 滚动(时间/文件大小)输出策略 --> <appender name="DEBUGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 过滤器,只记录debug级别的日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>DEBUG</level> <OnMismatch>DENY</OnMismatch> <OnMatch>ACCEPT</OnMatch> </filter> <!-- 日志文件路径及文件名 --> <File>${log.path}/${logfile.prefix}-debug.log</File> <!-- 日志记录器的滚动策略,按日期记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志输出格式 --> <FileNamePattern>${log.path}/${logfile.prefix}-debug.%d{yyyy-MM-dd}.log</FileNamePattern> <!-- 日志保留天数 --> <maxHistory>30</maxHistory> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>${log.pattern}</Pattern> </layout> </appender> ...//略 <!-- 日志级别,不向上级传递日志内容,日志按appender-ref输出 --> <logger name="me.mason.demo.simplelogback.service.UserService" level="WARN" additivity="false"> <appender-ref ref="STDOUT"/> </logger> <!-- 日志输出 --> <root level="DEBUG"> <appender-ref ref="STDOUT"/> <appender-ref ref="DEBUGFILE"/> ...//略 </root> </configuration>
logback配置文件决定日志输出格式、日志输出位置、输出文件策略等内容,所以须要对logback配置文件的结构及相关元素内容进行了解。
配置文件整体来讲内容比较简单,主要三个元素:
这三个元素中,logger和root可视为同一类,都是日志组件,能够把root看成是特殊logger,是根,必须配置。logger配置解答从哪里获取日志,输出什么级别日志问题。appender配置是指出日志以什么格式输出,日志如何过滤,输出文件后如何处理的问题。另外,还有可选的property及contextName元素,分别变量和应用上下文名称。
根元素configuration有三个属性能够设置,以下:
scanPeriod="30 seconds"
每30秒检测一次。%contextName
来区别。
注意,定义的变量只能在配置文件的值中进行引用,不能在元素属性中引用。如配置文件中有不少属性是
class
,里面的内容只能写类的全路径,尽管类前缀都相同,但不能用变量替换。
此元素是主要配置项,表示以什么格式输出,日志如何过滤,输出文件后如何处理。appender结构以下:
appender
有两个属性 name
和class
;name
指定appender
名称,class
指定appender
的全限定名。appender 默认有如下几种:
ch.qos.logback.core.ConsoleAppender
ch.qos.logback.core.FileAppender
ch.qos.logback.core.rolling.RollingFileAppender
。实践过程当中,通常使用ConsoleAppender及RollingFileAppender便可,若须要自定义如把日志输出到消息队列,能够自定义实现 AppenderBase 接口。
ConsoleAppender比较简单,只须要使用layout元素,按日志输出格式便可,以下:
<!-- 控制台输出日志 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>${log.pattern}</pattern> </layout> </appender>
RollingFileAppender的配置相对多一点,包括File、filter,rollingPolicy,encoder和layout元素。其中filter能够过滤日志,所以,若须要把日志按级别输出到不一样的文件中,所以,定义多个RollingFileAppender(如对应DEBUG、INFO、WARN、ERROR),分别按日志级别过滤便可。下面分别进行说明:
配置文件输出的路径及文件名,通常把路径和文件名前缀定义到变量(property中),以下:
<!--日志文件前缀,即应用名称 --> <property name="logfile.prefix" value="logback-demo"/> <!--日志路径,可写相对路径,也可写绝对路径 --> <property name="log.path" value="logs"/> ...//略 <File>${log.path}/${logfile.prefix}-debug.log</File>
filter能够为appender
添加一个或多个过滤器,对日志进行过滤。过滤器有ThresholdFilter
和LevelFilter
,前者是临界值过滤器,过滤掉低于指定临界值的日志;后者是级别过滤器,根据日志级别进行过滤, 若是日志级别等于配置级别 ,过滤器会根据onMath
(符合过滤条件的操做) 和 onMismatch
(不符合过滤条件的操做)接收(ACCEPT)或拒绝(DENY)日志。 按前面需求,把日志按不一样级别分别输出到各自文件中,须要多个RollingFileAppender
元素,每一个元素下对应的level
是DEBUG,INFO,WARN和ERROR。
<!-- 过滤器,只记录debug级别的日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>DEBUG</level> <OnMismatch>DENY</OnMismatch> <OnMatch>ACCEPT</OnMatch> </filter>
此元素描述滚动策略,有TimeBasedRollingPolicy
、SizeAndTimeBasedRollingPolicy
、FixedWindowRollingPolicy
、SizeBasedTriggeringPolicy
。分别是基于时间滚动,基于大小和时间滚动,固定窗口滚动和大小触发,其中FixedWindowRollingPolicy
通常和SizeBasedTriggeringPolicy
同时使用。下面以TimeBasedRollingPolicy
为例,以天为单位输出日志,天天一个日志。
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日志输出格式 --> <FileNamePattern>${log.path}/${logfile.prefix}-debug.%d{yyyy-MM-dd}.log</FileNamePattern> <!-- 日志保留天数 --> <maxHistory>30</maxHistory> </rollingPolicy>
FileNamePattern
表示日志的路径及名称,此处是按日期输出,即%d{yyyy-MM-dd}
格式。maxHistory
表示日志最多保留天数,大于这些天数后,前面的日志会删除。
对于SizeAndTimeBasedRollingPolicy
,以下所示:
<!-- 按日期滚动 --> <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern> <!-- 文件大小最大是100M,保存60日,总大小最大为20G --> <maxFileSize>100MB</maxFileSize> <maxHistory>60</maxHistory> <totalSizeCap>20GB</totalSizeCap>
注意,%i
和%d
标识符都是强制性的。 每当日志文件在当前时间段结束以前达到文件最大值时,它将以递增的%d
索引存档,从0开始。
layout
元素较简单,只须要设置输出的格式便可。
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5level [%15thread] %40.40logger{40} [%10method,%line] : %msg%n"/> ...//略 <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>${log.pattern}</Pattern> </layout>
对于日志输出格式的控制,使用logback的保留字进行控制,保留字不少,建议查阅官网文档,下面对经常使用进行说明:
保留字 | 做用 |
---|---|
c{length} lo{length} logger{length} | 输出日志的logger名,可有一个整型参数,功能是缩短logger名,最右的点符号以后的类名始终显示,设置为0表示只输入logger最右边点符号以后的字符串。 |
C{length} class{length} | 输出执行记录请求的调用者的全限定名。参数与上面的同样。尽可能避免使用,除非执行速度不形成任何问题。 |
contextName cn | 输出上下文名称。 |
d{pattern} date{pattern} | 输出日志的打印日志,模式语法与java.text.SimpleDateFormat兼容。 |
L / line | 输出执行日志请求的行号。尽可能避免使用,除非执行速度不形成任何问题。 |
m / msg / message | 输出应用程序提供的信息。 |
M / method | 输出执行日志请求的方法名。尽可能避免使用,除非执行速度不形成任何问题。 |
n | 输出平台相关的分行符“n”或者“rn”。 |
p / le / level | 输出日志级别。 |
t / thread | 输出产生日志的线程名。 |
另外,格式还有一个对齐功能,经过在%
后面添加-
、.
及数字进行控制。符号-
是可选修饰符,表示是左对齐,接着是可选的最小宽度修饰符,用十进制数表示。若是字符小于最小宽度,则左填充或右填充,默认是左填充(即右对齐),填充符为空格。最大宽度修饰符,符号是点号"."后面加十进制数。若是字符大于最大宽度,则从前面截断。点符号“.”后面加减号“-”在加数字,表示从尾部截断。
例如:%-40.40logger{40} 表示按40字符输出logger名,左对齐,若小于40字符的则填充空格,超过40则从左边截断。
对于控制台,还能够控制颜色,如前面springboot的默认输出就有颜色,以下:
格式 | 描述 |
---|---|
%black | 黑色 |
%red | 红色 |
%green | 绿色 |
%yellow | 黄色 |
%blue | 蓝色 |
%magenta | 品红 |
%cyan | 青色 |
%white | 白色 |
%gray | 灰色 |
%highlight | 高亮色 |
%bold | 强化上面的颜色,例如%boldRed,%boldBlack |
logger
用来设置某一个类或者某个包的日志输出级别、以及关联appender
指定输出位置,有三个属性:
logger
会向上继承最近一个非空级别,级别以name区分,如x和x.y,x则是x.y的父级。logger 经过设置子节点appender-ref
来指定日志输出位置,能够设置多个appender-ref
。root
是一个特殊的logger
, 是全部logger
的根节点,元素名为root
,没有父级别,只有一个属性level
,默认为DEBUG 。
此处对某个具体的类进行配置输出进行设置,因为设置了WARN
级别,additivity
为true
,并且关联STDOUT
的appender,所以此类的>=WARN
的日志会输出到控制台。同时会把日志上传到父级,即root。若root也有配置STDOUT
的输出的话,会发现此日志在控制台输出两次。若additivity
为false
,则不会。
<!-- 日志级别,不向上级传递日志内容,日志按appender-ref输出 --> <logger name="me.mason.demo.simplelogback.service.UserService" level="WARN" additivity="true"> <appender-ref ref="STDOUT"/> </logger>
logger能够不配置,但root元素是必须配置的,须要告诉logback把日志输出到哪里。以下,只须要关联日志须要输出的appender
便可。前面已经有STDOUT
控制台及按日志级别设置了各个文件appender
,此处直接关联便可。
<root level="DEBUG"> <appender-ref ref="STDOUT"/> <appender-ref ref="DEBUGFILE"/> <appender-ref ref="INFOFILE"/> <appender-ref ref="WARNFILE"/> <appender-ref ref="ERRORFILE"/> </root>
通过以上的配置,汇总到logback-spring.xml
中,启动运行程序,便可看到控制台会按格式输出日志,同时会在应用根目录下建立logs
目录存放日志文件,且日志格式是按配置输出,以下:
本篇文章针对springboot应用开发中,如何使用logback,结合在企业中的实践,建立springboot示例,而后对logback的配置进行详细说明,实现按日志级别输出日志文件功能。但在实际开发中,还有很多须要改进的地方,包括多环境配置,日志输出效率问题,分布式系统请求ID追踪问题等,将在下篇文章进行讲解。
本文中使用的示例代码已放在github:https://github.com/mianshenglee/my-example/tree/master/springboot-logback-demo
,有兴趣的同窗能够pull代码,结合示例一块儿学习。
http://logback.qos.ch
http://www.logback.cn/
https://github.com/qos-ch/logback
https://juejin.im/post/5b51f85c5188251af91a7525
关注个人公众号,获取更多技术记录: