文档站点
Skip to content

日志 ​

Laravel 用 Log::info(...) 全局函数;Java 世界有标准日志门面 SLF4J,Spring Boot 默认集成 Logback。你用 @Slf4j(Lombok)或 LoggerFactory 拿到 Logger,然后 log.info(...)。

最小示例 ​

java
@Service
public class PostService {
    private static final org.slf4j.Logger log =
            org.slf4j.LoggerFactory.getLogger(PostService.class);

    public Post create(PostDto dto) {
        log.info("创建帖子: {}", dto.getTitle());
        return repository.save(dto.toEntity());
    }
}

更简洁的姿势:Lombok 的 @Slf4j,直接有 log 变量:

java
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class PostService {

    public Post create(PostDto dto) {
        log.info("创建帖子: {}", dto.getTitle());   // {} 占位符,等价于字符串拼接
        log.warn("库存不足: {}", dto.getId());
        return repository.save(dto.toEntity());
    }
}

为什么用 {} 占位而不是 +?

log.info("创建帖子: {}", title) 只有真正要输出时才拼接字符串,性能好;"..." + title 无论如何都会拼接。占位符是 Java 日志的最佳实践。

日志级别 ​

级别用途Laravel 对应
TRACE最细粒度Log::debug(更细)
DEBUG调试Log::debug
INFO常规信息Log::info
WARN潜在问题Log::warning
ERROR错误Log::error

配置:application.yml ​

yaml
logging:
  level:
    root: info                    # 全局级别
    com.example.demo.post: debug  # 指定包更细
  file:
    name: logs/app.log            # 输出到文件(默认只打控制台)
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

类比 Laravel

Laravel 的 LOG_CHANNEL、LOG_LEVEL 在 .env;Spring Boot 在 application.yml 的 logging.*,同样支持按环境覆盖。

日志里的上下文信息 ​

Laravel 有 Log::withContext([...]);Spring Boot 3.x 用 MDC:

java
import org.slf4j.MDC;

// 入口(Filter/Interceptor)里写入
MDC.put("requestId", requestId);
MDC.put("userId", String.valueOf(userId));

// 整个请求生命周期内,任何日志自动带上这两个字段
log.info("查询帖子");

// 请求结束时清理(记得在 finally 里)
MDC.clear();

配合日志 pattern 输出:

yaml
logging:
  pattern:
    console: "%d{...} [%X{requestId}] [%X{userId}] %-5level %logger{36} - %msg%n"

TIP

结合 请求生命周期 里讲的 Filter,给每个请求生成 requestId 写入 MDC,是排查分布式问题的最强利器 —— 一条请求链路的所有日志都能串起来。

生产实践 ​

建议原因
生产级别设为 infodebug 会刷爆磁盘
业务关键节点打 info,异常打 error(带堆栈)可追溯、可告警
别打敏感信息(密码、token)日志会进日志系统,等于泄露
日志文件滚动logging.file.name 默认 10MB 滚动,够用
结构化日志(JSON)云平台/ELK 采集时更友好,可用 logstash-logback-encoder

常见坑 ​

  1. 忘写堆栈:log.error("出错了 {}", e.getMessage()) 只打了消息没有堆栈。要 log.error("出错了", e),把异常对象传进去。
  2. 日志没级别:全用 log.info,生产排障困难。
  3. 用 System.out:System.out.println 不走日志框架,没级别、没时间戳、性能差。永远用 Logger。

面向 PHP / Laravel 开发者的 Spring Boot 中文文档