logback和日志分离管理

news/2024/10/22 15:19:13

目录
  • 一、日志框架
    • 1. 什么是日志框架?
    • 2. 日志框架的作用
    • 3. 常见的日志框架
      • 3.1. Log4j
      • 3.2. Logback
      • 3.3. java.util.logging (JUL)
      • 3.4. SLF4J(日志门面)(Simple Logging Facade for Java)
    • 4.常见的日志级别
    • 5.讲讲logback
      • 5.1. logback-core
      • 5.2. logback-classic
      • 5.3. logback-access
      • 5.4.学到此处的疑惑?
    • 6.举个完整示例
      • 6.1. 项目结构 (登录为例)
      • 6.2. Maven 依赖
      • 6.3. Logback 配置文件
      • 6.4.Logback 的 JDBCAppender

一、日志框架

1. 什么是日志框架?

日志框架 是一种软件组件,负责记录应用程序在运行时生成的日志信息。日志信息通常包括错误、警告、调试信息和其他重要的运行状态,帮助开发者和运维人员监控和调试应用。

2. 日志框架的作用

  • 记录运行信息:捕获程序执行中的重要事件和状态信息,便于追踪问题和性能瓶颈。
  • 故障排查:当应用发生错误时,日志记录提供了上下文信息,有助于快速定位和解决问题。
  • 性能监控:记录性能指标,帮助分析系统的运行效率。
  • 审计和合规:某些应用需要记录操作历史以满足安全审计和合规要求。
  • 可追溯性:通过日志,用户可以追溯到具体的操作和系统状态。

3. 常见的日志框架

3.1. Log4j

最早的 Java 日志框架之一,提供了强大的日志记录功能。
支持多种输出目标(控制台、文件、数据库等),灵活的配置方式,但在性能上相对较低。
目前有 Log4j 1 和 Log4j 2,后者在性能和功能上进行了显著改进。

3.2. Logback

由 Log4j 的创始人开发,是 SLF4J 的原生实现,性能优越(比log4j强)。
支持异步日志记录、自动重载配置文件、灵活的输出格式等。

3.3. java.util.logging (JUL)

Java 官方自带的日志框架,简单易用,但功能和灵活性相对较弱。
默认与 JDK 一起提供,不需要额外依赖,但通常被其他日志框架替代。
java.util.logging 适合小型项目和快速集成,但在复杂应用中可能无法满足需求。

3.4. SLF4J(日志门面)(Simple Logging Facade for Java)

SLF4J 是一个日志门面,提供了统一的日志 API,允许开发者在不同的日志框架之间切换。可以与多种日志框架(如 Logback、Log4j)兼容使用,提供简洁的 API,易于使用。将依赖从具体日志框架转移到统一接口,简化了依赖管理。不处理日志,只是一层抽象,实际的日志处理依赖于其他框架。

4.常见的日志级别

  • TRACE:最细粒度的信息,通常用于追踪问题。
  • DEBUG:调试信息,通常在开发和测试时使用。
  • INFO:正常运行的信息。
  • WARN:警告信息,表示可能出现的问题。
  • ERROR:错误信息,表示发生了错误。
  • FATAL:严重错误,表示应用程序无法继续运行。

5.讲讲logback

Logback 主要由三个核心模块构成:
logback-core:核心模块,提供基本的日志记录功能。
logback-classic:经典模块,提供 SLF4J(Simple Logging Facade for Java)实现,支持多种日志级别和输出格式。
logback-access:用于 Servlet 环境中的访问日志记录。

5.1. logback-core

logback-core 是 Logback 的基础模块,提供了日志记录的核心功能和通用的 API。它包含了 Logback 的一些基本组件,比如 Appender、Layout 和 Filter。它定义了基本的日志记录行为。提供了其他模块(如 logback-classic 和 logback-access)所需的共享功能。
一般情况下,不需要直接与 logback-core 进行交互,因为它是 Logback 其他模块的基础。

5.2. logback-classic

