SKILL.md
readonly只读
name
logging-best-practices
description
专注于宽事件(规范日志行)的日志记录最佳实践,用于强大的调试和分析
日志记录最佳实践技能
版本:1.0.0
目的
本技能提供在应用程序中实施有效日志记录的指南。它专注于宽事件(也称为规范日志行)——一种针对每个请求每个服务发出单个、上下文丰富的事件的模式,从而实现强大的调试和分析。
何时应用
在以下情况下应用这些指南:
- 编写或审查日志记录代码时
- 添加 console.log、logger.info 或类似内容时
- 为新服务设计日志记录策略时
- 设置日志记录基础设施时
核心原则
1. 宽事件(关键)
针对每个请求每个服务发出一个上下文丰富的事件。不要在处理器中分散日志行,而是将所有内容整合到一个在请求完成时发出的结构化事件中。
const wideEvent: Record<string, unknown> = {
method: 'POST',
path: '/checkout',
requestId: c.get('requestId'),
timestamp: new Date().toISOString(),
};
try {
const user = await getUser(c.get('userId'));
wideEvent.user = { id: user.id, subscription: user.subscription };
const cart = await getCart(user.id);
wideEvent.cart = { total_cents: cart.total, item_count: cart.items.length };
wideEvent.status_code = 200;
wideEvent.outcome = 'success';
return c.json({ success: true });
} catch (error) {
wideEvent.status_code = 500;
wideEvent.outcome = 'error';
wideEvent.error = { message: error.message, type: error.name };
throw error;
} finally {
wideEvent.duration_ms = Date.now() - startTime;
logger.info(wideEvent);
}
2. 高基数和高维度(关键)
包含高基数字段(用户 ID、请求 ID——数百万个唯一值)和高维度字段(每个事件多个字段)。这样可以按特定用户进行查询,并回答你尚未预料到的问题。
3. 业务上下文(关键)
始终包含业务上下文:用户订阅层级、购物车价值、功能开关、账户年龄。目标是知道“一个高级客户无法完成 2,499 美元的购买”,而不仅仅是“结账失败”。
4. 环境特征(关键)
在每个事件中包含环境和部署信息:提交哈希、服务版本、区域、实例 ID。这有助于将问题与部署关联起来,并识别特定区域的问题。
5. 单一日志记录器(高)
使用一个在启动时配置的日志记录器实例,并在任何地方导入它。这确保了格式一致和自动的环境上下文。
6. 中间件模式(高)
使用中间件处理宽事件基础设施(计时、状态、环境、发出)。处理器只应添加业务上下文。
7. 结构与一致性(高)
- 一致地使用 JSON 格式
- 在服务间保持字段名称一致
- 简化为两个日志级别:
info和error - 绝不记录非结构化字符串
应避免的反模式
- 分散的日志:每个请求多个 console.log() 调用
- 多个日志记录器:不同文件中的不同日志记录器实例
- 缺少环境上下文:没有提交哈希或部署信息
- 缺少业务上下文:记录技术细节而不包含用户/业务数据
- 非结构化字符串:使用
console.log('something happened')而不是结构化数据 - 不一致的模式:服务间字段名称不同
指南
宽事件(rules/wide-events.md)
- 每个服务跳转发出一个宽事件
- 包含所有相关上下文
- 使用请求 ID 连接事件
- 在 finally 块中请求完成时发出
上下文(rules/context.md)
- 支持高基数字段(user_id, request_id)
- 包含高维度(多个字段)
- 始终包含业务上下文
- 始终包含环境特征(commit_hash, version, region)
结构(rules/structure.md)
- 在整个代码库中使用单一日志记录器
- 使用中间件实现一致的宽事件
- 使用 JSON 格式
- 保持一致的 schema
- 简化为 info 和 error 级别
- 绝不记录非结构化字符串
常见陷阱(rules/pitfalls.md)
- 避免每个请求多个日志行
- 为未知的未知设计
- 始终在服务间传播请求 ID
参考:






