---
title: Configure the EDOT Android SDK
description: Comprehensive list of configuration parameters for the Elastic Distribution of OpenTelemetry Android (EDOT Android).
url: https://www.elastic.co/elastic/docs-builder/docs/2422/reference/opentelemetry/edot-sdks/android/configuration
products:
  - Elastic Cloud Serverless
  - Elastic Distribution of OpenTelemetry SDK
  - Elastic Observability
---

# Configure the EDOT Android SDK
This section contains a comprehensive list of all the configurable parameters available for EDOT Android, including those you can set during initialization and those you can adjust dynamically afterward.

## Initialization configuration

Initialization configuration is available from the EDOT Android builder shown in [Agent setup](/elastic/docs-builder/docs/2422/reference/opentelemetry/edot-sdks/android/getting-started#agent-setup). The following are its available parameters.

### Application metadata

Provide your application name, version, and environment. For example:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            .setServiceName("My app name")
            .setServiceVersion("1.0.0")
            .setDeploymentEnvironment("prod")
            // ...
            .build()
    }
}
```


### Export connectivity

Configure where your app's telemetry is exported:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .setExportUrl("https://my-elastic-apm-collector.endpoint")
            .setExportAuthentication(Authentication.ApiKey("my-api-key"))
            .setExportProtocol(ExportProtocol.HTTP)
            .build()
    }
}
```

<tip>
  To provide these values from outside of your code, using an environment variable or a properties file for example, refer to [Provide config values outside of your code](#provide-config-values-from-outside-of-your-code).
</tip>


### Intercept export request headers

You can provide an interceptor for the signals' export request headers, where you can read or modify them if needed.
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .setExportHeadersInterceptor(interceptor)
            .build()
    }
}
```


### Intercept attributes

You can provide global interceptors for all spans and logs [attributes](https://opentelemetry.io/docs/specs/otel/common/#attribute). Interceptors are executed on every span or log creation, where you can read or modify them if needed.
This is useful for setting dynamic global attributes. If you'd like to set static global attributes, which are also applied to metrics, take a look at [Intercept resources](#intercept-resources).
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .addSpanAttributesInterceptor(interceptor)
            .addLogRecordAttributesInterceptor(interceptor)
            .build()
    }
}
```


### Session behavior

You can configure how [sessions](/elastic/docs-builder/docs/2422/reference/opentelemetry/edot-sdks/android#sessions) work. For example:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            .setSessionSampleRate(1.0)
            // ...
            .build()
    }
}
```


### Disk buffering behavior

You can configure how [disk buffering](/elastic/docs-builder/docs/2422/reference/opentelemetry/edot-sdks/android#disk-buffering) works. For example:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            .setDiskBufferingConfiguration(DiskBufferingConfiguration.enabled())
            // ...
            .build()
    }
}
```


### Intercept resources

EDOT Android creates a [resource](https://opentelemetry.io/docs/specs/otel/overview/#resources) for your signals, which is a set of static global attributes. These attributes help Kibana properly display your application's data.
You can intercept these resources and read or modify them as shown in the following example.
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .setResourceInterceptor(interceptor)
            .build()
    }
}
```

<note>
  The resource interceptor is only applied during initialization, as this is the only time where resource attributes can be modified. If you'd like to set _dynamic_ global attributes instead, take a look at [Intercept attributes](#intercept-attributes).
</note>


### Intercept exporters

EDOT Android configures exporters for each signal ([spans](https://opentelemetry.io/docs/languages/java/sdk/#spanexporter), [logs](https://opentelemetry.io/docs/languages/java/sdk/#logrecordexporter), and [metrics](https://opentelemetry.io/docs/languages/java/sdk/#metricexporter)) to manage features like [disk buffering](/elastic/docs-builder/docs/2422/reference/opentelemetry/edot-sdks/android#disk-buffering) and also to establish a connection with the Elastic export endpoint based on the provided [export connectivity](#export-connectivity) values.
You can intercept exporters to add your own logic, such as logging each signal that gets exported, or filtering some items that don't make sense for you to export. For example:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .addSpanExporterInterceptor(interceptor)
            .addLogRecordExporterInterceptor(interceptor)
            .addMetricExporterInterceptor(interceptor)
            .build()
    }
}
```


