正在加载

创建和上传源映射 (RUM)

Elastic Stack

在生产环境中缩小 JavaScript 包是一种常见的做法;它可以大大提高应用程序的加载时间和网络延迟。缩小代码的问题在于调试可能很困难。

为了获得最佳结果,上传源映射应成为部署过程的一部分,而不是仅在看到无用的错误时才执行的操作。这是因为在发生错误后上传源映射不会使旧错误神奇地变得可读 - 错误必须再次发生才能进行源映射。

以下是在应用程序 UI 中使用缩小代码时异常堆栈跟踪的示例。 正如你所见,它不是很有帮助。

Applications UI without source mapping

使用源映射,缩小的文件会映射回原始源代码,从而使您可以在不失去快速轻松调试应用程序的能力的情况下,保持缩小代码的速度优势。 这是与之前相同的示例,但是上传并应用了源映射

Applications UI with source mapping

请按照以下步骤启用应用程序 UI 中错误堆栈跟踪的源映射

初始化 RUM Agent 时,设置应用程序的服务名称和版本。 为了更轻松地上传后续源映射,您选择的 serviceVersion 可能是 package.json 中的 version。 例如

import { init as initApm } from '@elastic/apm-rum'
const serviceVersion = require("./package.json").version

const apm = initApm({
  serviceName: 'myService',
  serviceVersion: serviceVersion
})

或者,serviceVersion 可以是 git 提交引用。 例如

const git = require('git-rev-sync')
const serviceVersion = git.short()

它也可以是任何其他唯一的字符串,用于指示应用程序的特定版本。 APM 集成使用服务名称和版本来将正确的源映射文件匹配到每个堆栈跟踪。

为了与 Elastic APM 兼容,源映射必须遵循 源映射修订版 3 提案规范

源映射可以通过多种不同的方式生成和配置。 例如,parcel 默认情况下会自动生成源映射。 如果你使用的是 webpack,可能需要一些配置才能生成源映射

const webpack = require('webpack')
const serviceVersion = require("./package.json").version
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
  entry: 'app.js',
  output: {
    filename: 'app.min.js',
    path: './dist'
  },
  devtool: 'source-map',
  plugins: [
    new webpack.DefinePlugin({'serviceVersion': JSON.stringify(serviceVersion)}),
    new TerserPlugin({
      sourceMap: true
    })
  ]
}
  1. 如果你使用不同的方法定义 serviceVersion,可以在此处设置它。
提示

上传源映射时,请确保在 APM 集成中启用了 RUM 支持。

Kibana 公开了一个用于上传源映射的源映射端点。 源映射可以作为字符串上传,也可以作为文件上传。

让我们看看上传源映射的两种不同方法:curl 和自定义应用程序。 每个示例都包含 APM Server 以后将缩小代码映射到其源所需的四个字段

  • service_name:应与第一步中的 serviceName 匹配。
  • service_version:应与第一步中的 serviceVersion 匹配。
  • bundle_filepath:Web 应用程序中使用的最终捆绑包的绝对路径。
  • sourcemap:源映射的位置。

如果你有多个源映射,则需要单独上传每个源映射。

这是一个 curl 请求示例,该请求上传在上一步中创建的源映射文件。 此请求使用 API 密钥进行身份验证。

 SERVICEVERSION=`node -e "console.log(require('./package.json').version);"` && \ <1> curl -X POST "http://localhost:5601/api/apm/sourcemaps" \
-H 'Content-Type: multipart/form-data' \
-H 'kbn-xsrf: true' \
-H 'Authorization: ApiKey ${YOUR_API_KEY}' \
-F 'service_name=foo' \
-F 'service_version=$SERVICEVERSION' \
-F 'bundle_filepath=/test/e2e/general-usecase/app.min.js' \
-F 'sourcemap=@./dist/app.min.js.map'
  1. 此示例使用 package.json 中的版本
  2. 此处使用的 API 密钥需要具有适当的权限。 请参阅 Elastic StackServerless API 文档。

为了确保上传源映射成为部署过程的一部分,请考虑使用自定义应用程序自动化该过程。 这是一个 Node.js 应用程序示例,该应用程序上传在上一步中创建的源映射文件

console.log('Uploading sourcemaps!')
var request = require('request')
var filepath = './dist/app.min.js.map'
var formData = {
  headers: {
    Content-Type: 'multipart/form-data',
    kbn-xsrf: 'true',
    Authorization: 'ApiKey ${YOUR_API_KEY}'
  },
  service_name: 'service-name’,
  service_version: require("./package.json").version,
  bundle_filepath: 'http://localhost/app.min.js',
  sourcemap: fs.readFileSync(filepath, { encoding: 'utf-8' })
}
request.post({url: 'http://localhost:5601/api/apm/sourcemaps',formData: formData}, function (err, resp, body) {
  if (err) {
    console.log('Error while uploading sourcemaps!', err)
  } else {
    console.log('Sourcemaps uploaded!')
  }
})
  1. 或者使用 'git-rev-sync' 获取 git 提交哈希

源映射存储在 Elasticsearch 中。 上传源映射时,将创建一个新的 Elasticsearch 文档,其中包含源映射的内容。 当收到 RUM 请求时,APM Server 将利用这些源映射文档将源映射逻辑应用于事件的堆栈跟踪。

© . All rights reserved.