The Atatus mobile SDK forwards application logs from native Android and Android TV builds to Atatus over HTTP. Entries are batched on the device, enriched with attributes and tags you define, and bound to the RUM context active when they were emitted, so a log line resolves to the session and view that produced it.
Prerequisites
- The Atatus SDK initialized in your application. See Android Monitoring Setup.
- A RUM application in Atatus, which provisions the license key the SDK authenticates with.
Authenticate with the license key, never your account API key. Anything shipped inside an APK is recoverable through decompilation, and the license key is the only credential scoped for client-side distribution.
Setup
1. Add the logs dependency
Declare the logs library in your application module's build script. It depends on the core SDK, so no additional coordinate is required:
dependencies {
implementation("com.atatus:atatus-sdk-android-logs:1.0.1")
}
2. Initialize the SDK
Logs share the core SDK instance with RUM, so initialization is identical to Android Monitoring Setup. Skip this step if the SDK is already initialized in your Application class:
import android.app.Application
import com.atatus.android.Atatus
import com.atatus.android.core.configuration.Configuration
import com.atatus.android.privacy.TrackingConsent
class SampleApplication : Application() {
override fun onCreate() {
super.onCreate()
val configuration = Configuration.Builder(
licenseKey = "<LICENSE_KEY>",
env = "<ENV_NAME>",
variant = "<APP_VARIANT_NAME>"
)
.build()
Atatus.initialize(this, configuration, TrackingConsent.GRANTED)
}
}
Guard against emitting logs before initialization completes:
if (Atatus.isInitialized()) {
// Your code here
}
3. Enable the logs feature
Enabling the feature registers the logs intake pipeline and its batch storage:
import com.atatus.android.log.Logs
import com.atatus.android.log.LogsConfiguration
val logsConfiguration = LogsConfiguration.Builder().build()
Logs.enable(logsConfiguration)
4. Create a logger
A Logger is the entry point for emitting entries, and its builder fixes the enrichment and sampling applied to everything it sends. Create one per subsystem you want to filter on independently:
import com.atatus.android.log.Logger
val logger = Logger.Builder()
.setNetworkInfoEnabled(true)
.setLogcatLogsEnabled(true)
.setBundleWithRumEnabled(true)
.setRemoteSampleRate(100f)
.setName("<LOGGER_NAME>")
.build()
Logger.Builder options:
| Option | Description |
|---|---|
setNetworkInfoEnabled(true) |
Adds network connectivity attributes (carrier, connection type) to each log. |
setLogcatLogsEnabled(true) |
Also writes logs to Logcat, so they appear in your local console. |
setBundleWithRumEnabled(true) |
Links logs to the current RUM context so you can pivot between logs and sessions. |
setRemoteSampleRate(100f) |
Percentage of logs sent to Atatus, from 0f to 100f. Defaults to 100f. |
setName("<LOGGER_NAME>") |
Sets the logger name attribute. |
setService("<SERVICE_NAME>") |
Sets the service name attribute. |
5. Send log messages
Each method maps to an Android log priority, which drives severity filtering and alerting in Atatus:
logger.d("A debug message.")
logger.i("Some relevant information.")
logger.w("An important warning.")
logger.e("An error was met!")
logger.wtf("What a terrible failure!")
Pass a Throwable to record the exception and its stack trace alongside the message:
try {
doSomething()
} catch (e: IOException) {
logger.e("Error while doing something", e)
}
Attach attributes scoped to a single entry:
logger.i("onPageStarted", attributes = mapOf("http.url" to url))
6. Add global attributes and tags
Attributes are structured key-value pairs that remain queryable in Atatus, unlike values interpolated into a message string. Scope them to one logger, or to every logger through the Logs feature:
// Added to every log sent by this logger
logger.addAttribute("version_name", BuildConfig.VERSION_NAME)
// Added to every log sent by all loggers
Logs.addAttribute("version_code", BuildConfig.VERSION_CODE)
Tags partition logs into facets for filtering and aggregation:
logger.addTag("build_type", BuildConfig.BUILD_TYPE)
logger.addTag("device", "android")
Remove attributes and tags once they fall out of scope, so later entries are not enriched with stale state:
logger.removeAttribute("version_name")
Logs.removeAttribute("version_code")
logger.removeTagsWithKey("build_type")
Send data when the device is offline
Entries are serialized to batch files on disk and uploaded when network availability and battery level permit, so a session recorded offline is retained until connectivity returns. Batches exceeding their retention window are evicted to bound disk usage. No configuration is required.
Next steps
- Track views, actions, and errors with Android Monitoring Setup.
- Correlate logs with traces using Trace Collection.
- Explore your logs in Logs Monitoring.
+1-415-800-4104