logback-classic 是 Logback 的经典模块,它实现了 SLF4J的接口。这个模块是最常用的,通常用于大多数 Java 应用程序。
提供对 SLF4J API 的实现,支持多种日志级别(如 TRACE、DEBUG、INFO、WARN、ERROR、FATAL)。
允许配置日志输出到不同的目标(控制台、文件等)。
支持日志格式化和过滤器。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class MyApp {private static final Logger logger = LoggerFactory.getLogger(MyApp.class);public static void main(String[] args) {logger.info("应用程序启动");try {int result = 10 / 0;} catch (Exception e) {logger.error("发生错误:{}", e.getMessage());}logger.info("应用程序结束");}

5.3. logback-access

logback-access 是 Logback 的一个扩展模块,专门用于 Servlet 环境中的访问日志记录。它允许你记录 HTTP 请求和响应的相关信息。
提供一个 Servlet 过滤器,可以捕获和记录请求信息。
允许配置请求和响应日志的输出格式。

public class LoginServlet extends HttpServlet {private static final Logger logger = LoggerFactory.getLogger(LoginServlet.class);@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");// 假设的用户验证逻辑boolean isAuthenticated = authenticateUser(username, password);if (isAuthenticated) {logger.info("用户 {} 登录成功", username);response.getWriter().write("登录成功");} else {logger.warn("用户 {} 登录失败,密码错误", username);response.getWriter().write("登录失败");}}private boolean authenticateUser(String username, String password) {return "admin".equals(username) && "password".equals(password);}

5.4.学到此处的疑惑?

上述在http交互中,好像直接使用logback classic也可以,为什么还多此一举多个logback access?或者说logback access优越在哪里?
举个例子作比较:
1.假设我们在处理用户登录时,使用 Logback Classic 记录日志:

public class LoginServlet extends HttpServlet {private static final Logger logger = LoggerFactory.getLogger(LoginServlet.class);@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");boolean isAuthenticated = authenticateUser(username, password);if (!isAuthenticated) {// 手动记录登录失败的信息logger.warn("登录失败,用户名: {}, 请求方法: {}, 请求路径: {}", username, request.getMethod(), request.getRequestURI());            ---注意这里response.getWriter().write("登录失败");} else {response.getWriter().write("登录成功");}}private boolean authenticateUser(String username, String password) {return "admin".equals(username) && "password".equals(password);}
}

输出结果:

2024-10-21 10:00:00 WARN  [http-nio-8080-exec-1] LoginServlet [LoginServlet.java:25] 
登录失败,用户名: user, 请求方法: POST, 请求路径: /login

2.在同样的登录失败场景中,使用 Logback Access:

public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");boolean isAuthenticated = authenticateUser(username, password);if (!isAuthenticated) {// 使用 Logback Access 自动记录 HTTP 请求信息LogbackAccessFilter filter = new LogbackAccessFilter();filter.logAccess(request, response, "登录失败,用户名: " + username);     ---和上面比一下response.getWriter().write("登录失败");} else {response.getWriter().write("登录成功");}}private boolean authenticateUser(String username, String password) {return "admin".equals(username) && "password".equals(password);}
}

输出结果

2024-10-21 10:00:00 WARN  [http-nio-8080-exec-1] AccessLogger [LogbackAccess.java:123] 
请求方法: POST, 请求路径: /login, 用户名: user, 状态码: 401, 响应时间: 150ms

3.比较分析

输出内容:
Logback Classic:记录了用户名、请求方法和请求路径。这些信息帮助理解发生了什么,但缺乏对请求状态的详细描述。
Logback Access:自动记录请求方法、请求路径、状态码和响应时间等多种信息,使得分析请求情况更加全面。

代码简洁性:
Logback Classic:需要手动提取和记录请求相关的信息,代码较冗长且容易出错。
Logback Access:自动处理 HTTP 请求的记录,代码更简洁,专注于业务逻辑。

上下文信息:
Logback Classic:需要自己管理所有的请求上下文信息,容易遗漏关键信息。
Logback Access:全面捕获 HTTP 请求的上下文信息。

性能优化:
Logback Classic:未针对 HTTP 请求进行优化,记录过程相对较慢。
Logback Access:经过优化,专门为 HTTP 请求设计,可以更高效地记录访问信息。

6.举个完整示例

6.1. 项目结构 (登录为例)

my-login-app
│
├── src
│   ├── main
│   │   ├── java
│   │   │   ├── LoginServlet.java
│   │   │   └── MyApp.java
│   │   └── resources
│   │       └── logback.xml
│   └── webapp
│       └── index.html
└── pom.xml

6.2. Maven 依赖

<dependencies><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.30</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency>
</dependencies>

6.3. Logback 配置文件

在 src/main/resources 目录下创建 logback.xml 文件,内容如下:

<configuration><!-- 配置 ConsoleAppender,用于输出日志到控制台 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} [%file:%line] - %msg%n</pattern></encoder></appender><!-- 配置 AccessAppender,用于处理 HTTP 访问日志 --><appender name="ACCESS" class="ch.qos.logback.access.Appender"><encoder><pattern>%h %l %u %t "%r" %s %b %D</pattern> <!-- 自定义输出格式 --></encoder></appender><!-- 配置日志级别 --><root level="INFO"><appender-ref ref="STDOUT" />  <!-- 将控制台输出连接到根日志 --></root><logger name="ch.qos.logback.access" level="DEBUG"><appender-ref ref="ACCESS" />  <!-- 将访问日志连接到特定日志级别 --></logger></configuration>

