1、单元测试

1.1 概述【理解】

JUnit是一个 Java 编程语言的单元测试工具。JUnit 是一个非常重要的测试工具

1.2 特点【理解】

  • JUnit是一个开放源代码的测试工具。
  • 提供注解来识别测试方法。
  • JUnit测试可以让你编写代码更快,并能提高质量。
  • JUnit优雅简洁。没那么复杂,花费时间较少。
  • JUnit在一个条中显示进度。如果运行良好则是绿色;如果运行失败,则变成红色。

    1.3 使用步骤【应用】

    junit单元测试.zip

    注意,zip文件需要解压得到jar包

  • 使用步骤

    1. 将junit的jar包导入到工程中 junit-4.9.jar(不会添加点击jar包详解
    2. 编写测试方法该测试方法必须是公共的无参数无返回值非静态方法
    3. 在测试方法上使用@Test注解标注该方法是一个测试方法
    4. 选中测试方法右键通过junit运行该方法
  • 代码示例

    1. public class JunitDemo1 {
    2. @Test
    3. public void add() {
    4. System.out.println(2 / 0);
    5. int a = 10;
    6. int b = 20;
    7. int sum = a + b;
    8. System.out.println(sum);
    9. }
    10. }

    1.4 相关注解【应用】

  • 注解说明 | 注解 | 含义 | | —- | —- | | @Test | 表示测试该方法 | | @Before | 在测试的方法前运行 | | @After | 在测试的方法后运行 |

  • 代码示例

    1. public class JunitDemo2 {
    2. @Before
    3. public void before() {
    4. // 在执行测试代码之前执行,一般用于初始化操作
    5. System.out.println("before");
    6. }
    7. @Test
    8. public void test() {
    9. // 要执行的测试代码
    10. System.out.println("test");
    11. }
    12. @After
    13. public void after() {
    14. // 在执行测试代码之后执行,一般用于释放资源
    15. System.out.println("after");
    16. }
    17. }

2、日志技术

2.1 概述

  • 概述
    程序中的日志可以用来记录程序在运行的时候点点滴滴。并可以进行永久存储。
  • 日志与输出语句的区别
    | | 输出语句 | 日志技术 | | —- | —- | —- | | 取消日志 | 需要修改代码,灵活性比较差 | 不需要修改代码,灵活性比较好 | | 输出位置 | 只能是控制台 | 可以将日志信息写入到文件或者数据库中 | | 多线程 | 和业务代码处于一个线程中 | 多线程方式记录日志,不影响业务代码的性能 |

2.2 体系结构

09_日志的体系结构.png

2.2.1 Apache基金会

Apache软件基金会(也就是Apache Software Foundation,简称为ASF),为支持开源软件项目而办的一个非盈利性组织。

2.2.2 Log4J

Log4j是Apache的一个开源项目。
通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件等位置。
我们也可以控制每一条日志的输出格式。
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

2.2.3 Logback的介绍

Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch。它当前分为下面几个模块:

  • logback-core:其它两个模块的基础模块   
  • logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
  • logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能

    2.3 Logback取代log4j的理由

    1、更快的实现:Logback的内核重写了,在一些关键执行路径上性能提升10倍以上。而且logback不仅性能提升了,初始化内存加载也更小了。 2、非常充分的测试:Logback经过了几年,数不清小时的测试。Logback的测试完全不同级别的。 3、Logback-classic非常自然实现了SLF4j:Logback-classic实现了SLF4j。在使用SLF4j中,你都感觉不到logback-classic。而且因为logback-classic非常自然地实现了slf4j , 所以切换到log4j或者其他,非常容易,只需要提供成另一个jar包就OK,根本不需要去动那些通过SLF4JAPI实现的代码。 4、非常充分的文档 官方网站有两百多页的文档。 5、Logback的定制性更加灵活,同时也是spring boot的内置日志框架 6、自动重新加载配置文件,当配置文件修改了,Logback-classic能自动重新加载配置文件。扫描过程快且安全,它并不需要另外创建一个扫描线程。这个技术充分保证了应用程序能跑得很欢在JEE环境里面。 等等很多~~

2.4 Logback 的配置介绍

1、Logger、appender及layout

  • Logger(记录器)作为日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。
  • Appender(附加器)主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、 MySQL、PostreSQL、 Oracle和其他数据库、 JMS和远程UNIX Syslog守护进程等。
  • Layout(布局) 负责把事件转换成字符串,格式化的日志信息的输出。

2、logger context
各个logger 都被关联到一个 LoggerContext,LoggerContext负责制造logger,也负责以树结构排列各logger。其他所有logger也通过org.slf4j.LoggerFactory 类的静态方法getLogger取得。 getLogger方法以 logger名称为参数。用同一名字调用LoggerFactory.getLogger 方法所得到的永远都是同一个logger对象的引用。

3、有效级别及级别的继承
Logger 可以被分配级别。级别包括:TRACE、DEBUG、INFO、WARN 和 ERROR,定义于ch.qos.logback.classic.Level类。如果 logger没有被分配级别,那么它将从有被分配级别的最近的祖先那里继承级别。root logger 默认级别是 DEBUG。

4、打印方法与基本的选择规则
打印方法决定记录请求的级别。
例如,如果 L 是一个 logger 实例,那么,语句 L.info(“..”)是一条级别为 INFO的记录语句。记录请求的级别在高于或等于其 logger 的有效级别时被称为被启用,否则,称为被禁用。
记录请求级别为 p,其 logger的有效级别为 q,只有则当 p>=q时,该请求才会被执行。该规则是 logback 的核心。日志级别为: TRACE < DEBUG < INFO < WARN < ERROR

2.5 Logback的 默认配置

  • 如果配置文件logback-test.xmllogback.xml都不存在,那么 logback 默认地会调用BasicConfigurator ,创建一个最小化配置。最小化配置由一个关联到根 logger 的ConsoleAppender 组成。
  • 输出用模式为**%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n **的 PatternLayoutEncoder 进行格式化。root logger 默认级别是 DEBUG

  • Logback的配置文件 Logback 配置文件的语法非常灵活。

    • 正因为灵活,所以无法用 DTD 或 XML schema 进行定义。
    • 尽管如此,可以这样描述配置文件的基本结构:以开头,后面有零个或多个元素,有零个或多个元素,有最多一个元素。
  • Logback默认配置的步骤

    1. 尝试在 classpath下查找文件logback-test.xml;
    2. 如果文件不存在,则查找文件logback.xml;
    3. 如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。

2.6 logback.xml 常用配置详解

  • logback.xml配置文件的基本结构可以描述为元素

包含零个或多个元素,
后跟零个或多个元素,
后跟最多一个元素(也可以没有)。
下图说明了这种基本结构:
image.png
logback日志系统详解.pdf

2.7 logback.xml 配置示例

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!-- 在此未说明属性为非必须的,那就表示属性必须设置 -->
  3. <!-- *****************最小配置文件结构介绍******************************* -->
  4. <!--
  5. <configuration>
  6. <appender></appender> //存在1或多个,功能指定记录输出目的地
  7. <root></root> //最多存在一个,根logger
  8. <logger><logger> //存在1或多个,普通logger
  9. </configuration>
  10. -->
  11. <!-- *************************各个标签详细介绍********************************** -->
  12. <!--
  13. configuration属性
  14. debug(非必须)属性:true表示输出logback内部的日志信息(不影响配置和级别) ;
  15. scan(非必须)属性:默认为false,true表示扫描配置文件的变化并自动重新配置,默认每隔1分钟扫描一次;
  16. scanPeriod(非必须)属性:搭配scan属性使用,设置扫描的间隔时间
  17. -->
  18. <configuration debug="true" scan="true" scanPeriod="1 seconds">
  19. <!-- 用于指定logger上下文名称,默认为default -->
  20. <contextName>logback</contextName>
  21. <!--
  22. 设置变量FILE_PATH,用于指定名为FILE的appender的目的文件存放的目录
  23. 定义日志文件的存储地址, 勿在 LogBack 的配置中使用相对路径
  24. -->
  25. <property name="FILE_PATH" value="D:/"></property>
  26. <!-- **********************配置TurboFilter类型的过滤器**********************************
  27. TurboFilter类型过滤器有三种:这里使用的是DuplicateMessageFilter
  28. 子标签<cacheSize>:表示内部缓存对旧消息引用的个数上限
  29. 子标签<allowedRepetitions>:表示允许消息出现的重复次数上限,超过次数上限的记录请求将被丢弃
  30. -->
  31. <!-- 使用自定义的TurboFilter -->
  32. <turboFilter class="logback.SampleTurboFilter">
  33. </turboFilter>
  34. <!-- 使用DuplicateTurboFilter -->
  35. <turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter">
  36. <allowedRepetitions>1</allowedRepetitions>
  37. <cacheSize>20</cacheSize>
  38. </turboFilter>
  39. <!-- ************************常用的Appender************************************** -->
  40. <!--
  41. <appender>标签包含2个属性:name、class
  42. name属性:指定appender名称;class属性:指定目的地类型 (比如ConsoleAppender、FileAppender等)
  43. class属性的值决定了<appender>标签包含的子标签的种类。
  44. -->
  45. <!-- 控制台日志, 控制台输出 -->
  46. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  47. <!--
  48. encoder:将事件转换为字符串,默认配置为PatternLayoutEncoder类
  49. encoder用于替代Layout,encoder扩展了Layout功能
  50. Layout功能:只负责把事件转换为字符串,但是不能指定何时将记录写入到指定目的地
  51. encoder功能:即负责把事件转换为字符串,也可以指定何时将记录写入到指定目的地
  52. -->
  53. <encoder>
  54. <!-- 指定输出格式
  55. %d{} :表示时间
  56. %thread:请求记录所在的线程名
  57. %-5level:用5位显示请求级别
  58. %logger{36}:输出logger名,{36}表示logger名最大占用的字符位数,{0}表示最简短logger名(不包含包名)。
  59. -->
  60. <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -%msg%n</pattern>
  61. </encoder>
  62. </appender>
  63. <!-- 该appender的功能是将记录信息以特定格式写到文件 -->
  64. <appender name="FILE" class="ch.qos.logback.core.FileAppender">
  65. <!-- $使用变量FILE_PATH的格式,类似Linux中使用的格式:${FILE_PATH} -->
  66. <file>${FILE_PATH}/file.log</file>
  67. <encoder>
  68. <!-- 指定输出格式 -->
  69. <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -%msg%n</pattern>
  70. </encoder>
  71. </appender>
  72. <!-- ***********************以最小窗体为指定的滚动规则的appender*****************************
  73. RollingFileAppender类型的appender中必须包含4个子标签:<file>、<rollingPolicy>、<triggerPolicy>、<encoder>
  74. <rollingPolicy>标签用于指定滚动规则,该标签有一个属性class:用于指定实现具体的滚动规则的类。
  75. <triggerPolicy>标签用于指定发生滚动的条件,该标签有一个属性class:用于指定具体滚动条件的类。
  76. <rollingPolicy>和<triggerPolicy>中具体包含哪些子标签是由class属性指定的类来决定的,因为不同的类有不同的参数,从而需要不同的标签来传参
  77. -->
  78. <!-- 该appender的功能是将记录信息以特定格式写到文件,当文件达到20MB时,创建以特定规则新的文件,之后的记录会写到新文件-->
  79. <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
  80. <!-- 在第一次触发滚动之前记录将会写到该文件中 -->
  81. <file>${FILE_PATH}/rolling.log</file>
  82. <!--
  83. 前提条件:class的值为FixedWindowRollingPolicy,表示以最小窗体为指定的滚动规则
  84. RollingPolicy标签必须子标签:<fileNamePattern>、<minIndex>、<maxIndex>
  85. <fileNamePattern>:表示滚动条件达到后,创建文件名的规则,其中"%i"代表数字1~5。第一次触发条件,创建文件rolling1.log,并且记录开始写到这个文件中
  86. <minIndex>与<maxIndex>共同决定了文件的个数
  87. -->
  88. <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
  89. <!--日志文件输出的文件名-->
  90. <fileNamePattern>${FILE_PATH}/rolling%i.log</fileNamePattern>
  91. <minIndex>1</minIndex>
  92. <maxIndex>5</maxIndex>
  93. </rollingPolicy>
  94. <!--
  95. <triggeringPolicy>功能:用于限制文件大小
  96. 前提条件:class的值为SizeBasedTriggeringPolicy,表示以文件大小为触发条件
  97. 只有一个子标签<maxFileSize>用于指定触发条件
  98. -->
  99. <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
  100. <!--日志文件最大的大小-->
  101. <maxFileSize>20MB</maxFileSize>
  102. </triggeringPolicy>
  103. <!--格式化输出-->
  104. <encoder>
  105. <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -%msg%n</pattern>
  106. </encoder>
  107. </appender>
  108. <!-- *****************************根据时间滚动 为滚动规则和条件的appender(最常用)***********************-->
  109. <!--
  110. 该appender的功能:将记录信息以特定格式写到文件,当文件达到20MB时,创建以时间为特定规则新的 文件,之后的记录会写到新文件,
  111. 文件个数最多维持10个,文件达到10个 后删除旧的文件
  112. -->
  113. <appender name="time_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
  114. <!-- TimeBasedRollingPolicy实现了RollingPolicy与TriggeringPolicy,
  115. 因此只需要<rollingPolicy>标签,不需要<TriggeringPolicy>标签
  116. <rollingPolicy>标签有两个子标签:<fileNamePattern>、<maxHistory>
  117. <fileNamePattern>:用于指定文件名命名规则
  118. <maxHistory>:保留文件的个数,超过了就删除创建时间最久的文件
  119. -->
  120. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  121. <!-- 文件名 -->
  122. <fileNamePattern>${FILE_PATH}/java_log/test%d{yyyy-MM-dd_HH-mm}.log</fileNamePattern>
  123. <maxHistory>10</maxHistory>
  124. </rollingPolicy>
  125. <encoder>
  126. <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -%msg%n</pattern>
  127. </encoder>
  128. </appender>
  129. <!-- ***********************常规级别过滤器的使用****************************************
  130. 本配置功能:过滤并接受请求级别为debug的请求,对于其他级别请求一律丢弃。
  131. -->
  132. <appender name="level_console" class="ch.qos.logback.core.ConsoleAppender">
  133. <filter class="ch.qos.logback.classic.filter.LevelFilter">
  134. <level>debug</level>
  135. <onMatch>ACCEPT</onMatch>
  136. <onMismatch>DENY</onMismatch>
  137. </filter>
  138. <encoder>
  139. <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -%msg%n</pattern>
  140. </encoder>
  141. </appender>
  142. <!-- ***********************常规临界值滤器的使用****************************************
  143. 本配置功能:请求级别高于或等于info的请求响应NEUTRAL(进入下一个环节),低于info的级别请求响应DENY(表示丢弃)。
  144. -->
  145. <appender name="threshold_console" class="ch.qos.logback.core.ConsoleAppender">
  146. <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  147. <level>info</level>
  148. </filter>
  149. <encoder>
  150. <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -%msg%n</pattern>
  151. </encoder>
  152. </appender>
  153. <!-- appender的目的地为mysql数据库 -->
  154. <appender name="jdbc" class="ch.qos.logback.classic.db.DBAppender">
  155. <!-- 这里只使用jdbc中的DriverManager获得连接,不使用任何数据源 -->
  156. <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
  157. <driverClass>com.mysql.jdbc.Driver</driverClass>
  158. <url>jdbc:mysql://localhost:3306/logback?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=UTC</url>
  159. <user>root</user>
  160. <password>root</password>
  161. </connectionSource>
  162. </appender>
  163. <!-- ******以下DBAppender类型的appender的目的地为mysql数据库******** -->
  164. <appender name="c3p0_datasource" class="ch.qos.logback.classic.db.DBAppender">
  165. <!-- 这里使用DataSource获得连接-->
  166. <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
  167. <!-- 实现DataSource的数据库连接池有很多,比如DBCP、c3p0、Druid等,这里使用的是c3p0
  168. -->
  169. <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
  170. <user>root</user>
  171. <password>root</password>
  172. <driverClass>com.mysql.jdbc.Driver</driverClass>
  173. <jdbcUrl>jdbc:mysql://localhost:3306/logback?useUnicode=true&amp;characterEncoding=utf8</jdbcUrl>
  174. </dataSource>
  175. </connectionSource>
  176. </appender>
  177. <appender name="Druid_datasource" class="ch.qos.logback.classic.db.DBAppender">
  178. <!-- 这里使用DataSource获得连接-->
  179. <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
  180. <!-- 实现DataSource的数据库连接池有很多,比如DBCP、c3p0、Druid等,这里使用的是Druid-->
  181. <dataSource class="com.alibaba.druid.pool.DruidDataSource">
  182. <username>root</username>
  183. <password>root</password>
  184. <driverClassName>com.mysql.jdbc.Driver</driverClassName>
  185. <url>jdbc:mysql://localhost:3306/logback?useUnicode=true&amp;characterEncoding=utf8</url>
  186. </dataSource>
  187. </connectionSource>
  188. </appender>
  189. <appender name="dbcp_datasource" class="ch.qos.logback.classic.db.DBAppender">
  190. <!-- 这里使用DataSource获得连接-->
  191. <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
  192. <!-- 实现DataSource的数据库连接池有很多,比如DBCP、c3p0、Druid等,这里使用的是dbcp-->
  193. <dataSource class="org.apache.commons.dbcp.BasicDataSource">
  194. <username>root</username>
  195. <password>root</password>
  196. <driverClassName>com.mysql.jdbc.Driver</driverClassName>
  197. <url>jdbc:mysql://localhost:3306/logback?useUnicode=true&amp;characterEncoding=utf8</url>
  198. </dataSource>
  199. </connectionSource>
  200. </appender>
  201. <!-- level属性:指定根logger的分配级别 -->
  202. <root level="debug">
  203. <!-- ref属性:指定根logger关联的appender -->
  204. <appender-ref ref="STDOUT"></appender-ref>
  205. </root>
  206. <!-- name:指定logger名称;level:指定logger的分配级别;additivity(非必须,默认为true):设置appender叠加性 -->
  207. <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
  208. <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
  209. <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
  210. <logger name="org.hibernate.SQL" level="DEBUG" />
  211. <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
  212. <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
  213. <!--myibatis log configure-->
  214. <logger name="com.apache.ibatis" level="TRACE"/>
  215. <logger name="java.sql.Connection" level="DEBUG"/>
  216. <logger name="java.sql.Statement" level="DEBUG"/>
  217. <logger name="java.sql.PreparedStatement" level="DEBUG"/>
  218. <logger name="demo" level="debug" additivity="false">
  219. <appender-ref ref="FILE"/>
  220. </logger>
  221. <logger name="demo2" level="debug">
  222. <appender-ref ref="rollingFile"/>
  223. </logger>
  224. <logger name="demo3" level="debug">
  225. <appender-ref ref="time_file"/>
  226. </logger>
  227. <logger name="demo4" level="debug" additivity="false">
  228. <appender-ref ref="level_console"/>
  229. </logger>
  230. <logger name="demo5" level="debug" additivity="false">
  231. <appender-ref ref="threshold_console"/>
  232. </logger>
  233. <logger name="demo6" level="debug" additivity="false">
  234. <appender-ref ref="jdbc"/>
  235. </logger>
  236. <logger name="demo7" level="debug" additivity="false">
  237. <appender-ref ref="c3p0_datasource"/>
  238. </logger>
  239. <logger name="demo8" level="debug" additivity="false">
  240. <appender-ref ref="Druid_datasource"/>
  241. </logger>
  242. <logger name="demo9" level="debug" additivity="false">
  243. <appender-ref ref="dbcp_datasource"/>
  244. </logger>
  245. </configuration>

2.8 logback.xml 入门案例【应用】

<!-- ************************常用的Appender************************************** -->
<!-- 
    <appender>标签包含2个属性:name、class
    name属性:指定appender名称;class属性:指定目的地类型 (比如ConsoleAppender、FileAppender等)
    class属性的值决定了<appender>标签包含的子标签的种类。
-->
<!--
    本appender的功能是将记录信息以特定格式写到控制台
    CONSOLE : 表示当前日志信息是可以输送到控制台的。
-->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
    <!--encoder:将事件转换为字符串
        默认配置为PatternLayoutEncoder类 
        encoder用于替代Layout,encoder扩展了Layout功能
        Layout功能:只负责把事件转换为字符串,但是不能指定何时将记录写入到指定目的地
        encoder功能:即负责把事件转换为字符串,也可以指定何时将记录写入到指定目的地
     -->
    <encoder>
        <!-- 指定输出格式
            %d{} :表示时间
            %thread:请求记录所在的线程名
            %-5level:用5位显示请求级别
            %logger{36}:输出logger名,{36}表示logger名最大占用的字符位数,{0}表示最简短logger名(不包含包名)。
            %msg 日志文本
            %n换行
         -->
        <pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread])  %boldGreen(%logger{15}) -%msg %n</pattern>
    </encoder>
