Translate JavaScript stack traces captured by the Honeycomb OpenTelemetry Web SDK into human-readable formats using Honeycomb’s Symbolicator Processor for the OpenTelemetry Collector.
Honeycomb’s Symbolicator Processor makes JavaScript stack traces captured by the Honeycomb OpenTelemetry Web SDK easier to read by translating obfuscated or minified function names and addresses into human-readable formats (a process called symbolication) as they pass through your OpenTelemetry Collector.
Adding the Symbolicator Processor to your OpenTelemetry Collector automates this process, making debugging easier.
The Symbolicator Processor uses source maps to reconstruct the original source code from transformed stack traces. It supports:
Before you start, make sure:
You’re using the Honeycomb OpenTelemetry Web SDK v0.12.0 or later.
CGO is enabled. The processor relies on C libraries, so CGO must be enabled when building your OpenTelemetry Collector.
You’re using a compatible base image. If you’re using a custom-built OpenTelemetry Collector instance, it must support glibc
.
We recommend using gcr.io/distroless/cc
, a lightweight container image that includes both CGO and glibc
support, and is designed for security and minimalism.
To install the Symbolicator Processor, add it to your OpenTelemetry distribution’s build configuration file:
processors:
- gomod: github.com/honeycombio/opentelemetry-collector-symbolicator/symbolicatorprocessor v0.0.0
name: symbolicatorprocessor
path: ./symbolicatorprocessor
Alternatively, you can use the pre-built, custom Honeycomb OpenTelemetry Collector distro, which includes this processor by default.
After installing the Symbolicator Processor, you must register it in your OpenTelemetry Collector configuration.
To do this, add the processor to the processors
section of your configuration file:
processors:
symbolicator:
You can then configure the processor’s behavior by specifying settings, such as source map locations, file paths, and other options.
You can configure the processor to retrieve JavaScript source files and their corresponding source maps from one of the following storage locations:
Choose the appropriate storage method based on your infrastructure, ensuring that source maps are stored in a format the processor can recognize.
Before configuring a file store, make sure your JavaScript source files and source maps are correctly set up to support symbolication:
Provide both minimized Javascript files and source maps. The processor requires access to both your minimized JavaScript source files and their corresponding source maps, which are generated during your build process.
Use versioned file names with a hash.
To prevent conflicts and ensure the correct file versions are used, include a hash in the file names of both source and source map files (for example, main.c383b093b0b66825a9c3.js
).
Include sourceMappingURL
in Javascript source files.
Minimized JavaScript source files must contain a sourceMappingURL
comment at the end, pointing to the relative path of the source map file.
For example:
//# sourceMappingURL=/static/dist/main.c383b093b0b66825a9c3.js.map
Ensure file paths align with stack trace locations. The processor extracts file paths from stack traces and uses them to locate the corresponding source maps. Verify that file paths in stack traces match the structure used in your configured file store.
By default, the processor loads source files from a local directory. Specify the file path in your OpenTelemetry Collector configuration:
processors:
symbolicator:
source_map_store: file_store # Specify the file store to use (in this case, local disk)
local_source_maps: # Configure loading source maps from local disk
path: /tmp/sourcemaps # (optional) Set the base path for the files. Defaults to ".".
Verify that:
Each line of the stack trace includes the URL of the file it originated from. When retrieving source files from local disk, the processor:
Extracts the file path from the stack trace.
Example origin file URL: https://example.com/static/dist/main.c383b093b0b66825a9c3.js
Extracted path: /static/dist/main.c383b093b0b66825a9c3.js
.
Prepends the configured path
to the extracted path:
Example path
: /tmp/sourcemaps
Final path: /tmp/sourcemaps/static/dist/main.c383b093b0b66825a9c3.js.map
Uses the combined path to read the source map file from the local disk.
Optionally, you can load source files from an AWS S3 bucket. Add to your OpenTelemetry Collector configuration:
processors:
symbolicator:
source_map_store: s3_store # Specify the file store to use (in this case, S3)
s3_source_maps: # Configure loading source maps from S3
bucket: source-maps-bucket # Specify the name of the bucket the files are stored in
region: us-east-1 # (optional) Configure the geographical location of the bucket
prefix: source-maps # (optional) Specify the key the files are stored under
Verify that:
Each line of the stack trace includes the URL of the file it originated from. When retrieving source files from an S3 bucket, the processor:
Extracts the file path from the stack trace.
Example origin file URL: https://example.com/static/dist/main.c383b093b0b66825a9c3.js
Extracted path: /static/dist/main.c383b093b0b66825a9c3.js
.
If you configure a prefix
, prepends the prefix to the extracted path to create a key:
Example prefix
: source-maps
Final S3 key: source-maps/static/dist/main.c383b093b0b66825a9c3.js.map
Uses the key to retrieve the source map from the specified S3 bucket.
Optionally, you can load source files from a Google Cloud Storage (GCS) bucket. Add to your OpenTelemetry Collector configuration:
processors:
symbolicator:
source_map_store: gcs_store # Specify the file store to use (in this case, GCS)
gcs_source_maps: # Configure loading source maps from GCS
bucket: source-maps-bucket # Specify the name of the bucket the files are stored in
prefix: source-maps # (optional) Specify the key the files are stored under
Verify that:
storage.objects.get
access.Each line of the stack trace includes the URL of the file it originated from. When retrieving source files from a GCS bucket, the processor:
Extracts the file path from the stack trace.
Example origin file URL: https://example.com/static/dist/main.c383b093b0b66825a9c3.js
Extracted path: /static/dist/main.c383b093b0b66825a9c3.js
.
If you configure a prefix
, prepends the prefix to the extracted path to create a key:
Example prefix
: source-maps
Final GCS key: source-maps/static/dist/main.c383b093b0b66825a9c3.js.map
Uses the key to retrieve the source map from the specified GCS bucket.
The Symbolicator Processor requires exception stack traces to be formatted into distinct attributes:
columns
: Column numbers in the source file where the error occurred.functions
: Function names corresponding to each stack frame. If unknown, use "?"
.lines
: Line numbers in the source file where the error occurred.urls
: URLs of the JavaScript files referenced in the stack trace.Each of these attributes must be an array (slice
), and all four arrays must have the same length, with corresponding entries aligned across them.
For example:
columns: [6465,3512358,3512661,3514018,758545]
functions: ["?","w.callback","push.Br+g.w.crossDomainError","XMLHttpRequest.<anonymous>","XMLHttpRequest.<anonymous>"]
lines: [3582,2,2,2,2]
urls: ["https://example.com/static/dist/main.c383b093b0b66825a9c3.js","https://example.com/static/dist/vendor.1c285a50f5307be9648d.js","https://example.com/static/dist/vendor.1c285a50f5307be9648d.js","https://example.com/static/dist/vendor.1c285a50f5307be9648d.js","https://example.com/static/dist/vendor.1c285a50f5307be9648d.js"]
Ensure proper formatting of stack trace data by checking for:
n
th element in each array must correspond to the same stack frame.urls
array must contain fully qualified URLs that match the structure used when retrieving source maps.In addition to basic setup, you can customize how the Symbolicator Processor handles stack traces by configuring attribute mappings and additional processing options.
Use these configuration options to specify which attributes the processor should read from and write to when handling stack traces:
Configuration Key | Description | Example Value |
---|---|---|
symbolicator_failure_attribute_key |
Indicates whether the symbolicator failed to fully process the stack trace. | exception.symbolicator.failed |
columns_attribute_key |
Attribute containing the column numbers of the source stack trace. | exception.structured_stacktrace.columns |
functions_attribute_key |
Attribute containing the function names for the source stack trace. | exception.structured_stacktrace.functions |
lines_attribute_key |
Attribute containing the line numbers of the source stack trace. | exception.structured_stacktrace.lines |
urls_attribute_key |
Attribute containing the script URLs associated with the source stack trace. | exception.structured_stacktrace.urls |
output_stack_trace_key |
Attribute where the symbolicated stack trace should be stored. | exception.stacktrace |
stack_type_key |
Attribute containing the exception type. | exception.type |
stack_message_key |
Attribute containing the exception message. | exception.message |
preserve_stack_trace |
Indicates whether to retain the original stack trace values as attributes after symbolication (true to preserve). |
true |
original_stack_trace_key |
If preservation is enabled, key used to store the original stack trace. | exception.stacktrace.original |
original_columns_attribute_key |
If preservation is enabled, key used to store the original column numbers. | exception.structured_stacktrace.functions.original |
original_functions_attribute_key |
If preservation is enabled, key used to store the original function names. | exception.structured_stacktrace.lines.original |
original_lines_attribute_key |
If preservation is enabled, key used to store the original line numbers. | exception.structured_stacktrace.columns.original |
original_urls_attribute_key |
If preservation is enabled, key used to store the original script URLs. | exception.structured_stacktrace.urls.original |
Use these configuration options to control how stack traces are processed and managed:
Config Key | Description | Example Value |
---|---|---|
timeout |
Maximum time (in seconds) to wait for symbolication before timing out. | 5 |
source_map_cache_size |
Maximum number of source maps to cache in memory. Reduce this value if the Collector encounters memory constraints. | 128 |