### Intercept HTTP spans

This is a convenience tool to intercept HTTP-related spans. By default, EDOT Android enhances HTTP span names to include `domain:port` when only an HTTP verb is set. This is [often the case](https://opentelemetry.io/docs/specs/semconv/http/http-spans/#name) for HTTP client span names.
You can override this behavior by setting your own interceptor, or you can choose to set it to `null` to just turn it off. For example:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .setHttpSpanInterceptor(interceptor)
            .build()
    }
}
```


### Provide processors

Part of the work that EDOT Android does when configuring the OpenTelemetry SDK on your behalf is to provide processors, which are needed to delegate data to the exporters. For spans, EDOT Android provides a [BatchSpanProcessor](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace/latest/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.html); for logs, a [BatchLogRecordProcessor](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs/latest/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.html); whereas for metrics, it's a [PeriodicMetricReader](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics/latest/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.html), which is analogous to a processor.
If you want to provide your own processors, you can do so by setting a custom [ProcessorFactory](https://github.com/elastic/apm-agent-android/blob/main/agent-sdk/src/main/java/co/elastic/otel/android/processors/ProcessorFactory.kt), as shown in the example:
```kotlin
class MyApp : android.app.Application {

   override fun onCreate() {
      super.onCreate()
      val agent = ElasticApmAgent.builder(this)
         // ...
         .setProcessorFactory(factory)
         .build()
   }
}
```

The factory is called once during initialization and needs to provide a processor per signal. Each processor-provider method within the factory contains the configured exporter for that signal as an argument so that it's included into the processor as its delegate exporter.

### Internal logging policy

<note>
  Not to be confused with OpenTelemetry's [log signals](https://opentelemetry.io/docs/concepts/signals/logs/). The internal logging policy is about EDOT Android's internal logs that you should see in [logcat](https://developer.android.com/studio/debug/logcat) only.
</note>

EDOT Android creates logs using [Android's Log](https://developer.android.com/reference/android/util/Log) type to notify about its internal events, so that you can check them out in [logcat](https://developer.android.com/studio/debug/logcat) for debugging purposes. By default, all logs are printed for a debuggable app build. However, in the case of non-debuggable builds, only logs at the `INFO` level and higher are printed.
If you want to show specific logs from EDOT Android, or even turn off logs altogether, you can do so by providing your own `LoggingPolicy` configuration. The following example shows how to allow all logs of level `WARN` and higher to be printed, whereas those lower than `WARN` are ignored.
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .setInternalLoggingPolicy(LoggingPolicy.enabled(LogLevel.WARN))
            .build()
    }
}
```


## Dynamic configuration

Dynamic configuration settings are available from an already built [agent](https://github.com/elastic/apm-agent-android/blob/main/agent-sdk/src/main/java/co/elastic/otel/android/ElasticApmAgent.kt).

### Update export connectivity

You can change any of the configuration values provided as part of the [export connectivity](#export-connectivity) setters, at any time by setting a new [ExportEndpointConfiguration](https://github.com/elastic/apm-agent-android/blob/main/agent-sdk/src/main/java/co/elastic/otel/android/connectivity/ExportEndpointConfiguration.kt) object, which overrides them all. For example:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .build()
        agent.setExportEndpointConfiguration(configuration)
    }
}
```


## Central configuration

```
serverless: unavailable
stack: preview 9.1 
product:
  edot_android: preview 1.2.0
```

Starting from version `1.2.0`, you can remotely manage the EDOT Android behavior through [Central configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2422/reference/opentelemetry/central-configuration).

### Activate central configuration

The remote management is turned off by default. To turn it on, provide your central configuration endpoint when initializing EDOT Android, as shown here:
```kotlin
class MyApp : android.app.Application {

