Symbolicate Android Stack Traces with the OpenTelemetry Collector

Use the proguard processor in your OpenTelemetry Collector to symbolicate Android stack traces.

The proguard processor replaces obfuscated names and addresses in your Android stack traces with symbols from provided Proguard files.

Before You Start 

The proguard processor is compatible with Honeycomb OpenTelemetry Android SDK version 0.0.20 and later.

To use the proguard 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 Android SDK, make sure your exception data is in the format the processor expects.

Install 

By default, the Honeycomb OpenTelemetry Collector distribution includes the proguard 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 proguard processor by adding it to your OpenTelemetry Collector build configuration file.

processors:
  - gomod: github.com/honeycombio/opentelemetry-collector-symbolicator/proguardprocessor v0.0.7

You can find the latest proguard processor version on the releases page in the GitHub repo.

Proguard Files 

The proguard processor requires access to the Proguard 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 Proguard file must be versioned with the generated build UUID in the file name. For example: 6A8CB813-45F6-3652-AD33-778FD1EAB196.txt.

You can use the Honeycomb ProGuard UUID Plugin to generate UUIDs in your build process.

Configure a File Store 

Add the proguard_symbolicator as a processor in your OpenTelemetry Collector configuration:

processors:
  proguard_symbolicator:

You can then configure where your Proguard files are stored.

Local File Store 

By default, the proguard processor loads Proguard files from a local directory. You can set the file path in your collector configuration:

processors:
  proguard_symbolicator:
    # proguard_store is sets which store to use, in this case local disk
    proguard_store: file_store
    local_store:
        # (optional) path sets the base path of the files, defaults to `.`
        path: /tmp/proguards

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.

Amazon S3 Store 

Optionally, you can load Proguard files from an Amazon S3 bucket. Add to your OpenTelemetry Collector configuration:

processors:
  proguard_symbolicator:
    # proguard_store sets which store to use, in this case S3
    proguard_store: s3_store
    s3_store:
        # name of the bucket the files are stored in
        bucket: proguards-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: proguards

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.

Google Cloud Storage Store 

Optionally, you can load Proguard files from a Google Cloud Storage (GCS) bucket. Add to your OpenTelemetry Collector configuration:

processors:
  proguard_symbolicator:
    # proguard_store sets which store to use, in this case GCS
    proguard_store: gcs_store
    gcs_store:
        # the name of the bucket the files are stored in
        bucket: proguards-bucket
        # (optional) prefix is used to nest the files in a sub key of the bucket
        prefix: proguards

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.

Advanced Configuration 

In addition to basic setup, you can customize how the symbolicator 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.

Mapping Attributes 

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

Config Key Description Default Value
symbolicator_failure_attribute_key Signals if the the symbolicator fails to fully symbolicate the stack trace exception.symbolicator.failed
symbolicator_error_attribute_key Stores the error message that caused the symbolication to fail exception.symbolicator.error
symbolicator_parsing_method_attribute_key Indicates which parsing method was used: "structured_stacktrace_attributes" (SDK-provided structured attributes) or "processor_parsed" (collector-side parsing of raw stack trace) exception.symbolicator.parsing_method
classes_attribute_key Which attribute should the classes of the stack trace be sourced from (structured route only) exception.structured_stacktrace.classes
methods_attribute_key Which attribute should the methods of the stack trace be sourced from (structured route only) exception.structured_stacktrace.methods.
lines_attribute_key Which attribute should the lines of the stack trace be sourced from (structured route only) exception.structured_stacktrace.lines
source_files_attribute_key Which attribute should the source files of the stack trace be sourced from (structured route only) exception.structured_stacktrace.source_files
stack_trace_attribute_key Which attribute should the raw stack trace be sourced from (collector-parsed route) and where the symbolicated stack trace will be written to (both routes) exception.stacktrace
exception_type_attribute_key Which attribute should the exception type be sourced from. If using collector-side parsing, this will be populated from the parsed stack trace exception.type
exception_message_attribute_key Which attribute should the exception message be sourced from. If using collector-side parsing, this will be populated from the parsed stack trace exception.message
preserve_stack_trace After the stack trace has been symbolicated should the original values be preserved as attributes. Applies to both structured and collector-parsed routes true
original_stack_trace_attribute_key If the stack trace is being preserved which key should the original raw stack trace be copied to (both routes) exception.stacktrace.original
original_classes_attribute_key If the stack trace is being preserved which key should the classes be copied to (structured route only) exception.structured_stacktrace.classes.original
original_methods_attribute_key If the stack trace is being preserved which key should the methods be copied to (structured route only) exception.structured_stacktrace.methods.original
original_lines_attribute_key If the stack trace is being preserved which key should the lines be copied to (structured route only) exception.structured_stacktrace.lines.original
original_source_files_attribute_key If the stack trace is being preserved which key should the source files be copied to (structured route only) exception.structured_stacktrace.source_files.original
proguard_uuid_attribute_key Which resource or log attribute should the proguard UUID be sourced from. Required for both routes app.debug.proguard_uuid

Additional Processing Options 

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

Config Key Description Example Value
timeout Max duration to wait to symbolicate a stack trace in seconds. 5
proguard_cache_size The maximum number of proguard files to cache. Reduce this if you are running into memory issues with the collector. 128

Language-Based Routing 

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

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) ["java", "kotlin"]

Example configuration:

processors:
  proguard_symbolicator:
    allowed_languages: ["java", "android"]

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.