AELog
1.1.7indexedIn-app debugging overlay for inspecting logs, HTTP traffic, and analytics with syntax-highlighted JSON, secure header redaction, body truncation, modular plugin panels, and zero release overhead.
In-app debugging overlay for inspecting logs, HTTP traffic, and analytics with syntax-highlighted JSON, secure header redaction, body truncation, modular plugin panels, and zero release overhead.
Extensible on-device dev tools for Kotlin Multiplatform
An in-app debugging overlay for KMP — inspect logs, network traffic, analytics, crashes, and SQLite databases with a beautiful Compose UI. No external tools needed.
Features • Plugins • Installation • Quick Start • Custom Plugins • Documentation
AELog provides a suite of modular core plugins:
AELog is fully modularized. Add only the dependencies you need. Every plugin module carries ae-log-core transitively.
Add the following to your gradle/libs.versions.toml:
[versions]
aelog =
= { module = , version.ref = }
= { module = , version.ref = }
= { module = , version.ref = }
= { module = , version.ref = }
= { module = , version.ref = }
= { module = , version.ref = }
Add the required dependencies to your target source sets in build.gradle.kts:
// build.gradle.kts (shared module)
kotlin {
sourceSets {
commonMain.dependencies {
// Pick only what you need (each carries core transitively)
implementation(libs.aelog.logs)
implementation(libs.aelog.network.ktor)
implementation(libs.aelog.analytics)
implementation(libs.aelog.crashes)
implementation(libs.aelog.database) // Database Inspector & SQLite Driver
}
androidMain.dependencies {
// Optional OkHttp interceptor for Android
implementation(libs.aelog.network.okhttp)
}
}
}
📖 See the Full Installation Guide for direct dependency coordinates and details.
AELog features zero-config auto-initialisation on Android and iOS. Just add the Gradle dependencies for the plugins you want, and AELog automatically boots up when your app launches.
Add AELogOverlay() as a sibling anywhere in your root composable — no wrapping required:
@Composable
fun App() {
// Renders the floating overlay trigger
AELogOverlay()
MaterialTheme {
Scaffold(
floatingActionButton = {
FloatingActionButton(onClick = { AELog.show() }) {
Icon(Icons.Default.BugReport, contentDescription = "Open Inspector")
}
}
) {
YourAppContent()
}
}
}
To disable the floating notch trigger globally or locally:
AELog.showNotch = false // Disable globally
// or
AELogOverlay(showNotch = false) // Disable locally
To disable the library entirely in release builds:
AELog.isEnabled = BuildConfig.DEBUG
AELog)AELog provides static shorthands modeled after Android's built-in Log class:
AELog.log.v("Auth", "Token checked")
AELog.log.d("Auth", "Token refreshed")
AELog.log.i("HomeScreen", "App launched!")
AELog.log.w("Auth", "Session expiring soon")
AELog.log.e("Database", "Failed to clear cache", exception)
AELog.log.wtf("Auth", "Unexpected state")
Omit the tag and AELog derives it from the caller's class name automatically:
AELog.log.d("Token refreshed") // tag → "AuthViewModel"
AELog.log.i("App launched!") // tag → "HomeScreen"
AELog.log.e("Failed to clear cache", t) // tag → "Database"
// Network, Analytics & Crashes APIs
AELog.network.logRequest(method = "GET", url = "https://api.example.com/users")
AELog.network.logResponse(url = "https://api.example.com/users", statusCode = 200)
AELog.analytics.logEvent("item_added_to_cart", properties = mapOf("id" to "123"))
// Capture non-fatal exceptions manually
try {
performDangerousWork()
} catch (t: Throwable) {
AELog.crashes.recordNonFatal(t)
}
AELog provides first-class interceptors for OkHttp and Ktor.
Pass InterceptorDefaults.COMMON_EXCLUDED to hide sensitive headers like Authorization or Cookie:
// OkHttp
val interceptor = AELogOkHttpInterceptor(
excludeHeaders = InterceptorDefaults.COMMON_EXCLUDED
)
// Ktor
val client = HttpClient {
install(AELogKtorInterceptor) {
excludeHeaders = InterceptorDefaults.COMMON_EXCLUDED + "X-Custom-Secret"
}
}
Bodies are automatically truncated (default 250 KB) to prevent memory issues:
AELogOkHttpInterceptor(
maxRequestBodyBytes = 500_000, // 500 KB limit
maxResponseBodyBytes = 1_000_000 // 1 MB limit
)
val supabase = createSupabaseClient(url, key) {
install(Auth)
httpConfig {
install(AELogKtorInterceptor)
}
}
AELog includes a powerful on-device Database Inspector with live query interception for androidx.room, SQLDelight, and SQLite.
AELogSQLiteDriver)To automatically intercept and log all SQL statements executed by your app in real-time across Room, SQLDelight, or raw SQLite, wrap your underlying SQLiteDriver with AELogSQLiteDriver:
// 1. Room Database Integration:
Room.databaseBuilder<AppDatabase>(name = dbFilePath)
.setDriver(AELogSQLiteDriver(BundledSQLiteDriver(), databaseName = "app.db"))
.build()
// 2. SQLDelight Integration:
val driver = AELogSQLiteDriver(
delegate = NativeSQLiteDriver(Database.Schema, "app.db"),
databaseName = "app.db"
)
val database = Database(driver)
// 3. Raw SQLite Integration:
val driver = AELogSQLiteDriver(BundledSQLiteDriver(), databaseName = "app.db")
On Android and iOS, AELog also automatically scans application database directories to browse tables and schemas:
// Shared commonMain sourceSet
implementation("io.github.abdo-essam:ae-log-database:1.2.5")
AELog.database)Inspect databases, list tables, execute interactive SQL queries, or log custom app queries:
// List discovered databases
val databases = AELog.database.listDatabases()
// Browse database tables
val tables = AELog.database.listTables(dbName = "app.db")
// Execute interactive SQL queries
val result = AELog.database.query(
dbName = "app.db",
sql = "SELECT * FROM users WHERE active = 1"
)
// Log custom app database queries AELog.database.logQuery( databaseName = "app_database.db", sql = "SELECT * FROM orders WHERE total > 100", durationMs = 3L )
#### 3. Custom Configuration (`DatabasePluginConfig`)
Configure read/write security permissions, page sizes, and busy timeouts:
```kotlin
val dbConfig = DatabasePluginConfig(
allowWrite = true, // Enable INSERT, UPDATE, DELETE execution (default: false read-only)
defaultPageSize = 100, // Rows per page when browsing table data
busyTimeoutMs = 5000L // SQLite busy timeout in WAL mode
)
// Re-install DatabasePlugin with custom config
AELog.install(DatabasePlugin(config = dbConfig))
Three ways to open the inspector:
AELog.show() / AELog.hide()Create your own debug panel in 3 steps:
class FeatureFlagsPlugin : UIPlugin {
override val name = "Flags"
@Composable
override fun Content(modifier: Modifier) {
LazyColumn(modifier = modifier) {
items(flags) { flag ->
FlagRow(flag)
}
}
}
}
// Install alongside auto-registered plugins
AELog.install(FeatureFlagsPlugin())
📖 See the Custom Plugins Guide for the full API reference.
Forward logs from Kermit, Napier, Timber, or SLF4J directly to AELog.log:
AELog.log.i("MyTag", "Something happened")
AELog.log.e("Database", "Failed to clear cache", exception)
📖 See the Logging Integrations Guide for adapter details.
Contributions are welcome! Please read the Contributing Guide first.
git clone https://github.com/abdo-essam/AELog.git
cd AELog
./gradlew build
./gradlew allTests
Copyright 2026 Abdo Essam
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
wasmJs).ContentProvider) and iOS (@EagerInitialization) without boilerplate.| Plugin | Purpose | Key Capabilities |
|---|
| 🔍 Log Inspector | On-Device Log Viewer | Live console output, search queries, filter by severity level/tag, auto-class tagging, copy/share. |
| 🌐 Network Viewer | HTTP Traffic Inspector | Ktor and OkHttp interception, full headers, status codes, JSON payload inspection with sensitive key redaction. |
| 📊 Analytics Tracker | Analytics Event Tracker | Track event dispatches, screen views, and custom property dictionaries in real time. |
| 💥 Crash Reporter | Local Exception Manager | Intercept fatal exceptions and record non-fatal errors on-device that survive app restarts. |
| 🗄️ Database Inspector | SQLite & Room Inspector | Auto-discover databases, browse tables, search rows, inspect schemas, and execute SQL queries directly on-device. |
Surfaced from shared tags and platforms — no rankings paid for.