首页 > 其他分享 >logback和日志分离管理

logback和日志分离管理

时间:2024-10-22 15:09:40浏览次数:1  
标签:username 请求 logback 分离 日志 password Logback

目录

一、日志框架

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);

    @Override
    protected 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);

    @Override
    protected 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 {
    @Override
    protected 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	数据库连接失败

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

标签:username,请求,logback,分离,日志,password,Logback
From: https://www.cnblogs.com/20222320zcc/p/18491507

相关文章

  • 2024/10/21 日 日志 --》关于Mysql中的数据库连接池 简述笔记整理
    为了保证博客内容的连贯性,我决定把Maven内容单独开辟而不与JDBC相混。以下为数据库连接池的简单描述和笔记整理点击查看代码--数据库连接池--简介:--·数据库连接池是个容器,负责分配、管理数据库连接。--·它允许应用程序重复使用一个现有的数据库连接,而不是再重新建......
  • tocaf1的学习日志_两综述一文献
    基于深度学习的目标检测算法研究与应用综述张阳婷张阳婷,黄德启,王东伟,贺佳佳;新疆大学电气工程学院,乌鲁木齐830017摘要:总结基于深度学习的目标检测技术比较两阶段和单阶段网络架构的优缺点分析经典算法的改进策略及应用现状指出未来的研究方向前言:深度学习推动目标检测......
  • journalctl日志持久化
    默认情况下journalctl日志服务会把日志集中保存在单一结构化的日志文件/run/log默认情况下并不会持久化保存日志、每次重启后,之前的日志都会丢失。那我们如何配置journalctl日志持久化呢?日志持久化的主要优点在于,它可以帮助我们保存重启后的日志信息,以便在需要时进行查阅和分析......
  • spark整合logback
    在使用ApacheSpark和Scala进行开发时,合理的日志管理是确保应用程序可维护性和可调试性的关键。以下是一些最佳日志实践,帮助你有效地管理和优化Spark应用程序的日志记录。1.使用合适的日志库首选的日志库是SLF4J(SimpleLoggingFacadeforJava)和Logback。SLF4J提供了......
  • SpringBoot使用默认的日志logback(2)—自定义配置+控制台输出sql语句
    原文链接:SpringBoot使用默认的日志logback(2)—自定义配置+控制台输出sql语句–每天进步一点点上一篇文章中简单介绍了springboot通过系统配置的方式配置日志:SpringBoot使用默认的日志logback(1)—系统配置这篇文章简单介绍一下日志的自定义配置。1.自定义配置springboot......
  • logback.xml配置文件详解
    原文链接:logback.xml配置文件详解–每天进步一点点上一篇文章介绍了springboot配置自定义日志文件logback.xml今天这篇文章简单介绍一下logback.xml配置文件的一些含义。1.基本结构logback的基本结构如下图:configuration表示配置的根节点appender用来格式化日志输出......
  • 高等数学 7.2 可分离变量的微分方程
    讨论一阶微分方程\[y'=f(x,y)\tag{1}\]的一些解法。一阶微分方程有时也写成如下的对称形式:\[P(x,y)\mathrm{d}x+Q(x,y)\mathrm{d}y=0\tag{2}\]在方程\((2)\)中,变量\(x\)与\(y\)对称,它既可以看作是以\(x\)为自变量\(y\)为因变量的方程\[\cfrac{\mathr......
  • springboot基于java的OA管理系统(源码+文档+调试+vue+前后端分离)
    收藏关注不迷路!!......
  • 2024/10/19日 日志--》关于MySQL中 JDBC的API 详解的整理简述
    今天进一步学习了JDBC中的API,已经可以初步连接数据库了,接下来继续进行学习。点击查看代码--JDBCAPI详解--DirverManager--DriverManager(驱动管理类)作用:1.注册驱动2.获取数据库连接--1.注册驱动--Class.forName("com.mysql.jdbc.Driver");--·需要注意的是:My......
  • springboot vue前后端分离:母婴用品商城系统设计与实现计算机毕业设计作品和开题报告
      博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩,提供核心代码讲解,答辩指导。项目配有对应开......