日志
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:
phpuse 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 复杂,但也更强大
yamllogging: 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。