传统上传方法

了解如何使用较旧的 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 属性:

Copied
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 创建一个版本。版本名称在您的组织内必须是唯一的:

Copied
sentry-cli releases new <release_name>

接下来,上传您的工件(最小化源文件和源映射文件):

Copied
sentry-cli sourcemaps upload --release=<release_name> /path/to/directory

假设您已安装了版本 1.x@sentry/webpack 包,您可以参考 Sentry webpack 插件 v1 文档 了解如何配置插件。

示例:

webpack.config.js
Copied
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.initrelease 选项与插件的 release 选项完全匹配:

Copied
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
Copied
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.initrelease 选项与插件的 release.name 选项完全匹配:

Copied
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"
});

如果您按照上述所有步骤操作但仍无法使用旧版方法设置源映射,本节将帮助您排查问题。

要排查源映射设置,您可以选择以下方法之一:

  1. 使用 sentry-cli 内置的自动化验证工具,或
  2. 按照以下列出的手动步骤进行

要使用自动化验证过程,请安装并配置 Sentry 命令行界面。然后,使用 sourcemaps explain 命令,并通过在 sentry.io问题详情 页面左上角找到的相关事件 ID 来调用该命令。

例如,“事件 ID: c2ad049f”:

突出显示在 Sentry 上查找事件 ID 的位置的图片

Copied
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.jsabs_path 在每个堆栈跟踪帧中都会出现一次——请将其与未解压缩的文件匹配)。您可以在问题页面顶部的事件发生日期旁边找到指向 JSON 视图的链接。上传的工件名称必须与这些值匹配。

如果您在路径中有 动态值(例如,https://www.site.com/{some_value}/scripts/script.js),您可能需要使用 rewriteFrames 集成

如果您的 sourceMappingURL 注释类似于:

Copied
// -- end script.min.js (located at http://localhost:8000/scripts/script.min.js)
//# sourceMappingURL=script.min.js.map

一个正确的 sentry-cli 命令示例如下(假设您在 /scripts 目录中,从上一级目录运行 Web 服务器,因此我们使用 --url-prefix 选项):

Copied
sentry-cli sourcemaps upload --url-prefix '~/scripts' .

此命令会上传当前目录中的所有 JavaScript 文件。Sentry 中的工件页面现在应显示如下:

Copied
~/scripts/script.js
~/scripts/script.min.js
~/scripts/script.min.js.map

或者,您可以指定要上传的文件。例如:

Copied
sentry-cli sourcemaps upload --url-prefix '~/scripts' script.min.js script.min.js.map

您也可以使用完全合格的 URL 进行上传。例如:

Copied
sentry-cli sourcemaps upload --url-prefix 'http://localhost:8000/scripts' .

您也可以通过 使用我们的 API 来上传工件,遵循这里解释的相同命名约定。

Copied
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.jshttp://example.com/dist/js/script.js

但不会匹配 ~/script.js

一个 Web 应用程序可以从多个源访问是相当常见的。例如:

  • 网站可以通过 httpshttp 访问
  • 地理位置相关的 Web 地址:如 https://us.example.comhttps://eu.example.com
  • 多个静态 CDN:如 https://static1.example.comhttps://static2.example.com
  • 客户特定的域名或子域名

在这种情况下,相同的 JavaScript 和源映射文件可能位于两个或多个不同的源中。在这种情况下,我们建议在路径上使用我们特殊的波浪号 (~) 前缀。

例如,如果您有以下文件:

您可以使用 URL ~/js/app.js 进行上传。这将告诉 Sentry 忽略域名并为任何源使用该工件。

此外,您也可以使用多个名称上传相同的文件。Sentry 在后台会自动去重这些文件。

~ 前缀告诉 Sentry,对于给定的 URL,任何 协议和主机名组合,只要路径是 /js/app.js,都应使用此工件。仅当您的源文件和源映射文件在所有可能的协议/主机名组合中完全相同时,才使用此方法。如果存在完整的 URL,Sentry 会优先使用完整的 URL 而不是带波浪号前缀的路径

您打包或最小化后的 JavaScript 文件最后一行的 sourceMappingURL 注释告诉 Sentry(或浏览器)在哪里查找相应的源映射文件。这可以是一个完全合格的 URL、相对路径或文件名本身。在将工件上传到 Sentry 时,您必须使用文件解析的值来命名源映射文件。

也就是说,如果您的文件类似于:

Copied
// -- 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)。

或者,如果您的文件类似于:

Copied
//-- 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)。

最后,如果您的文件类似于:

Copied
//-- 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 模块:

Copied
npm install -g source-map

然后,编写一个 Node.js 脚本来读取您的源映射文件并测试映射。以下是一个示例:

Copied
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 uploadfiles 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 会以一种方式覆盖捕获的堆栈跟踪,从而阻止我们的源映射处理器正确解析它。