关于 nebula-logger-best-practices
nebula-logger-best-practices 是面向 Nebula Logger 团队的日志治理技能,适用于设计或审查日志规范。它介绍如何配置日志级别与保留策略、补充结构化信息,并在 Salesforce 限制内保存日志。
主要功能
- 01按环境设置日志级别
- 02用场景和标签归类日志
- 03添加结构化日志详情
- 04审慎选择日志保存节点
- 05考虑 Salesforce 限制
适用场景
- 01审查拉取请求中的日志改动
- 02设置生产和测试环境的日志级别
- 03为批处理或异步任务选择保存节点
- 04降低存储与事件配额压力
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jongpie/ nebulalogger --skill nebula-logger-best-practices安装后在 Claude Code 中输入/nebula-logger-best-practices确认已加载。
详细介绍
Nebula Logger 最佳实践与治理
团队通用实践
审核拉取请求或设计日志约定时,请采用以下默认做法。
- 将
ERROR、WARN和INFO用于具有重要运维意义的信息。 - 使用
DEBUG、FINE、FINER和FINEST记录大量诊断细节。结合LoggerSettings__c.LoggingLevel__c,这些日志级别可以保留在代码中,不会增加生产环境的运行时开销,并且只在需要深入诊断时启用。 - 根据环境调整
LoggerSettings__c数据。- 在生产组织中,将
LoggingLevel__c配置为ERROR、WARN或INFO,以减少日志噪声(或在尝试调试时改为DEBUG、FINE、FINER或FINEST) - 配置计划清理任务和保留期限(
DefaultLogPurgeAction__c、DefaultNumberOfDaysToRetainLogs__c)
- 在生产组织中,将
- 使用静态方法
Logger.setScenario(),以及实例方法LogEntryEventBuilder.addTag()和LogEntryEventBuilder.addTags()对业务流程进行分组。- 为场景和标签制定符合团队需求的规范命名约定
- 使用
LogEntryEventBuilder的实例方法进一步丰富数据,而不是将额外数据直接嵌入消息字符串中。这些方法有多个重载版本:.setExceptionDetails(...).setApprovalResult(...).setDatabaseResult(...).setRecord(...).setHttpRequestDetails(...).setHttpResponseDetails(...).setRestRequestDetails(...).setRestResponseDetails(...).setField(...)
- 谨慎调用
Logger.saveLog()——不要在每条日志后都调用,也不要在紧密循环中调用。调用时要有策略,就像在 Apex 中执行 DML 调用一样。Logger.info(...)/.error(...)等方法只会将条目添加到内存缓冲区。只有运行saveLog()后,数据才会持久化。如果事务结束时未调用saveLog(),缓冲的所有内容都会丢失,因此仍需在事务提交前调用saveLog()。- 每次调用
saveLog()都是一次实际的平台操作,会产生实际开销。使用默认的EVENT_BUS保存方法时,每次调用saveLog()都会调用一次System.EventBus.publish(List<LogEntryEvent__e>),消耗一个System.Limits.getLimitPublishImmediateDML()配额(每个事务 100 次),并占用组织每日平台事件发布配额的一次额度。其他保存方法也各有其限制:QUEUEABLE会消耗一个异步作业配额(System.Limits.getLimitQueueableJobs()),REST会消耗一次 callout,SYNCHRONOUS_DML会消耗常规 DML 行数和语句数。它们都不是免费的。 - 在一个事务中多次调用
saveLog()没问题,而且通常是正确的做法。适合保存中间状态的时机包括:批处理的每个分块结束后、长时间运行的循环每次外层迭代结束时(切勿在内层迭代中调用,见下文)、异步交接前(Queueable / Future / Batchable),以及准备重新抛出异常时捕获该异常的finally块中。每次保存只会发布当时缓冲区中的内容,因此即使事务其余部分之后发生故障,这些条目仍会持久化。 - 真正的问题是在每条日志后都调用
saveLog()。这会将 N 次日志调用变成 N 次平台事件发布,迅速耗尽getLimitPublishImmediateDML()(每个事务 100 次),并消耗组织每日平台事件配额,却没有任何运维收益。如果你发现自己反复编写Logger.info(...); Logger.saveLog();,请先缓冲这些条目,再在该组日志结束后调用一次保存。 - 切勿在遍历记录的循环最内层代码块中调用
saveLog()。应在循环中缓冲条目,并在循环结束后(或在安全检查点,例如每 N 次迭代后、每个工作分块完成后等)调用saveLog(),不要在处理每条记录后调用。 - 在事务性代码路径中,将
Logger.saveLog()调用放在finally块中,这样即使异常从 try 块中逸出,它也会运行。如果默认的EVENT_BUS不适合该代码路径,请在方法开头配合调用Logger.setSaveMethod(...)(参见上文有关保存方法的说明)。
环境感知型日志级别
将日志详细程度视为运维控制项,而不是代码常量。
| 环境 | 建议基线 | 原因 |
|---|---|---|
| 生产环境 | ERROR 或 WARN | 减少噪声和存储占用,同时保留事故信号 |
| UAT | INFO | 验证业务流程,避免过多细节 |
| QA | DEBUG 或 FINE | 支持缺陷复现和集成测试 |
| Sandbox/Dev | FINE 至 FINEST(限时启用) | 在主动开发期间进行深入诊断 |
通过层级覆盖(用户/配置文件)应对临时事故时段,然后恢复原设置。
现有代码审查清单
- 每条执行路径是否都在有意设置的检查点调用
saveLog(),而不是在每条记录之后或每个记录的内层循环中调用? - 是否使用堆栈跟踪上下文记录异常?
- 是否通过
.setRecord(...)附加记录引用? - 场景和标签是否符合团队分类体系?
- 未使用默认的
EVENT_BUS时,是否明确选择了保存方法?
Governor 和容量注意事项
Nebula Logger 有助于提升可观测性,但仍受 Salesforce governor 限制。
| 限制 | 对日志记录的影响 | 缓解措施 |
|---|---|---|
| 数据存储 | 大量日志会迅速占用自定义对象存储空间 | 强制执行保留策略和清理计划;降低生产环境中的日志详细程度 |
| 平台事件每日限额 | EVENT_BUS 的用量可能触及组织的事件配额 | 选择性记录日志;必要时将目标作业切换到 QUEUEABLE/SYNCHRONOUS_DML |
| SOQL 查询 | 日志路径中的额外数据补充查询可能会加剧限额压力 | 重用已查询的记录,避免仅为日志记录而发起大量查询 |
| CPU 时间 | 循环中的繁重序列化/标签处理会增加 CPU 用量 | 记录聚合里程碑,而非每次迭代;优先选择异步保存路径 |
| 异步作业配额 | 过度使用 QUEUEABLE 可能与业务异步工作争抢资源 | 将队列保存保留给高成本或对混合 DML 敏感的场景 |
| 堆大小 | 大型负载/异常可能会增加事务内存占用 | 截断过大的负载,避免转储完整对象图 |
不适合使用 Nebula Logger 的情况
Nebula Logger 不能替代良好的架构设计。
- 不要将日志记录用作应对领域设计不清晰的权宜之计。
- 不要在日志消息中存储机密、凭据或不必要的个人身份信息。
将 Nebula Logger 用作结构化可观测性层,并结合清晰的服务边界、可靠的错误处理和有目的的遥测。
评论
支持 Markdown