springboot+logback日志输出企业实践(上)

时间:2021-12-20 08:05:43

一句话概括:在java应用开发过程中,日志输出与记录是重要一环,logback是当前的首选日志框架,本文将对springboot+logback的使用及在企业的实践进行详细描述。

1.引言

在java应用开发过程中,日志输出与记录是重要的一环,有了日志,我们可以定位错误与异常,追踪应用运行情况,记录应用访问时间等等。在学习hello world时就会使用System.out.println()来输出内容,当涉及到复杂一点的日志输出,最好是引入成熟的日志框架,曾经log4j是流行的日志框架,现在已被它的继任者logback替代,它更快,更小,更灵活。在springboot的开发中,默认已经自带了logback,可直接使用。本文基本springboot+logback,结合在企业中的实践,对日志的输出及配置进行详细说明,具体有如下内容:

  • logback简要介绍
  • 使用springboot+logback构建示例工程及配置描述
  • logback配置文件的详述及使用

如需看源码,本文示例工程地址https://github.com/mianshenglee/my-example/tree/master/springboot-logback-demo

2.logback简介

logback官网地址 http://logback.qos.ch,从官网的介绍, logback是log4j框架的作者开发的新一代日志框架,是log4j的继任者,它更快,更小, 效率更高、能够适应各种运行环境,同时天然支持slf4j。 slf4j,即Simple Logging Facade For Java,它是对各类日志框架的统一抽象,即定义了接口,具体使用哪个日志 框架由运行时绑定实现。

logback主要由三个模块构成,分别是logback-corelogback-classiclogback-access,其中logback-core是基础核心,另外两个均依赖它。 logback-classic实现了简单日志门面 SLF4J;而 logback-access 主要作为一个与 Servlet 容器交互的模块,如tomcat或者 jetty,提供与 HTTP 访问相关的一些功能。

3. springboot默认日志框架-logback

本章节将使用springboot+logback构建示例工程,并对logback基本配置进行描述。

3.1 springboot示例工程搭建

(1) 创建项目:通过Spring Initializr 页面生成一个添加了web模块及lombok模块的 Spring Boot 项目。

(2)添加示例功能:

  • 首先添加几个通用包:vo,controller,service,model,分别存放视图层模型,控制层,服务层,数据模型层等代码。
  • 针对用户增删改查功能,对应有数据模型User,UserController,UserService,统一返回视图模型ResponseResult。

(3)添加日志输出

  • 在UserService类中添加lombok提供的@Slf4j注解,这样可直接在此类中使用log进行日志输出,避免自己使用LoggerFactory.getLogger来新建。
  • 在对应的方法中使用debuginfowarnerror等方法输出日志。如log.debug("get user by id:{}", id)

注意:此处具体代码不列出(详细可看示例源码)。

至此,示例工程构建完成,可正常运行工程,查看工程的依赖情况,可以发现,springboot已默认支持logback。如下:

springboot+logback日志输出企业实践(上)

3.2 日志输出与基本配置

3.2.1 日志默认输出

如上所示,默认情况下,springboot使用logback进行日志输出,输出日志为INFO级别,输出位置是控制台。启动示例工程,示例输出如下:

springboot+logback日志输出企业实践(上)

控制台日志输出的内容格式很清晰,分别是

  • 时间日期:格式是yyyy-MM-dd HH:mm:ss.SSS
  • 日志级别:输出>=INFO级别的日志(ERROR, WARN, INFO)
  • 进程ID
  • 分隔符:---
  • 线程名:线程名在方括号([])内
  • logger名:类的名称
  • 日志内容

3.2.2 基本配置

在springboot在配置文件application.properties中,可以设置日志相关的内容,如下:

springboot+logback日志输出企业实践(上)

关于日志的配置有很多,后面我们主要使用自定义配置,因此不作详细说明,此处主要讲两个,日志级别控制及日志文件输出。

  • 日志级别控制,设置格式为logging.leve.*=LEVEL,其中*为包名或logger名,LEVEL有:TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF

  • 日志输出到文件,默认日志只输出到控制台,不写文件,可以配置logging.file.namelogging.file.path来指定日志输出文件。logging.file.name设置文件, 会在项目的当前路径下生成此文件名的日志文件 。logging.path设置目录,会在此目录下创建spring.log文件。 默认情况下,日志文件的大小达到10MB时会切分一次,产生新的日志文件

    注意: 二者不能同时使用,如若同时使用,则只有logging.file生效

3.3 自定义logback配置

上面在properties文件中对日志进行基本的配置,但配置能力较弱,不够灵活。因此一般都使用自定义配置,通过xml文件对logback的日志输出进行配置。

3.3.1 logback配置文件加载顺序

在springboot应用中,对于logback的配置文件,默认情况下,配置文件放在src/main/resources下,支持的配置文件名称如下:

  • logback-spring.xml
  • logback-spring.groovy
  • logback.xml
  • logback.groovy

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配置则不需要了。

3.3.2 logback配置文件示例