</appender>

<!-- 
name:指定logger名称;
level:指定logger的分配级别;
additivity(非必须,默认为true):
设置appender叠加性 -->
<!--root设置全局的log level-->
<root name="com.lhl" level="DEBUG" additivity="false">
    <appender-ref ref="Console" />
</root>


- 使用步骤
   - ① 导入logback的相关jar包
      - 在模块下新建lib文件夹与src同级
      - 将jar包复制进lib文件夹下
      - 添加到依赖库中,`Add as  library`
      - ![image.png](https://cdn.nlark.com/yuque/0/2022/png/26775128/1650506945804-92151e4e-0ed9-48c7-b9c5-7622009abc06.png#clientId=u80b86e1f-8b87-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=197&id=ucf297028&margin=%5Bobject%20Object%5D&name=image.png&originHeight=222&originWidth=510&originalType=binary&ratio=1&rotation=0&showTitle=false&size=10381&status=done&style=none&taskId=uf7ba5e2c-c3a5-4138-afe5-0df371c87d9&title=&width=453.3333333333333)
   - ② 编写logback配置文件
   - ③ 在代码中获取日志的对象
   - ④ 按照级别设置记录日志信息
- 代码示例
```java
// 测试类
public class Test01 {

    //获取日志的对象
    private static  final Logger LOGGER = LoggerFactory.getLogger(Test01.class);

    public static void main(String[] args) {
        //1.导入jar包
        //2.编写配置文件
        //3.在代码中获取日志的对象
        //4.按照日志级别设置日志信息
        LOGGER.debug("debug级别的日志");
        LOGGER.info("info级别的日志");
        LOGGER.warn("warn级别的日志");
        LOGGER.error("error级别的日志");
    }
}

运行测试文件
image.png