跳转到内容

Spring Boot日志

来自代码酷

Spring Boot日志[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

Spring Boot日志是Spring框架中用于记录应用程序运行时信息的重要组件。它基于SLF4J(Simple Logging Facade for Java)和Logback(默认实现),提供了统一的日志接口和灵活的配置选项。日志系统帮助开发者调试代码、监控应用状态并追踪异常行为。

Spring Boot通过自动配置简化了日志系统的设置,开发者只需关注业务逻辑而无需手动初始化日志框架。日志级别(如DEBUG、INFO、WARN、ERROR)和输出格式均可通过配置文件调整。

核心概念[编辑 | 编辑源代码]

日志级别[编辑 | 编辑源代码]

Spring Boot支持以下标准日志级别(从低到高):

  • TRACE - 最详细的跟踪信息
  • DEBUG - 调试信息
  • INFO - 常规运行信息(默认级别)
  • WARN - 警告事件
  • ERROR - 错误事件
  • FATAL - 严重错误导致应用终止

日志框架结构[编辑 | 编辑源代码]

graph TD A[Application] -->|调用| B[SLF4J API] B -->|绑定| C[Logback] B -->|绑定| D[Log4j2] B -->|绑定| E[JUL]

基础配置[编辑 | 编辑源代码]

默认日志输出[编辑 | 编辑源代码]

Spring Boot自动配置的日志会输出到控制台,格式如下:

2023-05-20 14:30:45.123  INFO 12345 --- [main] com.example.MyApp : Starting MyApp

修改日志级别[编辑 | 编辑源代码]

application.properties中配置:

# 设置root日志级别
logging.level.root=WARN

# 设置特定包日志级别
logging.level.com.example=DEBUG

代码示例[编辑 | 编辑源代码]

基本日志记录[编辑 | 编辑源代码]

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LogController {
    // 获取Logger实例
    private static final Logger logger = LoggerFactory.getLogger(LogController.class);

    @GetMapping("/test")
    public String testLogging() {
        logger.trace("This is TRACE message");
        logger.debug("This is DEBUG message");
        logger.info("This is INFO message");
        logger.warn("This is WARN message");
        logger.error("This is ERROR message");
        return "Check console for logs";
    }
}

输出示例(当logging.level.com.example=DEBUG时):

2023-05-20 14:35:22.456 DEBUG 12345 --- [nio-8080-exec-1] com.example.LogController : This is DEBUG message
2023-05-20 14:35:22.456 INFO 12345 --- [nio-8080-exec-1] com.example.LogController : This is INFO message
2023-05-20 14:35:22.456 WARN 12345 --- [nio-8080-exec-1] com.example.LogController : This is WARN message
2023-05-20 14:35:22.456 ERROR 12345 --- [nio-8080-exec-1] com.example.LogController : This is ERROR message

高级配置[编辑 | 编辑源代码]

自定义日志格式[编辑 | 编辑源代码]

application.properties中:

# 控制台日志模式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n

# 文件日志模式
logging.pattern.file=%d{yyyy-MM-dd} [%thread] %-5level %logger{36} - %msg%n

日志文件输出[编辑 | 编辑源代码]

# 输出到指定文件
logging.file.name=app.log

# 或按大小轮转(Logback特性)
logging.logback.rollingpolicy.max-file-size=10MB
logging.logback.rollingpolicy.max-history=7

实际应用案例[编辑 | 编辑源代码]

异常监控[编辑 | 编辑源代码]

@RestController
public class OrderController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @PostMapping("/orders")
    public ResponseEntity<?> createOrder(@RequestBody Order order) {
        try {
            // 业务逻辑
            return ResponseEntity.ok("Order created");
        } catch (Exception e) {
            logger.error("Failed to create order: {}", order, e);
            return ResponseEntity.status(500).body("Error creating order");
        }
    }
}

日志输出

2023-05-20 14:40:33.789 ERROR 12345 --- [nio-8080-exec-2] com.example.OrderController : Failed to create order: Order(id=null, product=ABC)
java.lang.NullPointerException: Cannot invoke "com.example.Order.getId()" because the return value of "com.example.Service.process(com.example.Order)" is null
    at com.example.OrderController.createOrder(OrderController.java:25)
    ...

性能日志[编辑 | 编辑源代码]

使用AOP记录方法执行时间:

@Aspect
@Component
public class LoggingAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long duration = System.currentTimeMillis() - startTime;
        logger.info("{} executed in {} ms", joinPoint.getSignature(), duration);
        return result;
    }
}

数学公式示例[编辑 | 编辑源代码]

当需要计算日志采样率时,可能用到以下公式:

采样概率公式: P=1n

其中:

  • P 为采样概率
  • n 为采样率基数

最佳实践[编辑 | 编辑源代码]

1. 生产环境建议使用WARN作为默认级别 2. 敏感信息不应记录在日志中 3. 使用{}占位符而非字符串拼接(更高效) 4. 重要业务操作建议记录审计日志 5. 分布式系统考虑集中式日志收集(如ELK)

常见问题[编辑 | 编辑源代码]

Q: 如何切换日志实现(如从Logback到Log4j2)? A: 排除默认依赖并添加Log4j2 starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Q: 为什么我的DEBUG日志没有输出? A: 检查: 1. application.properties中的日志级别设置 2. 是否有多个配置文件冲突 3. 是否在启动命令中覆盖了日志级别(如--debug参数)