mcpField
S
sentry-instrument-logging

sentry-instrument-logging

github.com/getsentry开发272541 次安装今天更新
代码仓库

关于 sentry-instrument-logging

用于为已有 Sentry 配置的应用添加结构化日志的技能,涵盖应用盘点、日志选点、字段规范和验证。重点是记录少量有助于生产排查的信息,并避免敏感数据及低价值日志。

主要功能

  1. 01盘点仓库中的独立应用
  2. 02统一日志字段与命名约定
  3. 03添加高价值结构化日志
  4. 04检查隐私与日志级别
  5. 05验证日志并汇报应用状态

适用场景

  1. 01为已接入 Sentry 的应用补充日志
  2. 02梳理多语言仓库的日志覆盖
  3. 03排查生产决策与可恢复故障
  4. 04审查日志中的敏感信息

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/getsentry/sentry-for-ai --skill sentry-instrument-logging

安装后在 Claude Code 中输入/sentry-instrument-logging确认已加载。

详细介绍

为 Sentry 日志添加埋点

此技能会根据埋点指南,为应用添加结构化的 Sentry 日志。

目标是提供少量高价值日志消息,让生产环境中的行为更易于理解和调试。

此技能添加的日志消息也应作为清晰、可重复的示例,供用户在为应用其余部分添加埋点时参考。

前提条件

仓库应已完成基本的 Sentry 配置。

如果尚未配置 Sentry,请提出使用相应的技能进行设置。

步骤

  1. 盘点仓库中的每个应用。 查找语言/运行时清单文件(composer.json、package.json、go.mod、Gemfile、pyproject.toml、Cargo.toml,……)。每个清单通常都对应一个单独部署的应用。明确列出表格,并将其作为此技能其余步骤的工作清单:

    应用路径语言是否使用 Sentry SDK?日志抽象状态

    如果仓库中的应用超过约 2 个,请在开始前与用户确认范围:现在要为哪些应用添加监控,以及要做到什么程度。

  2. 一次性提前确定共享约定——在处理任何应用之前。确定一致的属性命名空间(例如 myapp.<domain>.<field>)、事件名称措辞和日志级别,以便能够跨语言搜索和关联所有日志。记录这些约定,供每个应用的处理过程遵循。注意会传递跟踪标头(baggage / sentry-trace)的服务边界——此类调用两端的日志应使用相同的属性名称,以便单个跟踪在不同语言间保持连贯。

  3. 按清单逐个完成每个应用的全部处理,再继续下一个应用,并随进度更新其状态(not started → configured → instrumented → verified):

    a. 阅读 skills 中对应语言的技能,并确认已配置 Sentry 日志记录。 b. 确定应用使用的日志抽象(Monolog/PHP、slog/Go、Rails logger/Ruby、Pino 或 console/JS)。如果 Sentry 支持,则配置相应集成;否则直接使用 Sentry 的日志 SDK。 c. 找出少量高价值日志消息,优先考虑运行时决策、重要算法、审计事件,以及可恢复故障的相关上下文。遵循值得添加监控的日志条目。 d. 遵循步骤 2 中的共享约定和监控指南,添加结构化日志。 e. 验证:运行应用的 lint/类型检查/测试工具(如果可用),并确认日志确实发出。如果本地没有可用的工具链,请明确说明,而不要暗示检查已通过。

  4. 执行高价值日志验证检查。 检查每一条新增或修改的日志,并移除或修改任何未通过此检查的日志:

    检查项问题
    生产环境问题这条日志能回答什么具体的生产环境问题?
    信号如果这条日志发出数百或数千次,它仍然有用吗?
    遥测适用性将其表示为跟踪、指标或 Sentry 错误是否更合适?
    现有覆盖异常、现有日志或共享 API/客户端封装是否已记录此信息?
    结构事件名称和属性是否符合共享约定?
    安全性是否避免记录 PII、机密信息、原始负载和不稳定的异常消息?
    可操作性看到这条日志是否会改变调查或响应方式?

    优先移除仅确认常规 UI 交互、重复记录通用 API 故障,或记录未提供有意义上下文的预期验证失败的日志。

    保留能够解释重要运行时决策、总结多步骤工作流、记录重要审计/业务事件,或提供可恢复故障相关上下文的日志。

    对于每一条保留的日志,都应能写出一句理由:“这条日志很有价值,因为它有助于回答<具体问题>。”

  5. 对照清单进行核对。 确认所有范围内的应用都已达到 verified(或已明确延期)。报告每个应用的状态,避免将部分覆盖误认为完整覆盖。

监控指南

何时使用日志,而非其他类型的遥测数据

日志非常适合记录应用运行期间发生的情况及其背后的上下文和决策。

  • 如需衡量请求的性能和流转情况,请使用追踪。
  • 对于意外的严重故障,请使用错误。
值得埋点记录的日志条目
应用在运行时做出的重要决策

应用在处理请求时做出的决策,往往是解释生产环境行为所缺少的上下文。

例如:

  • 用户启用了某个功能标志,因此走了不同的代码路径。
  • 移动端用户被重定向到不同的体验。
  • 付费用户和免费用户获得不同的功能。

这些信息既可以作为独立日志条目记录,例如评估功能标志时,也可以作为结构化上下文包含在后续日志消息中。

功能或算法是否按预期运行

如果某个功能包含多个步骤,日志会很有用。通过记录中间结果,你可以了解流程在哪个环节出了问题,以及原因。

以下是一个允许用户从其他服务导入日志簿的网站示例:

Sentry.logger.info("Aurora import started", {
  "import.source": "aurora",
  "import.entries_received": body.ascents.length,
});

// Algorithm runs here...

