Sentry 支持通过 source maps(源代码映射)对 JavaScript 进行 un-minifying,这允许您以原始的未转换形式查看从堆栈跟踪中获得的源代码上下文。这对于调试压缩后的代码(例如,UglifyJS
)或从高级语言编译的代码(如 TypeScript
和 ES6
)特别有用。
Sentry 将通过抓取堆栈跟踪中的 URL 自动获取源代码(source code
)和源代码映射(source maps
)。但是,您可能有正当的理由在 Sentry 中 disabling the JavaScript source fetching in Sentry(在 Sentry 中禁用 JavaScript 源代码获取)。
Capturing Source Maps
大多数现代 JavaScript 编译器都支持 source maps。下面你会发现我们推荐的说明,但我们也提供了各种常用工具的说明:
- Webpack
- TypeScript
- UglifyJS
- SystemJS
我们建议使用 Sentry's Webpack plugin 来配置 source maps 并在构建过程中自动上传它们:
npm install --save-dev @sentry/webpack-plugin or yarn add --dev @sentry/webpack-plugin
接下来,您需要为我们的 API 生成 access token。在您的组织设置中,导航到 Developer Settings
,create a new internal integration,并提供一个适合您组织的名称。重要: 选择 Releases -> Admin,针对权限。
Releases -> Admin 权限在其他 API 文档中也称为 'project:releases'。
你可以通过它的文档机制来配置 sentry-cli,或者在初始化插件时简单地绑定所需的参数:
const SentryWebpackPlugin = require("@sentry/webpack-plugin"); module.exports = { // other configuration configureWebpack: { plugins: [ new SentryWebpackPlugin({ // sentry-cli configuration authToken: process.env.SENTRY_AUTH_TOKEN, org: "exmaple-org", project: "example-project", // webpack specific configuration include: ".", ignore: ["node_modules", "webpack.config.js"], }), ], }, };
在 Vue 2.x 中,应使用 vue.config.js
而不是 webpack.config.js
,并使用 include: "./dist"
而不是 include: "."
。
Hosting Publicly
默认情况下,Sentry 将在已编译的 JavaScript 文件中查找源映射指令(source map directives),这些指令位于最后一行,并具有以下格式:
//# sourceMappingURL=<url>
当 Sentry 遇到这样一个指令时,它将解析与它所在的源文件相关的 source map URL,并尝试使用 HTTP 请求获取它。
例如,如果您有一个压缩的 JavaScript 文件位于 http://example.org/js/app.min.js
,并且在该文件的最后一行中,则找到以下指令:
//# sourceMappingURL=app.js.map
Sentry 将尝试从 http://example.org/js/app.js.map
获取 app.js.map
。
另外,在生成源代码映射时,你可以指定源代码映射所在的绝对 URL:
//# sourceMappingURL=http://example.org/js/app.js.map
虽然从服务器使 source maps 可用于 Sentry 是最自然的集成(natural integration),但并不总是建议这样做:
- Sentry 可能并不总是能够访问您的服务器。
- 如果您没有在您的 asset URLs 中指定版本,可能存在版本不匹配
- 额外的延迟可能意味着源映射对所有错误都不可用。
由于这些原因,最好的做法是预先上传 source maps 给 Sentry(见下文)。
Working Behind a Firewall
推荐的解决方案是将您的 source artifacts 上传到 Sentry,但有时有必要允许来自 Sentry 内部 IP 的通信。有关 Sentry 的公共IP 的更多信息,请参见:IP Ranges
。
Secure Access to Source Maps
如果你想保密你的 source maps 并且选择不直接上传你的 source maps 到 Sentry,你可以在你的项目设置中启用 “Security Token” 选项。
这将导致 Sentry 服务器对来自 “Allowed Domains” 的 URL 的出站请求附加 HTTP 标头 X-Sentry-Token
标头:
GET /assets/bundle.min.js X-Sentry-Token: {token}
token
是您在项目设置中定义的安全值。然后,您可以配置您的 web 服务器,以允许在此 header/token 对
存在时访问您的 source maps。你也可以覆盖默认的 header 名称(X-Sentry-Token
)并使用 HTTP Basic Authentication,例如通过传递 Authorization: Basic {encoded_password}
。
Multiple Origins
可以从多个来源访问 web 应用程序的情况并不少见。例如:
- 网站可以在
https
和http
上运行 - 地理位置网址:例如
https://us.example.com
,https://eu.example.com
- 多个静态 CDN:例如
https://static1.example.com
,https://static2.example.com
- 客户特定的域(
domains
)/子域(subdomains
)
在这种情况下,相同的 JavaScript 和 source map 文件可能位于两个或多个不同的源。在这种情况下,我们建议在路径上使用特殊的波浪号(~
)前缀。
例如,如果你有以下内容:
您可以使用 ~/js/app.js
的 URL 进行上传。这将告诉 Sentry 忽略域,并将 artifact 用于任何来源。
此外,您还可以使用多个名称上传同一文件。在后台,Sentry 会将这些重复数据删除。
~
前缀告诉 Sentry,对于给定的 URL,任何 路径为 /js/app.js
的协议和主机名的组合都应该使用这个工件(artifact)。只有当您的 source/source map 文件在所有可能的 protocol/hostname 组合上都相同时,才使用此方法。如果找到完整的 URL, Sentry 将优先使用,高于波浪前缀路径。
Tools
SystemJS
SystemJS 是 Angular 2 项目的默认模块加载器。SystemJS 构建工具可用于 bundle,transpile 和 minify 用于生产环境的源代码,并可配置为输出 source maps。
builder.bundle("src/app.js", "dist/app.min.js", { minify: true, sourceMaps: true, sourceMapContents: true, });
上面的示例配置会将您原始的(original
),未经转换(un-transformed
)的源代码内联到生成的 source map 文件中。Sentry要求 source map(s) 和原始源文件都执行反向转换。如果您选择不内联源文件,则除了源映射外,还必须使这些源文件对 Sentry 可用(请参见下文)。
TypeScript
TypeScript 编译器可以输出 source maps。将 sourceRoot
属性配置为 /
,以从生成的源代码引用中去除构建路径前缀。这允许 Sentry 匹配源文件相对于你的源根文件夹:
{ "compilerOptions": { "sourceMap": true, "inlineSources": true, "sourceRoot": "/" } }
UglifyJS
UglifyJS 是一种流行的工具,可用于压缩生产源代码。通过消除空格,重写变量名,删除无效代码分支等,它可以大大减少文件的大小。
我们强烈建议您使用更高级别的 bundler
(或 transpiler
),因为 UglifyJS
配置可能会变得非常复杂,无法达到预期的效果。
如果你正在使用 UglifyJS 来压缩你的源代码,下面的命令将额外生成一个 source map,将压缩的代码映射回原始源代码:
uglifyjs app.js \ -o app.min.js.map \ --source-map url=app.min.js.map,includeSources
Webpack
Webpack 是一个强大的构建工具,可以解析、捆绑和压缩 JavaScript 模块。它还支持各种 loaders 来转换高级语言、引用样式表或包含静态资源。
Sentry 提供了一个方便的 Webpack plugin,可以配置 source maps,并在构建时将它们上传到 Sentry。对于上传源到 Sentry,推荐使用这个过程:
npm install --save-dev @sentry/webpack-plugin or yarn add --dev @sentry/webpack-plugin
您可以通过其 documented mechanisms 来配置 sentry-cli,或者在初始化插件时仅绑定必需的参数:
const SentryWebpackPlugin = require("@sentry/webpack-plugin"); module.exports = { // other configuration configureWebpack: { plugins: [ new SentryWebpackPlugin({ // sentry-cli configuration authToken: process.env.SENTRY_AUTH_TOKEN, org: "exmaple-org", project: "example-project", // webpack specific configuration include: ".", ignore: ["node_modules", "webpack.config.js"], }), ], }, };
在 Vue 2.x 中,应使用 vue.config.js
而不是 webpack.config.js
,并使用 include: "./dist"
而不是 include: "."
。
将 SentryWebpackPlugin
设置为最后一个正在运行的插件,否则,该插件接收到的结果 source maps 可能不是最终的。
Advanced Usage
如果您希望手动上传 source maps,请将 Webpack 配置为输出 source maps:
module.exports = { output: { path: path.join(__dirname, "dist"), filename: "[name].js", sourceMapFilename: "[name].js.map", }, // other configuration };
如果使用 SourceMapDevToolPlugin 进行 source map 生成的更细粒度控制,请关闭 noSources,以便 Sentry 在事件堆栈跟踪中显示正确的源代码上下文。
此外,Webpack 插件将自动设置 window.SENTRY_RELEASE
,因此您的 Sentry.init
调用将不需要更新。