Source Mapsedit

Additional information on the source map endpoint is available in the APM Server’s source map documentation. Don’t forget, you must enable RUM support in the APM Server for this endpoint to work.

It’s a common practice to minify JavaScript bundles. However, debugging minified files is inherently difficult. To resolve this issue, you can generate source maps for your bundles and upload them to the APM server.

Here’s an example that shows how to generate source maps with webpack, and configure the JavaScript agent accordingly.

First, you need to configure webpack to generate source maps and provide the service version to your app:

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
    })
  ]
}

Or you can use current git commit hash:

const webpack = require('webpack')
const git = require('git-rev-sync')
const serviceVersion = git.short()
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
    })
  ]
}

Then you can use the provided service version to set the "serviceVersion" configuration:

import { init as initApm } from '@elastic/apm-rum'
var apm = initApm({
  // Set required service name
  serviceName: 'service-name',

  // Set service version (required for source map feature)
  serviceVersion: serviceVersion
})

Make sure to upload the generated source map file to APM server with the same "serviceVersion" and "serviceName".

Here is a Node.js example of uploading source map file to the APM server:

console.log('Uploading sourcemaps!')
var request = require('request')
var filepath = './dist/app.min.js.map'
var formData = {
  sourcemap: fs.createReadStream(filepath),
  service_version: require("./package.json").version, // Or use 'git-rev-sync' for git commit hash
  bundle_filepath: 'http://localhost/app.min.js',
  service_name: 'service-name'
}
request.post({url: 'http://localhost:8200/assets/v1/sourcemaps',formData: formData}, function (err, resp, body) {
  if (err) {
    console.log('Error while uploading sourcemaps!', err)
  } else {
    console.log('Sourcemaps uploaded!')
  }
})

You can also use curl command:

SERVICEVERSION=`node -e "console.log(require('./package.json').version);"` && \
curl http://localhost:8200/assets/v1/sourcemaps -X POST \
    -F sourcemap=@./dist/app.min.js.map \
    -F service_version="$SERVICEVERSION" \
    -F bundle_filepath="http://localhost/app.min.js" \
    -F service_name="service-name"

Or use current git commit hash:

SERVICEVERSION=`git rev-parse --short HEAD` && \
curl http://localhost:8200/assets/v1/sourcemaps -X POST \
    -F sourcemap=@./dist/app.min.js.map \
    -F service_version="$SERVICEVERSION" \
    -F bundle_filepath="http://localhost/app.min.js" \
    -F service_name="service-name"

Using a secret tokenedit

You can configure a secret token on APM Server to restrict uploading sourcemaps.

Here’s how to add the secret token to a curl command:

SERVICEVERSION=`git rev-parse --short HEAD` && \
curl http://localhost:8200/assets/v1/sourcemaps -X POST \
    -F sourcemap=@./dist/app.min.js.map \
    -F service_version="$SERVICEVERSION" \
    -F bundle_filepath="http://localhost/app.min.js" \
    -F service_name="service-name" \
    -H "Authorization: Bearer <token>"

Please note that the previously provided endpoint (/v1/rum/sourcemaps) has been deprecated and will be removed starting with APM Server version 7.0+.