    override fun onCreate() {
        super.onCreate()
        val agent = ElasticApmAgent.builder(this)
            // ...
            .setManagementUrl("https://...")
            .setManagementAuthentication(Authentication.ApiKey("my-api-key"))
            .build()
    }
}
```


### Available settings

You can modify the following settings for EDOT Android through the Central Configuration:

| Setting             | Central configuration name | Description                                                                                                                                                                                                   | Type    |
|---------------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
| Recording           | `recording`                | Whether EDOT Android should record and export telemetry or not. By default it's enabled, disabling it is effectively turning EDOT Android off where only the central configuration polling will be performed. | Dynamic |
| Session sample rate | `session_sample_rate`      | To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. Data will be sampled per session, this is so context in a given session isn't lost.                  | Dynamic |

Dynamic settings can be changed without having to restart the application.

## Provide config values from outside of your code

You might need to get values such as an endpoint URL or API key or secret token from a local file in your project directory or an environment variable, or both. You can do this through the Android Gradle plugin and its [build config fields](https://developer.android.com/build/gradle-tips#share-custom-fields-and-resource-values-with-your-app-code), which provide a way to share Gradle info with your app's Kotlin/Java code.

### Provide data from an environment variable

The following example shows how to obtain configuration values from environment variables:
```kotlin
// Your app's build.gradle.kts file
plugins {
    // ...
}

val url = System.getenv("MY_ENV_WITH_MY_URL")
val apiKey = System.getenv("MY_ENV_WITH_MY_KEY")

android {
    // ...
    buildFeatures.buildConfig = true

    defaultConfig {
        // ...
        buildConfigField("String", "MY_EXPORT_URL", "\"$url\"")
        buildConfigField("String", "MY_EXPORT_API_KEY", "\"$apiKey\"")
    }
}
```

You've properly created build config fields from environment variables. To use them in code, take a look at how to [read build config fields](#read-build-config-fields) in code.

### Provide data from a properties file

[Properties](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html) are a common way to provide values to JVM apps through files. Here's an example of how you could use them to provide config values to EDOT Android.
Given the following example properties file:
```properties
my.url=http://localhost
my.api.key=somekey
```

This is what your `build.gradle.kts` configuration should look like:
```kotlin
// Your app's build.gradle.kts file
import java.util.Properties

plugins {
    // ...
}

val myPropertiesFile = project.file("myfile.properties")
val myProperties = Properties().apply {
    myPropertiesFile.inputStream().use { load(it) }
}

val url = myProperties["my.url"]
val apiKey = myProperties["my.api.key"]

android {
    // ...
    buildFeatures.buildConfig = true

    defaultConfig {
        // ...
        buildConfigField("String", "MY_EXPORT_URL", "\"$url\"")
        buildConfigField("String", "MY_EXPORT_API_KEY", "\"$apiKey\"")
    }
}
```

You've properly created build config fields from a properties file. To use them in code, refer to [read build config fields](#read-build-config-fields) in code.

### Read build config fields in code

After adding [build config fields](https://developer.android.com/build/gradle-tips#share-custom-fields-and-resource-values-with-your-app-code) in your `build.gradle.kts` file, you can now use them within your app's Kotlin or Java code by following these steps:
1. Compile your project. The build config fields are generated during compilation, so this step is required so that you can find them in your code later.
2. Find them within your app's `BuildConfig` generated type, as shown in the following example:

```kotlin
import my.app.namespace.BuildConfig
// ...

fun myMethod() {
    val agent = ElasticApmAgent.builder(application)
        // ...
        .setExportUrl(BuildConfig.MY_EXPORT_URL)
        .setExportAuthentication(Authentication.ApiKey(BuildConfig.MY_EXPORT_API_KEY))
        .build()
}
```