传统上传方法
了解如何使用较旧的 SDK 和 Sentry 工具上传源映射。
Sentry 已迁移到新的源映射处理流程,我们称之为“使用调试 ID 的源映射”。
此流程要求您使用更新的 Sentry 依赖项。我们知道这并不总是可行,因此本页面解释了如何在不使用调试 ID 的情况下上传源映射。
如果您使用的是以下任意一项,请参考本页面的指南:
- JavaScript SDK 版本
7.46.0
或更低 @sentry/webpack-plugin
包版本1.x
或更低sentry-cli
版本2.16.1
或更低- Sentry 自托管或单租户版本
23.6.1
或更低
如果您的所有 Sentry 依赖项都比上述列表中的版本更新,我们建议使用常规的 源映射指南。
如果您使用的是这些工具的一个或多个旧版本,您仍然可以上传源映射;但是,流程会有所不同。您将使用 版本 来匹配事件的堆栈帧与其对应的最小化源文件和源映射文件(统称为工件),而不是使用调试 ID。
要使用本指南,请滚动到与您使用的工具相对应的部分,并按照该部分的步骤操作:
sentry-cli
- Sentry webpack 插件版本 1.x
- Sentry 打包插件版本 2.x
最后的 “验证工件已上传” 部分适用于每种类型的工具。
为了将事件与正确的版本匹配,您必须在 SDK 配置选项中提供 release
属性:
Sentry.init({
// This value must be identical to the name you give the release that you
// create below using `sentry-cli`.
release: "<release_name>",
});
您必须首先使用 sentry-cli
创建一个版本。版本名称在您的组织内必须是唯一的:
sentry-cli releases new <release_name>
接下来,上传您的工件(最小化源文件和源映射文件):
sentry-cli sourcemaps upload --release=<release_name> /path/to/directory
假设您已安装了版本 1.x
的 @sentry/webpack
包,您可以参考 Sentry webpack 插件 v1 文档 了解如何配置插件。
示例:
webpack.config.js
const SentryWebpackPlugin = require("@sentry/webpack-plugin");
module.exports = {
// ... other config above ...
devtool: "source-map", // Source map generation must be turned on
plugins: [
new SentryWebpackPlugin({
org: "example-org",
project: "example-project",
// Specify the directory containing build artifacts
include: "./dist",
// Auth tokens can be obtained from
// https://sentry.io/orgredirect/organizations/:orgslug/settings/auth-tokens/
authToken: process.env.SENTRY_AUTH_TOKEN,
// Optionally uncomment the line below to override automatic release name detection
// release: process.env.RELEASE,
}),
],
};
Sentry webpack 插件会自动将版本值注入 SDK,因此您必须从 Sentry.init
中省略 release
选项,或者确保 Sentry.init
的 release
选项与插件的 release
选项完全匹配:
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
// When using the plugin, either remove the `release`` property here entirely or
// make sure that the plugin's release option and the Sentry.init()'s release
// option match exactly.
// release: "my-example-release-1"
});
如果您使用的是:
- Sentry 自托管或单租户版本
23.6.1
或更低 - 或者 Sentry JavaScript SDK 版本
7.46.0
- 或者带有
splitting: true
的 esbuild
您需要使用 release.uploadLegacySourcemaps
选项配置打包插件。
这适用于在版本 2.x
及以上使用以下包的情况:
@sentry/webpack-plugin
@sentry/vite-plugin
@sentry/esbuild-plugin
@sentry/rollup-plugin
使用 release.uploadLegacySourcemaps
选项的示例:
webpack.config.js
const { sentryWebpackPlugin } = require("@sentry/webpack-plugin");
module.exports = {
// ... other config above ...
devtool: "source-map", // Source map generation must be turned on
plugins: [
sentryWebpackPlugin({
org: "example-org",
project: "example-project",
// Auth tokens can be obtained from your User Settings
// and need `project:releases` and `org:read` scopes
authToken: process.env.SENTRY_AUTH_TOKEN,
release: {
uploadLegacySourcemaps: {
paths: ["."],
ignore: ["./node_modules"],
},
},
}),
],
};
Sentry 打包插件会自动将版本值注入 SDK,因此您必须从 Sentry.init
中省略 release
选项,或者确保 Sentry.init
的 release
选项与插件的 release.name
选项完全匹配:
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
// When using one of the plugins, either remove the `release`` property here entirely or
// make sure that the plugin's `release.name` option and the Sentry.init()'s release
// option match exactly.
// release: "my-example-release-1"
});
如果您按照上述所有步骤操作但仍无法使用旧版方法设置源映射,本节将帮助您排查问题。
要排查源映射设置,您可以选择以下方法之一:
- 使用
sentry-cli
内置的自动化验证工具,或 - 按照以下列出的手动步骤进行
要使用自动化验证过程,请安装并配置 Sentry 命令行界面。然后,使用 sourcemaps explain
命令,并通过在 sentry.io 的 问题详情 页面左上角找到的相关事件 ID 来调用该命令。
注意
sourcemaps explain
命令需要具有以下作用域的身份验证令牌:project:admin
、release:admin
、event:read
和 organization:read
。我们建议创建一个 内部集成令牌 而不是个人令牌。
例如,“事件 ID: c2ad049f”:
sentry-cli sourcemaps explain c2ad049fd9e448ada7849df94575e019
CLI 输出应为您提供有关源映射设置问题的有用信息。
为了使上传的源映射能够被定位和应用,版本需要通过 CLI 或 API 创建(并正确上传相关工件),并且新创建的版本名称需要在您的 SDK 配置中指定。
要验证这一点,请从 Sentry UI 打开问题并检查是否已配置版本。如果在屏幕右侧的 版本 旁边显示“未配置”或“N/A”(或如果您在标签列表中未看到 release
标签),您需要返回并 标记您的错误。如果配置正确,您将看到“版本: my_example_release”。
一旦您的版本配置正确且问题已标记,您可以通过导航到 [设置] > 项目 > 选择您的项目 > 源映射 来查找已上传到 Sentry 的工件。
此外,确保所有必要的文件都可用。为了让 Sentry 解压缩您的堆栈跟踪,您必须提供最小化文件(例如,app.min.js
)和相应的源映射文件。如果源映射文件不包含您的原始源代码,
一些 CDN 会自动从静态文件(包括 JavaScript 文件)中移除注释。这可能会导致您的 JavaScript 文件中的 sourceMappingURL
指令被移除,因为它被视为注释。例如,CloudFlare 有一个名为 Auto-Minify 的功能,如果启用,它会移除 sourceMappingURL
。
请仔细检查您部署的最终 JavaScript 文件中是否包含 sourceMappingURL
。
每当您使用分发标识符(SDK 中的 dist
配置选项)时,上传源映射时也必须使用相同的值。反之,如果您的源映射在上传时带有 dist
值,则 SDK 中也必须设置相同的值。
要为上传的源映射添加 dist
值,请使用 sentry-cli
的 --dist
标志或我们 Sentry 打包插件(例如 @sentry/webpack-plugin
)中的 dist
选项。要在 SDK 中设置 dist
值,请在 Sentry.init()
中使用 dist
选项。
要验证 SDK 中的分发值是否正确设置,请在 Sentry UI 中打开一个问题并检查是否存在 dist
标签。对于工件,转到项目设置中的 源映射
页面。
如果您已上传源映射,但它们并未应用到 Sentry 中的问题代码,请查看事件的 JSON,查找 abs_path
以确定我们尝试解析文件的确切位置——例如,http://localhost:8000/scripts/script.js
(abs_path
在每个堆栈跟踪帧中都会出现一次——请将其与未解压缩的文件匹配)。您可以在问题页面顶部的事件发生日期旁边找到指向 JSON 视图的链接。上传的工件名称必须与这些值匹配。
如果您在路径中有 动态值(例如,https://www.site.com/{some_value}/scripts/script.js
),您可能需要使用 rewriteFrames
集成。
如果您的 sourceMappingURL
注释类似于:
// -- end script.min.js (located at http://localhost:8000/scripts/script.min.js)
//# sourceMappingURL=script.min.js.map
一个正确的 sentry-cli
命令示例如下(假设您在 /scripts
目录中,从上一级目录运行 Web 服务器,因此我们使用 --url-prefix
选项):
sentry-cli sourcemaps upload --url-prefix '~/scripts' .
此命令会上传当前目录中的所有 JavaScript 文件。Sentry 中的工件页面现在应显示如下:
~/scripts/script.js
~/scripts/script.min.js
~/scripts/script.min.js.map
或者,您可以指定要上传的文件。例如:
sentry-cli sourcemaps upload --url-prefix '~/scripts' script.min.js script.min.js.map
您也可以使用完全合格的 URL 进行上传。例如:
sentry-cli sourcemaps upload --url-prefix 'http://localhost:8000/scripts' .
您也可以通过 使用我们的 API 来上传工件,遵循这里解释的相同命名约定。
curl -X POST \
https://sentry.io/api/0/organizations/ORG_SLUG/releases/VERSION/files/ \
-H 'Authorization: Bearer AUTH_TOKEN' \
-H 'content-type: multipart/form-data' \
-F file=@script.min.js.map \
-F 'name=~/scripts/script.min.js.map'
在 Sentry 中,~
用于替换方案和域名。它不是一个通配符!
http://example.com/dist/js/script.js
将匹配 ~/dist/js/script.js
或 http://example.com/dist/js/script.js
但不会匹配 ~/script.js
。
一个 Web 应用程序可以从多个源访问是相当常见的。例如:
- 网站可以通过
https
和http
访问 - 地理位置相关的 Web 地址:如
https://us.example.com
、https://eu.example.com
- 多个静态 CDN:如
https://static1.example.com
、https://static2.example.com
- 客户特定的域名或子域名
在这种情况下,相同的 JavaScript 和源映射文件可能位于两个或多个不同的源中。在这种情况下,我们建议在路径上使用我们特殊的波浪号 (~
) 前缀。
例如,如果您有以下文件:
您可以使用 URL ~/js/app.js
进行上传。这将告诉 Sentry 忽略域名并为任何源使用该工件。
此外,您也可以使用多个名称上传相同的文件。Sentry 在后台会自动去重这些文件。
~
前缀告诉 Sentry,对于给定的 URL,任何 协议和主机名组合,只要路径是 /js/app.js
,都应使用此工件。仅当您的源文件和源映射文件在所有可能的协议/主机名组合中完全相同时,才使用此方法。如果存在完整的 URL,Sentry 会优先使用完整的 URL 而不是带波浪号前缀的路径。
您打包或最小化后的 JavaScript 文件最后一行的 sourceMappingURL
注释告诉 Sentry(或浏览器)在哪里查找相应的源映射文件。这可以是一个完全合格的 URL、相对路径或文件名本身。在将工件上传到 Sentry 时,您必须使用文件解析的值来命名源映射文件。
也就是说,如果您的文件类似于:
// -- end script.min.js
//# sourceMappingURL=script.min.js.map
如果您的源映射文件位于 http://example.com/js/script.min.js.map
,那么您上传的工件必须命名为 http://example.com/js/script.min.js.map
(或 ~/js/script.min.js.map
)。
或者,如果您的文件类似于:
//-- end script.min.js
//# sourceMappingURL=https://example.com/dist/js/script.min.js.map
那么您上传的工件也应命名为 https://example.com/dist/js/script.min.js.map
(或 ~/dist/js/script.min.js.map
)。
最后,如果您的文件类似于:
//-- end script.min.js
//# sourceMappingURL=../maps/script.min.js.map
那么您上传的工件应命名为 https://example.com/dist/maps/script.min.js.map
(或 ~/dist/maps/script.min.js.map
)。
Sentry 期望给定版本中的源代码和源映射文件在错误发生 之前 已上传到 Sentry。
如果您在 Sentry 捕获错误 之后 上传工件,Sentry 不会回溯并重新应用任何源注释到这些错误。只有在工件上传后触发的新错误才会受到影响。
我们维护了一个在线验证工具,可以用来测试您的源映射与您 托管的 源代码:sourcemaps.io。
或者,如果您使用 Sentry CLI 将源映射上传到 Sentry,您可以使用命令行选项 --validate
来验证源映射是否正确。
如果您发现 Sentry 未能正确映射文件名、行号或列号,您应该验证源映射是否在本地正常工作。为此,您可以使用 Node.js 结合 Mozilla 的 source-map 库。
首先,全局安装 source-map
作为 npm 模块:
npm install -g source-map
然后,编写一个 Node.js 脚本来读取您的源映射文件并测试映射。以下是一个示例:
var fs = require("fs"),
path = require("path"),
sourceMap = require("source-map");
// Path to file that is generated by your build tool (webpack, tsc, ...)
var GENERATED_FILE = path.join(".", "app.min.js.map");
// Line and column located in your generated file (for example, the source
// of the error from your minified file)
var GENERATED_LINE_AND_COLUMN = { line: 1, column: 1000 };
var rawSourceMap = fs.readFileSync(GENERATED_FILE).toString();
new sourceMap.SourceMapConsumer(rawSourceMap).then(function (smc) {
var pos = smc.originalPositionFor(GENERATED_LINE_AND_COLUMN);
// You should see something like:
// { source: 'original.js', line: 57, column: 9, name: 'myfunc' }
console.log(pos);
});
如果在本地和通过 Sentry 获取的结果相同(且不正确),请仔细检查您的源映射生成配置。
对于单个工件,Sentry 接受的最大文件大小为 40 MB。
用户经常遇到此限制是因为他们在中间构建阶段传输源文件。例如,在打包器合并所有源文件之后,但在最小化(minification)之前:
Sentry API 当前仅支持以纯文本(UTF-8 编码)格式上传的源映射和源文件。如果文件以压缩格式(例如,gzip)上传,则无法正确解析。
如果您使用 sentry-cli
上传工件,从版本 2.4.0
开始,您可以在 sourcemaps upload
或 files upload
命令中添加 --decompress
标志。
有时构建脚本和插件会生成预压缩的最小化文件(例如,webpack 的 compression plugin)。在这些情况下,您需要禁用此类插件,并在生成的源映射/源文件上传到 Sentry 之后 再进行压缩。
如果您正在运行自托管版本的 Sentry,可以通过检查容器的日志来验证 symbolicator
服务/容器是否正常运行。
Sentry 在其工作进程中进行源映射计算。这意味着工作进程需要访问通过前端上传的文件。请确保 cron 工作进程和 Web 工作进程可以从同一磁盘读取和写入文件。
如果尚未将源映射上传到 Sentry,Sentry Node.js SDK 通常可以很好地与 source-map-support 包一起工作。
但是,如果您正在将源映射上传到 Sentry,或者在浏览器中使用 Sentry SDK,则您的代码不能使用 source-map-support
包。source-map-support
会以一种方式覆盖捕获的堆栈跟踪,从而阻止我们的源映射处理器正确解析它。