这里先直接给出配置文件的示例,后面章节将对配置文件内容进行详细说明。如下所示,配置文件主要功能是把日志按格式输出到控制台和文件中,并且文件按日志输出级别分别输出到独立文件,文件按时间滚动(每天一个日志文件,保留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>

4. logback配置文件详述

logback配置文件决定日志输出格式、日志输出位置、输出文件策略等内容,因此需要对logback配置文件的结构及相关元素内容进行了解。

4.1 配置文件结构

配置文件总体来说内容比较简单,主要三个元素:

springboot+logback日志输出企业实践(上)

这三个元素中,logger和root可视为同一类,都是日志组件,可以把root当作是特殊logger,是根,必须配置。logger配置解答从哪里获取日志,输出什么级别日志问题。appender配置是指出日志以什么格式输出,日志如何过滤,输出文件后如何处理的问题。另外,还有可选的property及contextName元素,分别变量和应用上下文名称。

4.2 根元素configuration

4.2.1 属性配置

根元素configuration有三个属性可以设置,如下:

  • debug:默认为false,若设置为true,则打印出logback内部日志信息

  • scan:默认值为true,若设置为true,配置文件如果发生改变,将会被重新加载。

  • scanPeriod:与scan配合使用,当scan为true时,此属性生效,默认的时间间隔为1分钟,设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。如可以设置为scanPeriod="30 seconds"每30秒检测一次。

4.2.2 定义上下文名称和变量

  • contextName元素,每一个日志组件(logger)都会关联到日志上下文,默认上下文名称是'default',用于标识应用,如果多个应用输出到同一个地方,就有必要使用%contextName来区别。
  • property元素,定义变量,有name和value属性,定义变量后,可以使“${name}”来使用变量。在配置中多个地方的值使用到相同的内容时,就有必要把相同内容设置变量,通过引用来设置。如示例工程中的日志文件名称前缀、日志路径、日志输出格式。

注意,定义的变量只能在配置文件的值中进行引用,不能在元素属性中引用。如配置文件中有很多属性是class,里面的内容只能写类的全路径,尽管类前缀都相同,但不能用变量替换。

4.3 日志输出组件appender

此元素是主要配置项,表示以什么格式输出,日志如何过滤,输出文件后如何处理。appender结构如下:

springboot+logback日志输出企业实践(上)

appender 有两个属性 nameclass;name指定appender名称,class指定appender的全限定名。appender 默认有以下几种:

  • ConsoleAppender:把日志添加到控制台,类名ch.qos.logback.core.ConsoleAppender
  • FileAppender:把日志添加到文件,类名ch.qos.logback.core.FileAppender
  • RollingFileAppender:滚动记录文件,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),分别按日志级别过滤即可。下面分别进行说明:

4.3.1 File配置

配置文件输出的路径及文件名,一般把路径和文件名前缀定义到变量(property中),如下:

<!--日志文件前缀,即应用名称 -->
<property name="logfile.prefix" value="logback-demo"/>
<!--日志路径,可写相对路径,也可写绝对路径 -->
<property name="log.path" value="logs"/>
...//略
<File>${log.path}/${logfile.prefix}-debug.log</File>

4.3.2 filter配置

filter可以为appender 添加一个或多个过滤器,对日志进行过滤。过滤器有ThresholdFilterLevelFilter,前者是临界值过滤器,过滤掉低于指定临界值的日志;后者是级别过滤器,根据日志级别进行过滤, 如果日志级别等于配置级别 ,过滤器会根据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>

4.3.3 rollingPolicy配置

此元素描述滚动策略,有TimeBasedRollingPolicySizeAndTimeBasedRollingPolicyFixedWindowRollingPolicySizeBasedTriggeringPolicy。分别是基于时间滚动,基于大小和时间滚动,固定窗口滚动和大小触发,其中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开始。

4.3.4 layout配置

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>

4.3.5 输出格式控制

对于日志输出格式的控制,使用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”或者“\r\n”。
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

4.4 日志组件logger及root

logger用来设置某一个类或者某个包的日志输出级别、以及关联appender指定输出位置,有三个属性:

  • name:指定的包名或者类名
  • level:输出日志级别,如果未设置此级别,那么当前logger会向上继承最近一个非空级别,级别以name区分,如x和x.y,x则是x.y的父级。
  • additivity:是否将日志向上级传递,默认为 true

logger 通过设置子节点appender-ref来指定日志输出位置,可以设置多个appender-refroot是一个特殊的logger, 是所有logger的根节点,元素名为root,没有父级别,只有一个属性level,默认为DEBUG 。

4.4.1 logger配置,

此处对某个具体的类进行配置输出进行设置,由于设置了WARN级别,additivitytrue,而且关联STDOUT的appender,因此此类的>=WARN的日志会输出到控制台。同时会把日志上传到父级,即root。若root也有配置STDOUT的输出的话,会发现此日志在控制台输出两次。若additivityfalse,则不会。

<!-- 日志级别,不向上级传递日志内容,日志按appender-ref输出 -->
<logger name="me.mason.demo.simplelogback.service.UserService" level="WARN" additivity="true">
<appender-ref ref="STDOUT"/>
</logger>

4.4.2 root配置

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日志输出企业实践(上)

