Skip to content

日志


SLF4J + Logback

Spring Boot 默认使用 SLF4J(日志门面)+ Logback(日志实现)。

java
@Service
public class UserService {

    // 每个类声明一个 logger
    private static final Logger log = LoggerFactory.getLogger(UserService.class);
    //                        ⬆ 通常类名作为 logger name

    public User findById(Long id) {
        log.info("查询用户: {}", id);          // 类比 Log::info('查询用户: ' . $id)
        log.debug("详情: {}", user);            // 类比 Log::debug(...)
        log.warn("用户不存在: {}", id);         // 类比 Log::warning(...)
        log.error("查询失败", exception);       // 类比 Log::error(...)
    }
}

对比 PHP:

php
use Illuminate\Support\Facades\Log;
Log::info('查询用户: ' . $id);

Java 中 LoggerFactory.getLogger() 每个类写一次有点烦,但这是 SLF4J 的设计——通过 logger name(类名)来区分日志来源。IDEA 有 live template,输入 log 回车自动补全。


Lombok 简化

java
@Slf4j           // Lombok 注解,自动生成 log 字段
@Service
public class UserService {

    public User findById(Long id) {
        log.info("查询用户: {}", id);
        // 不需要手动声明 Logger
    }
}

需要 Lombok 依赖 + IDE 安装 Lombok 插件。


日志级别

yaml
# application.yml
logging:
  level:
    root: INFO                    # 全局默认级别
    com.example.myapp: DEBUG      # 项目包级别
    org.springframework.web: DEBUG # Spring Web 的请求日志
    org.springframework.security: TRACE  # Security 详细日志
级别用途类似 PHP 的
ERROR错误事件,需要关注Log::error()
WARN潜在问题,不影响运行Log::warning()
INFO重要业务事件Log::info()
DEBUG开发调试信息Log::debug()
TRACE最详细的跟踪信息无直接对应

占位符 {}(避免字符串拼接)

java
// ❌ 不推荐:字符串拼接
log.info("用户 " + id + " 登录成功,IP: " + ip);
// 即使日志级别不输出,字符串拼接也会执行

// ✅ 推荐:占位符
log.info("用户 {} 登录成功,IP: {}", id, ip);
// 当前日志级别不输出时,不会拼接字符串

PHP 中 Log::info("用户 {$id} 登录成功") 也是拼接,但是 PHP 的字符串插值性能开销可以忽略。Java 中 {} 占位符的方式在日志级别较高(比如生产只输出 WARN)时能节省字符串构建的开销。


⚠️ 关键差异

1. Java 的日志生态很混乱

PHP 中 Log::info() 一个函数搞定。Java 有多个日志框架:

  • Log4j:最早的(已过时)
  • Logback:Spring Boot 默认
  • Log4j 2:新版的 Log4j
  • SLF4J:日志门面,统一 API

Spring Boot 解决了选择困难——默认 SLF4J + Logback,直接用就好。不要自己去引入其他日志框架。

2. 没有全局的 Log 门面

PHP 中 Log::info() 是 Facade,直接调用。Java 中每个类需要先声明 Logger log = LoggerFactory.getLogger(类名.class),或者用 Lombok 的 @Slf4j

3. 配置比 PHP 复杂,但也更强大

yaml
logging:
  file:
    path: ./logs                    # 类比 Laravel 的 LOG_CHANNEL=stack
    name: myapp.log
  logback:
    rollingpolicy:
      max-file-size: 10MB          # 每 10MB 分割
      max-history: 30              # 保留 30 天

PHP 的日志通常按天分割(laravel-2026-04-25.log),Logback 默认按大小分割。

4. System.out.println 不是日志

java
// 新手常见错误:用 System.out 打印
System.out.println("查询用户: " + id);  // ❌

// 应该用 logger
log.info("查询用户: {}", id);            // ✅

System.out 会直接输出到控制台,无法控制级别、无法归档、无法按环境区分。一定要用 logger。

面向 PHP 开发者的 Spring Boot 文档