6.4.Logback 的 JDBCAppender

将日志输出到数据库中
1.先数据库建表:

CREATE TABLE logs (id INT AUTO_INCREMENT PRIMARY KEY,timestamp TIMESTAMP NOT NULL,level VARCHAR(10) NOT NULL,thread VARCHAR(50),logger VARCHAR(100),message TEXT
);

2.配置xml:

<configuration><!-- JDBC Appender --><appender name="JDBC" class="ch.qos.logback.classic.db.JDBCAppender"><connectionSource><driverClass>com.mysql.cj.jdbc.Driver</driverClass>  <url>jdbc:mysql://localhost:3306/database</url>  <user>username</user>  <password>password</password>  </connectionSource><encoder><pattern>%date %level [%thread] %logger{10} %msg%n</pattern> </encoder></appender><root level="debug"><appender-ref ref="JDBC" />  <!-- 引用 JDBC Appender --></root>
</configuration>

3.数据存储结果:

id	timestamp	level	thread	logger	message
1	2024-10-22 10:00:00	INFO	main	com.example.LoginServlet	用户 admin 登录成功
2	2024-10-22 10:01:00	WARN	main	com.example.LoginServlet	登录失败,用户名: user
3	2024-10-22 10:02:00	ERROR	main	com.example.LoginServlet	数据库连接失败

已经集成了与数据库操作,很方便

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/74654.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Amazon Q Developer 实践:零基础创建贪吃蛇游戏

本文探讨了如何使用 Amazon Q Developer 根据结构化的提示词,直接生成一个贪吃蛇游戏原型,并剖析了其背后人工智能的思考和迭代完善过程,展示了人工智能能快速进行游戏原型创作的巨大潜力。 原文出处来自作者于 2024 年 9 月在 community.aws 发表的技术文章: “From Conce…

GBU608-ASEMI室内空调机专用GBU608

GBU608-ASEMI室内空调机专用GBU608编辑:ll GBU608-ASEMI室内空调机专用GBU608 型号:GBU608 品牌:ASEMI 封装:GBU-4 安装方式:直插 批号:2024+ 现货:50000+ 正向电流(Id):6A 反向耐压(VRRM):800V 正向浪涌电流:175A 正向电压(VF):1.10V 引脚数量:4 芯片个数:…

4、建造者模式

建造者模式的主要思想是让建造者关注产出,不关心过程

NAS教程丨如何通过DDNS实现SMB服务的远程访问?

适用版本:所有版本适用机型:所有 TNAS 型号操作步骤:一、SSH登录TNAS设备1. 通过SSH登录TNAS设备。二、编辑SMB配置文件1、在SSH会话中,输入命令 vi /etc/samba/smb-extend.conf 并按回车键打开SMB配置文件。2、按 i 键进入编辑模式。3、使用键盘的方向键将光标移动到文件的…

PHP在区块链开发中的应用

### PHP在区块链开发中的应用 PHP在区块链开发中主要应用于构建前端用户界面、后端API服务、与区块链网络交互等方面。 其中,PHP通过后端API服务与区块链网络的交互尤为关键,它允许开发者创建和管理区块链数据、执行智能合约等功能,为区块链应用提供了强大的后端支持。 ####…

大数据实时链路备战——数据双流高保真压测

作者:京东零售 京东零售 一、大数据双流建设 1.1 数据双流大数据时代,越来越多的业务依赖实时数据用于决策,比如促销调整,点击率预估、广告分佣等。为了保障业务的顺利开展,也为了保证整体大数据链路的高可用性,越来越多的0级系统建设双流,以保证日常及大促期间数据流的…

Lightroom和Photoshop在图片编辑中有什么区别

Lightroom和Photoshop在图片编辑中的区别:1.应用场景不同;2.功能特性差异;3.工作流程差异;4.调整方式的不同;5.文件格式支持和输出差异。本文深入比较了Adobe Lightroom和Photoshop这两款常用的图片编辑软件。从应用场景、功能特性、工作流程等多个方面探讨它们的区别,帮…

快到2025年了,OCP的认证考试费用会降价吗?

从事数据库工作的都知道,OCP证书是非常受欢迎的一个认证,是从事数据库管理员的首选证书之一,所以想考OCP证书的也非常多,关于OCP考试的费用问题,也一直是大家关注的焦点。其实,考OCP证书总的费用是根据Oracle官方的考试价格再加上培训机构的培训费用、培训记录、教材费用…