Sentry.logger.info("Aurora import finished", {
  "import.source": "aurora",
  "import.entries_received": body.ascents.length,
  "import.imported": imported,
  "import.climbs_created": climbsCreated,
  "import.skipped": skipped,
  "import.skipped.missing_name": skipDetails.missingName,
  "import.skipped.unknown_grade": skipDetails.unknownGrade,
  "import.skipped.invalid_angle": skipDetails.invalidAngle,
  "import.skipped.already_imported": skipDetails.alreadyImported,
});

日志记录了关键阶段,最终结果则总结了执行的工作,让你更容易了解导入成功、失败或产生意外结果的环节。

审计和访问事件(创建、更新、删除、访问、权限)

审计日志有助于回答“谁更改了此内容?”“何时发生?”和“此操作是否符合预期?”等问题。

记录应用状态的重要变更,例如实体被创建、更新、删除、查看或权限被修改。

请合理判断。大多数应用无需为每次数据库操作都记录日志,但通常会受益于记录与安全相关的操作和重要业务事件。

错误和故障的相关上下文

对于异常,使用错误通常比添加日志行更合适。

并非每次故障都应成为 Sentry 问题。

以下故障通常更适合用日志消息表示:

  • 非关键的可选上游服务发生故障。
  • 最终尝试之前,重试循环中发生的故障。

对于这类 error 日志消息,可以考虑包含:

  • 重试次数。
  • 外部 API 调用的响应状态代码,以及重要的非敏感请求或响应字段。
  • 导致故障的运行时决策。
如何构建日志消息
使用结构化日志消息

使用结构化日志,以一致的键值对捕获信息。

在整个应用中使用一致的字段名称,以便搜索、汇总和比较类似事件。

一条好的日志消息通常会回答三个问题:

  • 谁执行了此操作(例如,经过身份验证的用户)。
  • 发生了什么(便于理解的消息和辅助元数据)。
  • 何时发生(通常由日志系统自动添加)。

在适当情况下,使用 Sentry SDK 全局设置上下文。例如,许多 SDK 都提供 set_user,可在一个位置将经过身份验证的用户信息附加到所有事件。

随着请求推进添加上下文

随着请求在应用中流转,日志应逐步累积上下文。

早期的日志消息可能只包含请求信息。后续消息可以添加经过身份验证的用户信息、功能标志、运行时决策和特定事件的元数据。

Sentry 会自动为日志消息附加 Trace ID,使其能够与追踪数据相关联。

选择合适的日志级别

使用合适的日志级别,可以在日志消息中传达更多含义。

使用 debug 记录临时诊断信息。

使用 info 记录常规应用事件和上下文信息。

使用 warn 记录值得关注但可以恢复、且不会妨碍应用正常运行的情况。

使用 error 记录得到妥善处理的意外故障。对于应转化为 Sentry 问题的异常,优先使用错误级别。

如何记录对象

避免记录整个对象。应只记录与事件相关的字段,并使用点号表示法为嵌套值添加命名空间。

可选属性不存在时,应省略,而不是记录空字符串、null 或占位值。

不应记录的内容
不要记录每一行代码或每次函数调用

为每次函数调用或服务调用添加埋点,更适合通过跟踪或性能分析来处理。

不要记录 PII 和其他敏感信息

假设写入日志的任何内容最终都可能被其他人看到。

  • 尽可能使用不透明的用户 ID,而不是电子邮件地址、用户名或全名;设置全局用户上下文时也应如此(例如通过 set_user)。
  • 密码、访问令牌、API 密钥及类似机密绝不应出现在日志中。
  • 根据司法管辖区的不同,其他类型的个人信息也可能受到监管,包括年龄、性别和邮政编码。
  • 决定记录、保留或公开哪些内容时,请留意 PCI、GDPR、CCPA 和 HIPAA 等法律与标准。

审慎决定记录哪些内容。只记录调试和运行应用所需的最少信息。

大块数据(没有特定用途时)

记录大型非结构化数据块有合理的用途:

  • 查看完整的大模型提示词和响应,可能有助于了解产品行为是否符合预期。
  • 记录 webhook 请求体,可能有助于调试外部集成问题。

不过,记录这类数据既有成本,也有风险:

  • 用户可能会在大模型提示词中包含个人信息或敏感信息。
  • 完整的 HTTP 请求和响应可能包含访问令牌、机密或其他敏感数据。

在可能的情况下,优先记录预期用于查询的特定字段,而不是整个负载。

针对技能的指导

此技能旨在展示良好的日志记录实践,而不是最大限度地覆盖日志。

优先添加少量高价值日志消息,而不是为所有可能的代码路径添加埋点。

每条日志消息都应:

  • 在调试生产环境问题时立即发挥作用。
  • 展示结构化日志的有效用法。
  • 作为用户可在代码库其他位置借鉴的实用示例。

对于小型代码库,应添加足够有代表性的日志,使其成为后续添加埋点时的实用范例。

对于大型代码库,应聚焦少数有代表性的位置,而不是尝试为所有内容添加埋点。

强烈建议使用 SDK 的 setUser 功能将日志与已认证用户关联,而不是反复将用户标识符作为日志属性。只有当用户标识符描述的并非已认证用户时,才将其作为日志属性。

代码库已有日志时

添加新的日志行之前,请检查现有日志并找出缺口。

建议:

  • 将现有日志改进为结构化日志。
  • 为现有的重要日志补充缺失的上下文。
  • 仅在当前尚无答案的重要生产问题所涉及的位置添加日志。特别注意故障是否已体现为未捕获异常,因此可能已经被 Sentry 错误捕获。

评论

支持 Markdown