How-tos
Your Application instance is needed to initialize the agent. There are a couple of ways you can get yours:
Ideally, the agent should get initialized as soon as your application is launched to make sure that it can start collecting telemetry from the very beginning.
Based on the above, an ideal place to do so is from within your own, custom Application.onCreate method implementation, as shown below:
package my.app
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
val agent = ElasticApmAgent.builder(this)
//...
.build()
}
}
this
is your application.
For it to work, you must register your custom application in your AndroidManifest.xml
file, like so:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:name="my.app.MyApp"
...
</application>
</manifest>
You can get your application from an Activity by calling its getApplication() method.
From a Fragment instance, you can get the Activity that it is associated to by calling its requireActivity() method. Once you get the Activity object, you can get your application from it as explained above.
The export endpoint is where your app's telemetry is sent, so it's required to initialize the agent. The way to find it in your Elastic Stack will depend on the type of deployment you use, as explained below.
On a Serverless deployment, open Kibana and find Add data in the main menu. Alternatively, you can use the global search field and search for "Observability Onboarding".
Then select Application, as shown below:
Choose OpenTelemetry:
On the next page, select the OpenTelemetry tab, followed by Managed OTLP Endpoint under "Configure the OpenTelemetry SDK":
Your export endpoint URL is the value for the OTEL_EXPORTER_OTLP_ENDPOINT
configuration setting:
For Cloud Hosted and self-managed deployments, the export endpoint (also known as EDOT Collector) is not available out of the box at the moment. You can still create your own service by following creating and configuring a standalone EDOT Collector.
API Keys are the recommended way of authenticating the agent with your Elastic Stack. There's a couple of ways you can create one:
This is the most straightforward approach. Follow this quick guide and leave all the settings with their default values.
Follow this guide to create an API Key with a set of privileges that are scoped for the APM Agent use case only.
You many want to get values such as an endpoint URL or API Key/Secret Token from a local file in your project directory or an environment variable (or both).
The Android Gradle plugin has you covered with its build config fields, which provide a way to share Gradle info with your app's Kotlin/Java code. Since Gradle has access to your project directory and to the compilation's host environment, you can share a lot with it from your code. The following are some possible use cases.
// 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\"")
}
}
- Since the
build.gradle.kts
files are written using Kotlin code, you can get your environment variables the same way you would with regular Kotlin sources. The same applies tobuild.gradle
files, which work with Groovy instead. - Ensure Android's
buildConfig
feature is enabled. - Adding our build config fields to the
android.defaultConfig
block ensures they're available for all of your app's build variants. You could also, if needed, create fields with the same name but different values for each of your build variants, as shown in Android's official docs, to provide different values per variant.
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 in code.
Properties are a common way to provide values to JVM apps through files (they're even mentioned for Android cases such as storing keystore info). Here's an example of how you could use them to provide config values to the agent.
Given the following example properties file:
my.url=http://localhost
my.api.key=somekey
This is what your build.gradle.kts
configuration should look like:
// 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\"")
}
}
- Your file path, provided here, is relative to your
build.gradle.kts
file (where this code is written). So in this example, both files (ourbuild.gradle.kts
andmyfile.properties
) are located in the same directory. - Ensure Android's
buildConfig
feature is enabled. - Adding your build config fields to the
android.defaultConfig
block ensures they're available for all of your app's build variants. You could also, if needed, create fields with the same name but different values for each of your build variants, as shown in Android's official docs, to provide different values per variant.
You've properly created build config fields from a properties file. To use them in code, refer to read build config fields in code.
After adding build config fields in your build.gradle.kts
file, you may now use them within your app's Kotlin/Java code, by following these steps:
- 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.
- Find them within your app's
BuildConfig
generated type, as shown below.
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()
}
- There might be multiple
BuildConfig
types available to use in your code. The one that belongs to your app has a package name equal to your app's namespace value. So, for example, if your app's namespace is set tocom.my.app
, then theBuildConfig
type you must use would becom.my.app.BuildType
.
Note that the Elastic Agent does not handle SSL/TLS configs internally. Therefore, you should manage these types of configurations as part of your app’s network security configurations, as explained in Android’s official security guidelines. Below we show a set of common use cases and quick tips on what could be done on each one. However, each case might be different, so please refer to Android’s official docs on this topic if you need more details.
If your Elastic Stack is hosted in Elastic Cloud, you shouldn’t need to add any SSL/TLS config changes in your app. It should work out of the box.
If your Elastic Stack is hosted on-prem, then it depends on the type of CA your host uses to sign its certificates. If it’s a commonly trusted CA, you shouldn’t have to worry about changing your app’s SSL/TLS configuration as it all should work well out of the box. However, if your CAs are unknown/private or your server uses a self-signed certificate, then you would need to configure your app to trust custom CAs by following Android’s guide.
If you’re running a local server and need to connect to it without using https in order to run a quick test, then you could temporarily enable cleartext traffic within your AndroidManifest.xml
file, inside the <application>
tag. As shown below:
<application
...
android:usesCleartextTraffic="true">
...
</application>
You should only enable cleartext traffic for debugging purposes and not for production code.
If enabling cleartext traffic isn’t a valid option for your debugging use case, you should refer to Android’s guide on configuring CAs for debugging.
For more information on how Android handles network security, please refer to the official Android docs.