写在前面
在APM中集成前端监控可分为以下步骤:
- 初始化APM,与 APM Server 建立“连接”
- 上传 sourcemap 到 APM Server,跟踪代码抛出的错误
- 使用 gitlab 控制只在发布版本时上传
- 删除 sourcemap 文件,防止和源代码一起部署到线上
初始化apm依赖(实现监控)
import { init as initApm } from '@elastic/apm-rum'
const apm = initApm({
// apm 服务器上的项目名称
serviceName: '',
// apm 服务器的地址,注意结尾不要手误多加斜杆“/”, 如:https://apm.myApmServer.com/
serverUrl: 'https://apm.myApmServer.com',
// apm 服务的版本,如果你想要错误信息跟踪到行的级别,这里是必填的并且要与上传source map的版本相同。
serviceVersion: '', // 一般直接取package.json中的版本
// Set the service environment
environment: '' // 环境变量,可用于在kibana平台中过滤指定的环境
})
复制代码
启动项目后会通过 Ajax 向 APM 服务器发送日志。
在kibana的APM控制台中就可以看到对应的项目
配置 webpack 上传 source map文件(实现错误追踪)
source map
不了解 Source Map
可以看一下阮一峰写的文章 JavaScripte Source Map,也可以跳过,下面做出简单介绍:
打包产生的文件中以 .map
结尾的就是 source map
文件,对应的是浏览器中运行的源文件
上传
两种方法
- 自己写一个上传的请求 apply source maps to error stack traces
- 使用第三方依赖,使用 elastic-apm-sourcemap-webpack-plugin 插件来上传
source map
文件
下面只对第二种方法做出介绍
创建一个 production 环境的 webpack
配置文件
// webpack.config.prod.js
const serviceVersion = require('./package.json').version
const ElasticAPMSourceMapPlugin = require('elastic-apm-sourcemap-webpack-plugin').default
module.export = {
mode:'production',
devtool: 'source-map', // 配置devtool
plugins: [
new webpack.DefinePlugin({'serviceVersion': serviceVersion}),
new ElasticAPMSourceMapPlugin({
serviceName: 'SERVICE_NAME',
serviceVersion: 'SERVICE_VERSION', // 使用package.json的版本号
// apm服务器上用来存放sourcemap资源的位置
serverURL: 'http://apm.youApmServer.com/assets/v1/sourcemaps', // /assets/v1/sourcemaps 路径是固定的
publicPath: PUBLIC_PATH, // 你的项目域名
logLevel: 'debug'
})
]
}
复制代码
配置yaml控制何时上传source-map (优化)
一般在打包的时候webpack默认mode就是production,这会导致每次打包都会以 sourcemap 方式打包并上传到 APM Server。而往往并不是任何时候打包都需要上传sourcemap,只想在项目发布版本时上传sourcemap。
如果项目中使用了一些 CI/CD
来自动化构建项目,一般都会用到 yaml
文件来控制整个流程,最基本的过程一般包括这几点 test -> build -> deploy
,下面主要在项目打包时做文章。
以 Gitlab CI 为例子 下面是一段 .gitlab-ci.yml
配置
//.gitlab-ci.yml
stages:
- build
- deploy
build-latest:
stage: build
artifacts:
paths:
- dist/
script:
- yarn install
- yarn build:dev
except:
- tags
build-tag:
stage: build
artifacts:
paths:
- dist/
script:
- yarn install
- yarn build:prod
only:
- tags
复制代码
当打包的 git
分支被标记为 tag
(如发布1.0.1版本)时走 build-tag
,其余的都走 build-lateset
这样就实现了发布一个版本时走不同的命令。此逻辑主要是通过 expect
和 only
来控制的。
当执行 yarn build:prod
和 yarn build:dev
命令时走不同的 webpack
配置文件即可,package.json
的scripts
属性中配置命令:
// package.json
{
"scripts":{
"build:dev": "cross-env NODE_ENV=dev webpack --config webpack.config.dev.js",
"build:prod": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
}
}
复制代码
删除 sourcemap 文件
如果将 sourcemap 一起和源文件部署到线上存在一些安全、信息泄露问题。
可以使用 delete-source-maps-webpack-plugin 插件删除打包后产生的所有sourcemap文件
// webpack.config.prod.js
const serviceVersion = require('./package.json').version
const ElasticAPMSourceMapPlugin = require('elastic-apm-sourcemap-webpack-plugin').default
const DeleteSourceMapsWebpackPlugin = require('delete-source-maps-webpack-plugin').default
module.export = {
mode:'production',
devtool: 'source-map', // 配置devtool
plugins: [
new DeleteSourceMapsWebpackPlugin(),
new webpack.DefinePlugin({'serviceVersion': serviceVersion}),
new ElasticAPMSourceMapPlugin({
serviceName: 'SERVICE_NAME',
serviceVersion: 'SERVICE_VERSION', // 使用package.json的版本号
// apm服务器上用来存放sourcemap资源的位置
serverURL: 'http://apm.youApmServer.com/assets/v1/sourcemaps', // /assets/v1/sourcemaps 路径是固定的
publicPath: PUBLIC_PATH, // 你的项目域名
logLevel: 'debug'
})
]
}
复制代码