5. 总结

本篇文章针对springboot应用开发中,如何使用logback,结合在企业中的实践,创建springboot示例,然后对logback的配置进行详细说明,实现按日志级别输出日志文件功能。但在实际开发中,还有不少需要改进的地方,包括多环境配置,日志输出效率问题,分布式系统请求ID追踪问题等,将在下篇文章进行讲解。

本文中使用的示例代码已放在githubhttps://github.com/mianshenglee/my-example/tree/master/springboot-logback-demo,有兴趣的同学可以pull代码,结合示例一起学习。

参考资料

往期文章

关注我的公众号,获取更多技术记录:

springboot+logback日志输出企业实践(上)

springboot+logback日志输出企业实践(上)的更多相关文章

  1. springboot&plus;logback日志输出企业实践(下)

    目录 1.引言 2. 输出 logback 状态数据 3. logback 异步输出日志 3.1 异步输出配置 3.2 异步输出原理 4. springboot 多环境下 logback 配置 5. ...

  2. vscode springboot logback 日志输出到不同文件

    参照了:https://blog.csdn.net/appleyk/article/details/78717388# 在src\main\resources中新建一个logback-boot.xml ...

  3. SpringBoot Logback 日志配置

    目录 前言 日志格式 日志输出 日志轮替 日志级别 日志分组 小结 前言 之前使用 SpringBoot 的时候,总是习惯于将日志框架切换为 Log4j2,可能是觉得比较靠谱,也可能年龄大了比较排斥新 ...

  4. SpringBoot Logback日志配置

    Logback的配置介绍: 1.Logger.appender及layout Logger作为日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型.级别. ...

  5. &lbrack;日志&rsqb; spring boot &plus; logback 日志输出配置

    一.输出日志到控制台 springboot有很多starter(参考starter)方便快速构建项目依赖组件,logback是springboot默认的日志组件,启动即可看到打印在控制台输出的info ...

  6. 8&period; springboot logback 日志整合

    在resources目录下,新建log/logback-spring.xml文件,内容如下: <?xml version="1.0" encoding="UTF-8 ...

  7. springboot logback日志的使用

    以下有两个使用,一个是简单使用,另一个是需要进行详细的配置再使用.首先给出源代码.可以直接使用 import org.slf4j.Logger;import org.slf4j.LoggerFacto ...

  8. Spring-boot logback日志处理

    1:在resources目录下面创建logback.xml配置文件 <?xml version="1.0"?> <configuration> <!- ...

  9. Logback日志输出到ELK

    用docker-compose本机部署elk docker-compose.yml version: "3" services: es01: image: docker.elast ...

随机推荐

  1. Shell练习

    1   在终端下运行程序,首先清屏,然后提示:“Input a file or directory name, please!”.从键盘输入一个字符串(如:xxx),如果该字符串是目录,则显示:“xx ...

  2. ant build utf-8

    使用Ant编译过程中,报error: unmappable character for encoding UTF8 最简单的方法是在Build.xml文件中,在所有出现Javac的地方,增加一个选项: ...

  3. Could not fetch https&colon;&sol;&sol;api&period;github&period;com&sol;repos&sol;RobinHerbots&sol;jquery

    使用 composer 安装YII2时, 如题所示提示, 原因是由于yii安装中, 需要有一些相关的认证[或许说是composer的认证], 如有如下提示 Could not fetch https: ...

  4. ASP&period;NET常用编程代码&lpar;一&rpar;

    1.为按钮添加确认对话框 Button1.Attributes.Add("onclick","return confirm(’确认?’)");button.at ...

  5. connect函数的用法

    无论流式套接字(如TCP)还是数据报(如UDP),均可以使用connect函数.对于流式套接字,使用connect函数后,建立固定地址的连接,之后可以使用send/rev函数进行数据收发.对于数据报, ...

  6. ShoneSharp语言&lpar;S&num;&rpar;的设计和使用介绍系列(3)— 修炼工具

    ShoneSharp语言(S#)的设计和使用介绍 系列(3)- 修炼工具 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. ...

  7. &lbrack;转&rsqb;CDH QuickStart VM基本使用

    https://blog.csdn.net/wiborgite/article/details/78731944 https://www.cnblogs.com/harrychinese/p/big_ ...

  8. 获奖感想与Java阶段性学习总结

    获奖感想 其实我早就知道有小黄衫这个东西,而且它就在我的目标清单里,不过没想到娄老师发的这么早.我想小黄衫代表着的是老师对我这一阶段来学习成果和努力的肯定,虽然Java学习中付出很多时间精力,现在也值 ...

  9. Windows系统配置

    1.常用设置 (1)设置虚拟内存 右击:计算机-属性-高级系统设置-高级选项卡-性能组框设置按钮-高级选项卡-虚拟内存组框更改按钮-按需求设置 (2)设置休眠文件 改变休眠文件大小:powercfg ...

  10. tomcat localhost

    启动tomcat后,登录本地localhost时,被要求输入用户名和密码,自己也从没有设置过啊,上网查找,原因如下: 机器装的oracle,它自带的httpserver的端口是8080,同时,tomc ...