> ## Documentation Index
> Fetch the complete documentation index at: https://docs.honeycomb.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Symbolicate iOS Stack Traces with the OpenTelemetry Collector

> Use the dSYM processor in the OpenTelemetry Collector to replace obfuscated names in iOS stack traces with readable symbols for easier debugging.

export const FlexStyleTable = ({columns, overflowWrap = "normal", children}) => {
  const colWidths = columns ? columns.trim().split(/\s+/) : [];
  const scopeKey = [columns || "auto", overflowWrap].join("-").replace(/[^a-zA-Z0-9-]/g, "-");
  const colRules = colWidths.map((width, i) => `[data-fst="${scopeKey}"] table th:nth-of-type(${i + 1}) { width: ${width}; }`).join("\n");
  const css = `
    [data-fst="${scopeKey}"] table {
      table-layout: ${colWidths.length > 0 ? "fixed" : "auto"};
      width: 100%;
    }
    ${colRules}
    [data-fst="${scopeKey}"] table td { overflow-wrap: ${overflowWrap}; }
  `.trim();
  return <div className="flex-style-table" data-fst={scopeKey}>
      <style>{css}</style>
      {children}
    </div>;
};

Use the dSym processor in your OpenTelemetry Collector to symbolicate iOS stack traces.

The [dSym processor](https://github.com/honeycombio/opentelemetry-collector-symbolicator?tab=readme-ov-file#dsym-symbolication) replaces obfuscated names and addresses in your iOS stack traces with symbols from provided dSYM files.

## Before You Start

The dSym processor is compatible with [Honeycomb OpenTelemetry Swift SDK](https://github.com/honeycombio/honeycomb-opentelemetry-swift) version `0.0.14` and later.

To use the dSym processor, you need:

* OpenTelemetry Collector built with `CGO` enabled.
* An environment or container image with `glibc` support.

  We recommend `gcr.io/distroless/cc`, a secure and lightweight container image with CGO and `glibc` support.

If you're not using the Honeycomb OpenTelemetry Swift SDK, make sure your exception data is in [the format the processor expects](https://github.com/honeycombio/opentelemetry-collector-symbolicator/blob/main/README.md#exception-information-format-1).

## Install

By default, the [Honeycomb OpenTelemetry Collector distribution](https://github.com/honeycombio/honeycomb-collector-distro) includes the symbolicator processor, so you can skip to the next section if you're using it. If you use another collector distribution or build your own, it must be built with CGO enabled.

You can install the symbolicator processor by adding it to your OpenTelemetry Collector build configuration file:

```yaml theme={}
processors:
  - gomod: github.com/honeycombio/opentelemetry-collector-symbolicator/dsymprocessor v0.0.9
```

You can find the latest dSym processor version on the [releases page](https://github.com/honeycombio/opentelemetry-collector-symbolicator/releases) in the GitHub repo.

## dSYM Files

The dSym processor requires access to the dSYM file generated by your build process.
This file can be stored in your local file system, Amazon S3, or Google Cloud Storage.

To support symbolication, your dSYM file must be versioned with the generated build UUID in the file name.
For example: `6A8CB813-45F6-3652-AD33-778FD1EAB196.dSYM`.

### Getting the Build UUID

You can use the `dwarfdump` tool to get the build UUID from an an `.xcarchive` file generated by Xcode.
The following example script finds the latest build and uploads it to the `app-archives` Amazon S3 bucket with the `ios` prefix.

```bash theme={}
# Get the App Name
if [[ -z "$1" ]]; then
  echo "❌ Usage: $0 <TargetName>"
  exit 1
fi

TARGET_NAME=$1

export ARCHIVE_PATH=$(ls -dt ~/Library/Developer/Xcode/Archives/*/"$TARGET_NAME"*.xcarchive | head -1)
echo "📦 Using Archive Path: $ARCHIVE_PATH"

if [[ ! -d "$ARCHIVE_PATH" ]]; then
  echo "❌ Archive not found for target: $TARGET_NAME! Please archive the project first in Xcode."
  exit 1
fi

find "$ARCHIVE_PATH/dSYMs" -name "*.dSYM" | while read line ; do
   echo "🔍 Found dsym at: $line"
   dsymuuid=$(dwarfdump -u "$line" | awk '{ print $2 }').dSYM
   echo "⬆️ Uploading dsym to: $dsymuuid"
   aws s3 cp --recursive "$line" s3://app-archives/ios/$dsymuuid
done
```

## Configure a File Store

Add the `dsym_symbolicator` as a processor in your OpenTelemetry Collector configuration:

```yaml theme={}
processors:
  dsym_symbolicator:
```

You can then configure where your source maps are stored.

<Tabs>
  <Tab title="Local File Store">
    By default, the dSym processor loads dSYM files from a local directory.
    You can set the file path in your collector configuration:

    ```yaml theme={}
    processors:
      dsym_symbolicator:
        # dsym_store is sets which store to use, in this case local disk
        dsym_store: file_store
        local_dsyms:
            # (optional) path sets the base path of the files, defaults to `.`
            path: /tmp/dsyms
    ```

    Make sure your collector can access the `path` directory you set, and that file paths in stack traces match the structure of your configured file store.
  </Tab>

  <Tab title="Amazon S3 Store">
    Optionally, you can load dSYM files from an Amazon S3 bucket.
    Add to your OpenTelemetry Collector configuration:

    ```yaml theme={}
    processors:
      dsym_symbolicator:
        # dsym_store sets which store to use, in this case S3
        dsym_store: s3_store
        s3_dsyms:
            # name of the bucket the files are stored in
            bucket: dsyms-bucket
            # (optional) the bucket's region
            region: us-east-1
            # (optional) prefix is used to nest the files in a sub key of the bucket
            prefix: dsyms
    ```

    Make sure your collector has permission to access the S3 bucket.
    Also, ensure the file paths in stack traces match the structure used in your file store.

    #### Private AWS S3 bucket authentication

    To use a private Amazon S3 bucket as your file store, set the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` [environment variables](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html).
  </Tab>

  <Tab title="Google Cloud Storage Store">
    Optionally, you can load dSYM files from a Google Cloud Storage (GCS) bucket.
    Add to your OpenTelemetry Collector configuration:

    ```yaml theme={}
    processors:
      dsym_symbolicator:
        # dsym_store sets which store to use, in this case GCS
        dsym_store: gcs_store
        gcs_dsyms:
            # the name of the bucket the files are stored in
            bucket: dsyms-bucket
            # (optional) prefix is used to nest the files in a sub key of the bucket
            prefix: dsyms
    ```

    Make sure your collector has permission to access the GCS bucket.
    Also, ensure the file paths in stack traces match the structure used in your file store.

    #### Private GCS bucket authentication

    To use a private Google Cloud Storage bucket as your file store, set the `GOOGLE_APPLICATION_CREDENTIALS` [environment variable](https://cloud.google.com/docs/authentication/application-default-credentials).
  </Tab>
</Tabs>

## Advanced Configuration

In addition to basic setup, you can customize how the dSym processor handles stack traces by configuring attribute mappings and additional processing options.

<Tip>
  After updating the configuration file, restart the OpenTelemetry Collector to apply the changes.
</Tip>

### Mapping Attributes

Use these configuration options to specify which attributes the processor should read from and write to when handling stack traces:

<FlexStyleTable columns="33% 33% 33%" overflowWrap="break-word">
  | Config Key                                         | Description                                                                                                | Example Value                                          |
  | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
  | `symbolicator_failure_attribute_key`               | Signals if the the symbolicator fails to fully symbolicate the stack trace                                 | `exception.symbolicator.failed`                        |
  | `symbolicator_error_attribute_key`                 | Contains the error message if the the symbolicator fails to fully symbolicate the stack trace              | `exception.symbolicator.error`                         |
  | `stack_trace_attribute_key`                        | Which attribute should the stack trace of a generic stacktrace log be sourced from                         | `exception.stacktrace`                                 |
  | `metrickit_stack_trace_attribute_key`              | Which attribute should the json representation of a metrickit stacktrace log be sourced from               | `metrickit.diagnostic.crash.exception.stacktrace_json` |
  | `output_metrickit_stack_trace_attribute_key`       | Which attribute should the symbolicated metrickit stack trace be populated into                            | `exception.stacktrace`                                 |
  | `output_metrickit_exception_type_attribute_key`    | Which attribute should the exception type be populated into                                                | `exception.type`.                                      |
  | `output_metrickit_exception_message_attribute_key` | Which attribute should the exception message be populated into                                             | `exception.message`.                                   |
  | `preserve_stack_trace`                             | After the stack trace has been symbolicated should the original values be preserved as attributes          | `true`                                                 |
  | `original_stack_trace_attribute_key`               | If the stack trace is being preserved, which key should it be copied to                                    | `exception.stacktrace.original`                        |
  | `build_uuid_attribute_key`                         | Which resource attribute should the binary UUID of a generic stacktrace log be sourced from                | `app.debug.build_uuid`                                 |
  | `app_executable_attribute_key`                     | Which resource attribute should the name of the app executable of a generic stacktrace log be sourced from | `app.bundle.executable`                                |
</FlexStyleTable>

### Additional Processing Options

Use these configuration options to control how stack traces are processed and managed:

<FlexStyleTable columns="33% 33% 33%" overflowWrap="break-word">
  | Config Key        | Description                                                                                                 | Example Value |
  | ----------------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
  | `timeout`         | Max duration to wait to symbolicate a stack trace in seconds.                                               | `5`           |
  | `dsym_cache_size` | The maximum number of dSYMs to cache. Reduce this if you are running into memory issues with the collector. | `128`         |
</FlexStyleTable>

### Language-Based Routing

The dSYM processor supports language-based routing to ensure it only processes signals from iOS/macOS applications. This prevents the processor from running on signals from other platforms (like Android or JavaScript), improving performance and avoiding unnecessary processing.

<FlexStyleTable columns="25% 25% 25% 25%" overflowWrap="break-word">
  | Config Key               | Description                                                                                                                                                                                                                                                                                                                                           | Default Value               | Example Values           |
  | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------ |
  | `language_attribute_key` | The attribute key that contains the programming language or SDK language of the telemetry signal.                                                                                                                                                                                                                                                     | `telemetry.sdk.language`    | `telemetry.sdk.language` |
  | `allowed_languages`      | A list of language values that this processor will handle. If the signal's language attribute matches any value in this list, the processor will run. If empty (default), the processor will process all signals regardless of language. **Important:** When `allowed_languages` is configured, signals without a language attribute will be skipped. | `[]` (empty, processes all) | `["swift", "ios"]`       |
</FlexStyleTable>

**Example configuration:**

```yaml theme={}
processors:
  dsym_symbolicator:
    allowed_languages: ["swift", "ios"]
```

`allowed_languages` configuration behavior:

* Empty `allowed_languages` (default): Processes all signals, regardless of language attribute.
* With `allowed_languages` configured: Only processes signals where the language attribute matches one of the allowed values (case-insensitive).
* Missing language attribute: Skips processing when `allowed_languages` is configured.
