leniu-java-logging
SKILL.md
leniu 日志规范
基本规则
- 使用
@Slf4j(Lombok),禁止直接用 Log4j/Logback API - 使用
{}占位符,禁止字符串拼接 - 异常对象作为
log.error的最后一个参数(自动打印堆栈) - 日志用中文,用
【模块名】前缀便于检索 - 禁止记录密码、完整手机号等敏感信息
日志级别选择
| 级别 | 场景 | 示例 |
|---|---|---|
| ERROR | 系统错误、需立即处理 | 数据库异常、外部服务失败 |
| WARN | 非预期但可处理 | 配置缺失用默认值、数据不存在 |
| INFO | 关键业务节点 | 订单创建/支付成功、定时任务完成 |
| DEBUG | 开发调试(生产不输出) | 查询参数、中间结果 |
模块标识格式
log.info("【订单】开始创建订单, userId:{}", userId);
log.info("【支付】支付成功, orderId:{}, transactionId:{}", orderId, txId);
log.info("【库存】扣减库存, productId:{}, quantity:{}", productId, qty);
log.error("【远程调用】用户服务调用失败, userId:{}", userId, e);
MQ 消费用方括号:
log.info("[xxx事件]MQ消费:开始");
log.info("[xxx事件]MQ消费:消息消费完成");
log.error("[xxx事件]MQ消费:处理异常", e);
异常日志(最重要)
// ✅ 正确:异常 e 作为最后参数,保留完整堆栈
try {
doProcess(orderId);
} catch (Exception e) {
log.error("订单处理失败, orderId:{}", orderId, e);
throw new LeException("订单处理失败");
}
// ✅ 记录案发现场(关键参数 + 上下文)
try {
updateStatus(orderId, status);
} catch (Exception e) {
log.error("订单状态更新失败, orderId:{}, oldStatus:{}, newStatus:{}",
orderId, oldStatus, status, e);
throw new LeException("订单状态更新失败");
}
// ❌ 错误:只记录 message,丢失堆栈
log.error("处理失败:{}", e.getMessage());
各层日志规范
Business/Service 层(关键业务)
@Slf4j
@Service
public class OrderService {
@Transactional(rollbackFor = Exception.class)
public Long create(OrderParam param) {
log.info("【订单】开始创建订单, userId:{}, productId:{}",
param.getUserId(), param.getProductId());
try {
Order order = buildOrder(param);
orderMapper.insert(order);
log.info("【订单】订单创建成功, orderId:{}", order.getId());
return order.getId();
} catch (Exception e) {
log.error("【订单】订单创建失败, param:{}", param, e);
throw new LeException("订单创建失败");
}
}
}
定时任务
@Slf4j
@Component
public class DataSyncJob {
@XxlJob("syncDataJob")
public void syncData() {
log.info("【定时任务】开始同步数据");
try {
int count = doSync();
log.info("【定时任务】数据同步完成, 同步数量:{}", count);
} catch (Exception e) {
log.error("【定时任务】数据同步失败", e);
}
}
}
MQ 消费者
@Slf4j
@MQMessageListener(group = "order-order-v3-xxx", topic = "order", tag = "order-v3-xxx")
public class OrderMqListenerXxx implements MQListener<MqPayload<String>> {
@Override
public void onMessage(MqPayload<String> payload) {
log.info("[xxx事件]MQ消费:开始");
orderMqHandler.handleMessage(payload, OrderXxxPO.class, OrderMqHandler::handleXxx);
}
}
外部调用
public UserDTO getUserFromRemote(Long userId) {
log.info("【远程调用】开始调用用户服务, userId:{}", userId);
try {
UserDTO user = remoteUserService.getUser(userId);
log.info("【远程调用】用户服务调用成功, userId:{}", userId);
return user;
} catch (Exception e) {
log.error("【远程调用】用户服务调用失败, userId:{}", userId, e);
throw new LeException("用户信息获取失败");
}
}
性能规则
// ✅ debug 级别用条件判断或 Lambda(避免无用计算)
if (log.isDebugEnabled()) {
log.debug("详细数据: {}", expensiveOperation());
}
// ✅ 批量操作:前后各一条,不在循环内打印
log.info("开始处理订单, 数量:{}", orders.size());
int success = 0, fail = 0;
for (Order order : orders) {
try { process(order); success++; }
catch (Exception e) { log.error("订单处理失败, orderId:{}", order.getId(), e); fail++; }
}
log.info("订单处理完成, 成功:{}, 失败:{}", success, fail);
// ✅ 只记录关键信息,不序列化大对象
log.info("查询结果数量: {}", orders.size()); // ✅
// log.info("查询结果: {}", orders); // ❌ 大对象
敏感信息脱敏
// ❌ 禁止记录:密码、完整手机号、身份证、银行卡
log.info("用户登录, username:{}, password:{}", username, password);
// ✅ 脱敏后记录
log.info("发送验证码, mobile:{}", maskMobile(mobile)); // 138****1234
脱敏工具:详见 references/data-mask.md
Logback 配置
配置文件:core-starter/src/main/resources/logback-spring.xml
| Profile | 作用 |
|---|---|
no_log_console |
不输出到控制台 |
no_log_file |
不输出到文件 |
# application.yml 日志级别
logging:
level:
net.xnzn.core: INFO # 项目
com.baomidou.mybatisplus: INFO
org.springframework: WARN
开发环境 net.xnzn.core: DEBUG,生产环境 INFO + no_log_console。
禁止项
// ❌ 直接用 Log4j API
import org.apache.log4j.Logger;
// ❌ 字符串拼接
log.info("userId:" + userId + ", name:" + name);
// ❌ 无意义日志
log.info("进入方法");
log.info("退出方法");
// ❌ 英文日志(项目要求中文)
log.info("Order created successfully");
// ❌ 丢失异常堆栈
log.error("失败:{}", e.getMessage());
参考文档
- 详细场景示例(Controller/分页/远程调用):详见
references/logging-scenarios.md - 脱敏工具方法:详见
references/data-mask.md
Weekly Installs
3
Repository
xu-cell/ai-engi…ing-initGitHub Stars
8
First Seen
8 days ago
Security Audits
Installed on
gemini-cli3
github-copilot3
codex3
kimi-cli3
cursor3
amp3