sentry-instrument-logging
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseInstrument Sentry Logging
接入Sentry日志记录
This skill adds structured Sentry logs to an application following the guidance
in Instrumentation guidance.
The goal is to provide a small set of high-value log messages that make
production behavior easier to understand and debug.
The log messages added by this skill should also serve as clear, repeatable,
examples that users can follow when instrumenting the rest of their application.
本技能会按照埋点实施指南的要求,为应用添加结构化Sentry日志。
目标是提供一组高价值的日志消息,让生产环境的行为更易于理解和调试。
本技能添加的日志消息还应作为清晰、可复用的示例,供用户在为应用其他部分做埋点时参考。
Prerequisites
前置条件
The repository should already have basic Sentry configuration.
If Sentry has not yet been configured, offer to set it up using the appropriate
skills.
代码仓库需已完成基础Sentry配置。
若尚未配置Sentry,可使用相应的技能来完成配置。
Steps
步骤
-
Inventory every application in the repository. Locate language/runtime manifests (,
composer.json,package.json,go.mod,Gemfile,pyproject.toml, …). Each manifest typically marks a separately deployed application. Produce an explicit table and treat it as the work list for the rest of this skill:Cargo.tomlApp Path Language Sentry SDK? Logging abstraction Status If the repo has more than ~2 apps, confirm scope with the user before starting: which apps to instrument now, and at what depth. -
Establish shared conventions once, up front — before touching any app. Decide on consistent attribute namespacing (e.g.), event-name phrasing, and log levels, so logs from every language can be searched and correlated together. Record these so each per-app pass follows them. Note service boundaries that propagate trace headers (baggage / sentry-trace) — logs on both sides of such a call should share attribute names so a single trace reads coherently across languages.
myapp.<domain>.<field> -
For each application in the inventory, complete the full pass below before moving to the next, updating its Status as you go ():
not started → configured → instrumented → verifieda. Read the corresponding language-specific skill in skills and confirm Sentry logging is configured. b. Determine the app's logging abstraction (Monolog/PHP, slog/Go, Rails logger/Ruby, Pino or console/JS). If Sentry supports it, configure that integration; otherwise use Sentry's logging SDK directly. c. Identify a small number of high-value log messages, prioritizing runtime decisions, important algorithms, audit events, and context around recoverable failures. Follow Valuable log entries to instrument. d. Add structured logs following the shared conventions from Step 2 and the Instrumentation guidance. e. Verify: run the app's lint/type/test tooling if available, and confirm logs are emitted. If the toolchain isn't available locally, say so explicitly rather than implying it passed. -
Apply a high-value log validation check. Review every added or modified log line and remove or revise any log that does not pass this check:
Check Question Production question What concrete production question does this log answer? Signal Would this still be useful if emitted hundreds or thousands of times? Telemetry fit Is this better represented as a trace, metric, or Sentry error? Existing coverage Is this already captured by an exception, existing log, or shared API/client wrapper? Structure Are event names and attributes consistent with the shared conventions? Safety Does it avoid PII, secrets, raw payloads, and unstable exception messages? Actionability Would seeing this log change how someone investigates or responds? Prefer removing logs that merely confirm routine UI interactions, duplicate generic API failures, or record expected validation failures without adding meaningful context.Keep logs that explain important runtime decisions, summarize multi-step workflows, record important audit/business events, or provide context around recoverable failures.For each remaining log, be able to write a one-sentence justification: "This log is valuable because it helps answer <specific question>." -
Reconcile against the inventory. Confirm every in-scope app reached(or was explicitly deferred). Report per-app status so partial coverage is never mistaken for full coverage.
verified
-
清点仓库中的所有应用程序。查找语言/运行时清单文件(、
composer.json、package.json、go.mod、Gemfile、pyproject.toml……)。每个清单文件通常对应一个独立部署的应用。生成明确的表格,并将其作为后续操作的任务清单:Cargo.toml应用 路径 语言 是否已集成Sentry SDK? 日志抽象层 状态 如果仓库中的应用数量超过约2个,开始前需与用户确认范围:当前要为哪些应用做埋点,以及埋点的深度。 -
首先统一制定通用规范——在处理任何应用之前完成。确定一致的属性命名空间(例如)、事件名称表述方式和日志级别,以便不同语言的日志可以统一搜索和关联。记录这些规范,确保每个应用的埋点都遵循它们。注意传播跟踪头(baggage / sentry-trace)的服务边界——这类调用两侧的日志应使用相同的属性名称,以便跨语言的单个跟踪链路可以连贯读取。
myapp.<domain>.<field> -
针对清单中的每个应用,完成以下全部步骤后再处理下一个,并更新其状态():
未开始 → 已配置 → 已埋点 → 已验证a. 阅读技能中对应的语言专属技能,确认Sentry日志已配置完成。 b. 确定应用的日志抽象层(Monolog/PHP、slog/Go、Rails logger/Ruby、Pino或console/JS)。如果Sentry支持该集成,则配置对应的集成;否则直接使用Sentry的日志SDK。 c. 确定少量高价值的日志消息,优先选择运行时决策、重要算法、审计事件以及可恢复故障的上下文信息。遵循需埋点的高价值日志条目的要求。 d. 按照步骤2中制定的通用规范和埋点实施指南添加结构化日志。 e. 验证:如果有可用的代码检查/类型校验/测试工具,运行这些工具并确认日志已正常输出。如果本地无法使用工具链,需明确说明,而非默认验证通过。 -
执行高价值日志校验检查。审核所有新增或修改的日志行,移除或修改未通过以下检查的日志:
检查项 问题 生产环境问题 这条日志能解答什么具体的生产环境问题? 信号价值 即使被输出数百或数千次,这条日志仍然有用吗? 遥测适配性 这条日志用链路追踪、指标或Sentry错误来表示是否更合适? 已有覆盖 这条日志是否已被异常、现有日志或共享API/客户端封装所捕获? 规范性 事件名称和属性是否符合通用规范? 安全性 是否避免了PII、敏感信息、原始负载和不稳定的异常消息? 可操作性 看到这条日志会改变人们的调查或响应方式吗? 优先移除那些仅确认常规UI交互、重复通用API故障记录,或在未添加有意义上下文的情况下记录预期验证失败的日志。保留那些解释重要运行时决策、总结多步骤工作流、记录重要审计/业务事件,或提供可恢复故障上下文的日志。对于保留的每条日志,都应能写出一句理由:“这条日志很有价值,因为它有助于解答<具体问题>。” -
与清单核对。确认所有范围内的应用都已达到状态(或已明确延期处理)。报告每个应用的状态,避免将部分覆盖误认为完全覆盖。
已验证
Instrumentation guidance
埋点实施指南
When to reach for logging, vs., other types of telemetry
何时选择日志,而非其他类型的遥测
Logs are ideal for recording the context and decisions that explain what
happened during an application's execution.
- For measuring the performance and flow of requests, use tracing.
- For unexpected critical failures, use errors.
日志非常适合记录解释应用执行过程中发生了什么的上下文和决策。
- 若要衡量请求的性能和流转,使用链路追踪。
- 若要处理意外的严重故障,使用错误上报。
Valuable log entries to instrument
需埋点的高价值日志条目
Important runtime decisions made by your application
应用做出的重要运行时决策
The decisions your application makes while serving a request are often the
missing context needed to explain production behaviour.
Examples include:
- A user has a feature flag enabled, resulting in a different code path.
- Mobile users are redirected to a different experience.
- Paid and free users receive different functionality.
This information can be useful both as a standalone log entry, for example when
a feature flag is evaluated, and as structured context included with later log
messages.
应用在处理请求时做出的决策往往是解释生产环境行为所需的缺失上下文。
示例包括:
- 用户启用了功能标志,导致执行不同的代码路径。
- 移动端用户被重定向到不同的体验页面。
- 付费用户和免费用户获得不同的功能。
这些信息既可以作为独立的日志条目(例如功能标志被评估时),也可以作为结构化上下文包含在后续的日志消息中。
Whether a feature or algorithm is behaving as expected
功能或算法是否按预期运行
Logs are useful when a feature performs multiple steps. By recording
intermediate outcomes, you can understand where a process is breaking down and
why.
Here's an example from a site that allows users to import a logbook from another
service:
js
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,
});Key stages are logged and the final outcome summarizes the work performed,
making it easier to understand where the import succeeded, failed, or produced
unexpected results.
当某个功能执行多个步骤时,日志非常有用。通过记录中间结果,你可以了解流程在哪个环节出了问题以及原因。
以下是一个允许用户从其他服务导入日志本的网站示例:
js
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,
});关键阶段会被记录,最终结果会总结已完成的工作,从而更容易理解导入在哪些环节成功、失败或产生了意外结果。
Audit and access events (creates, updates, deletes, access, permissions)
审计和访问事件(创建、更新、删除、访问、权限变更)
Audit logs help answer questions like "Who changed this?", "When did it
happen?", and "Was this action expected?"
Log important changes to application state, such as entities being created,
updated, deleted, viewed, or having permissions modified.
Use good judgment. Most applications don't need a log entry for every database
operation, but they often benefit from recording security-sensitive actions and
important business events.
审计日志有助于解答诸如“谁修改了这个?”、“什么时候发生的?”以及“这个操作是预期内的吗?”之类的问题。
记录应用状态的重要变更,例如实体的创建、更新、删除、查看或权限修改。
请合理判断。大多数应用不需要为每个数据库操作都添加日志条目,但记录安全敏感操作和重要业务事件通常会有帮助。
Context surrounding errors and failures
错误和故障的上下文信息
For exceptions, you'll often be better off using errors rather than adding a log
line.
Not every failure should become a Sentry issue.
Examples of failures that are often better represented as log messages include:
- Failures from non-critical, optional upstream services.
- Failures that occur in a retry loop prior to the final attempt.
For these types of log messages, consider including:
error- Retry count.
- Response status code and important non-sensitive request or response fields for external API calls.
- Runtime decisions leading up to the failure.
对于异常,使用错误上报通常比添加日志行更好。
并非所有故障都应成为Sentry问题。
通常更适合用日志消息表示的故障示例包括:
- 来自非关键、可选上游服务的故障。
- 在最终尝试之前的重试循环中发生的故障。
对于这类级别的日志消息,建议包含:
error- 重试次数。
- 外部API调用的响应状态码和重要的非敏感请求或响应字段。
- 导致故障的运行时决策。
How to structure log messages
如何结构化日志消息
Use structured log messages
使用结构化日志消息
Use structured logs that capture information as consistent key/value pairs.
Use consistent field names throughout the application so similar events can be
searched, aggregated, and compared.
A good log message typically answers three questions:
- Who performed the action (for example, the authenticated user).
- What happened (a human-readable message and supporting metadata).
- When it happened (typically added automatically by the logging system).
Use Sentry's SDK when appropriate for setting context globally. For example,
is available in many SDKs to attach authenticated user information
to all events in a single location.
set_user使用捕获信息为一致键值对的结构化日志。
在整个应用中使用一致的字段名称,以便类似事件可以被搜索、聚合和比较。
一条好的日志消息通常能解答三个问题:
- 谁执行了操作(例如已认证用户)。
- 发生了什么(人类可读的消息和支持元数据)。
- 什么时候发生的(通常由日志系统自动添加)。
在合适的情况下使用Sentry的SDK来全局设置上下文。例如,许多SDK都提供方法,用于在单个位置将已认证用户信息附加到所有事件。
set_userAdd context as a request evolves
随着请求推进添加上下文
Logs should accumulate context as a request moves through your application.
Early log messages may contain only request information. Later messages can add
authenticated user information, feature flags, runtime decisions, and
event-specific metadata.
Sentry automatically attaches a Trace ID to log messages, allowing them to be
correlated with traces.
日志应随着请求在应用中的流转积累上下文。
早期的日志消息可能仅包含请求信息。后续消息可以添加已认证用户信息、功能标志、运行时决策和事件特定元数据。
Sentry会自动为日志消息附加Trace ID,使其可以与链路追踪关联。
Choose the appropriate log level
选择合适的日志级别
Using appropriate log levels conveys additional meaning in your log messages.
Use for temporary diagnostic information.
debugUse for normal application events and contextual information.
infoUse for recoverable situations that deserve attention but do not prevent
the application from functioning correctly.
warnUse for unexpected failures that are handled gracefully. Prefer errors
for exceptions that should become Sentry issues.
error使用合适的日志级别可以为日志消息传达额外的含义。
使用级别记录临时诊断信息。
debug使用级别记录正常应用事件和上下文信息。
info使用级别记录值得关注但不会阻止应用正常运行的可恢复情况。
warn使用级别记录已被优雅处理的意外故障。对于应成为Sentry问题的异常,优先使用错误上报。
errorHow to log objects
如何记录对象
Avoid logging entire objects. Instead, log only the fields relevant to the
event, using dot notation to namespace nested values.
Omit optional attributes when they are not present instead of logging empty
strings, , or placeholder values.
null避免记录整个对象。相反,仅记录与事件相关的字段,使用点符号来命名嵌套值的空间。
当可选属性不存在时,省略它们,而不是记录空字符串、或占位符值。
nullWhat not to log
不应记录的内容
Do not log every line of code or function call
不要记录每一行代码或函数调用
Instrumenting every function call or service invocation is better handled by
tracing or profiling.
为每个函数调用或服务调用做埋点更适合用链路追踪或性能分析来处理。
Do not log PII and other sensitive information
不要记录PII和其他敏感信息
Assume anything written to logs may eventually be viewed by another human.
- Prefer opaque user IDs over email addresses, usernames, or full names whenever
possible, including when setting global user context (for example via
).
set_user - Passwords, access tokens, API keys, and similar secrets should never appear in logs.
- Other types of personal information may also be regulated depending on jurisdiction, including age, gender, and postal code.
- Be aware of laws and standards such as PCI, GDPR, CCPA, and HIPAA when deciding what should be logged, retained, or exposed.
Be intentional about what you log. Log the minimum information necessary to
debug and operate your application.
假设日志中记录的任何内容最终都可能被其他人查看。
- 尽可能使用不透明的用户ID替代电子邮件地址、用户名或全名,包括设置全局用户上下文时(例如通过)。
set_user - 密码、访问令牌、API密钥和类似的敏感信息绝不应出现在日志中。
- 根据司法管辖区的不同,其他类型的个人信息也可能受到监管,包括年龄、性别和邮政编码。
- 在决定应记录、保留或公开哪些内容时,请注意PCI、GDPR、CCPA和HIPAA等法律法规和标准。
要谨慎决定记录的内容。仅记录调试和运维应用所需的最少信息。
Large blobs of data (without a specific purpose)
无特定用途的大数据块
There are legitimate reasons to log large unstructured blobs of data:
- Seeing a full LLM prompt and response may help you understand whether your product is behaving as expected.
- Logging a webhook body may help you debug issues with an external integration.
However, logging this type of data has both costs and risks:
- Users may include personal or sensitive information in an LLM prompt.
- Entire HTTP requests and responses may contain access tokens, secrets, or other sensitive data.
When possible, prefer logging the specific fields you expect to query rather
than entire payloads.
记录大型非结构化数据块有合理的理由:
- 查看完整的LLM提示和响应可能有助于你了解产品是否按预期运行。
- 记录Webhook体可能有助于你调试与外部集成相关的问题。
然而,记录这类数据既有成本也有风险:
- 用户可能在LLM提示中包含个人或敏感信息。
- 完整的HTTP请求和响应可能包含访问令牌、敏感信息或其他敏感数据。
在可能的情况下,优先记录你希望查询的特定字段,而非整个负载。
Skill-specific guidance
技能专属指南
The purpose of this skill is to demonstrate good logging practices, not to
maximize log coverage.
Prefer adding a handful of high-value log messages over instrumenting every
possible code path.
Each log message should:
- Be immediately useful when debugging production behaviour.
- Demonstrate effective use of structured logging.
- Serve as a practical example that users can follow elsewhere in the codebase.
For small codebases, add enough representative logs that the result serves as a
practical model for future instrumentation.
For large codebases, focus on a few representative locations rather than trying
to instrument everything.
Strongly prefer using the SDK's setUser functionality to associate logs with
the authenticated user, rather than repeating user identifiers as log attributes.
Only include user identifiers as log attributes when they describe something other
than the authenticated user.
本技能的目的是展示良好的日志实践,而非最大化日志覆盖范围。
优先添加少量高价值的日志消息,而非为每个可能的代码路径做埋点。
每条日志消息应:
- 在调试生产环境行为时立即有用。
- 展示结构化日志的有效使用方式。
- 作为用户可以在代码库其他地方参考的实用示例。
对于小型代码库,添加足够多的代表性日志,使其成为未来埋点的实用模型。
对于大型代码库,专注于几个代表性的位置,而非尝试为所有内容做埋点。
强烈建议使用SDK的setUser功能将日志与已认证用户关联,而非将用户标识符作为日志属性重复记录。仅当用户标识符描述的是已认证用户以外的对象时,才将其作为日志属性包含。
When the codebase already has logging
当代码库已有日志时
Before adding new log lines, inspect existing logs and identify gaps.
Prefer to:
- Improve existing logs by making them structured.
- Add missing context to existing important logs.
- Add logs only where an important production question is currently unanswered. Pay specific attention to whether the failure is already represented as an uncaught exception, and therefore likely captured by Sentry errors.
在添加新日志行之前,检查现有日志并找出空白点。
优先选择:
- 通过结构化改造优化现有日志。
- 为现有重要日志添加缺失的上下文。
- 仅在当前无法解答重要生产环境问题的位置添加日志。特别注意故障是否已被未捕获异常表示,因此可能已被Sentry错误上报捕获。