Skip to content

rosalesKevin/katch

Repository files navigation

Katch

Katch banner

Maven Central License: MIT

An Android crash logging library written in Kotlin. When your app crashes, Katch captures the last 100 log entries and writes a structured report to the device — either a plaintext .txt file or an AES-256-GCM encrypted .enc file.


Installation

Add mavenCentral() to your repository block if it isn't there already:

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}

Add the dependency:

// app/build.gradle.kts
dependencies {
    implementation("io.github.rosaleskevin:katch:1.0.0")
}

Setup

Initialize once in your Application class:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        Katch.init(this)
    }
}

Logging

Use Katch the same way you'd use Android's Log:

Katch.d("Auth", "Token refreshed")
Katch.i("Home", "User navigated to dashboard")
Katch.w("Network", "Slow response detected")
Katch.e("Api", "Request failed — timeout")

Entries are held in memory only. Nothing is written to disk until a crash occurs.


Crash reports

When a crash happens, Katch writes a file to:

/sdcard/Android/data/<your.package>/files/crash_logs/crash_YYYY-MM-DD_HH-mm-ss.txt

The full path is also printed to Logcat immediately after writing:

E/Katch: Crash report saved -> /sdcard/Android/data/com.example.app/files/crash_logs/crash_2026-04-01_14-32-05.txt

Report format:

=====================================
 KATCH - CRASH REPORT
=====================================
Timestamp   : 2026-04-01 14:32:05
App Version : 1.2.3 (45)
Device      : Samsung Galaxy S21
OS Version  : Android 13 (API 33)
=====================================

--- LOGS (last 100 entries) ---
[14:32:01] D/Auth: Token refreshed
[14:32:02] I/Home: User navigated to dashboard
[14:32:04] E/Api: Request failed — timeout

--- STACK TRACE ---
java.lang.NullPointerException: ...
    at com.example.app.HomeViewModel.loadData(HomeViewModel.kt:42)
    ...
=====================================

Custom output directory

By default Katch writes to getExternalFilesDir("crash_logs"). To save reports somewhere else, call outputDir() with any File — before or after init():

Katch.outputDir(File(getExternalFilesDir(null), "my_crashes"))
Katch.init(this)

If the directory does not exist Katch will attempt to create it. If creation fails it falls back to the default location silently.


Encryption (optional)

Crash reports contain sensitive runtime data. You can opt into AES-256-GCM encryption so reports are unreadable without the correct key.

Auto-generated key

Katch generates and manages the key for you, stored via Android Keystore:

Katch.init(this, encryptionKey = Katch.EncryptionKey.Auto)

The key persists across app restarts. Call logKey() once in a debug build to print the key to Logcat — you'll need it to run the CLI decryptor:

if (BuildConfig.DEBUG) Katch.logKey()
// W/Katch: Encryption key: 3a9f1c...  (keep this safe — required to decrypt crash reports)

Passphrase key

Pass any non-blank string and Katch derives the AES-256 key for you via SHA-256:

Katch.init(this, encryptionKey = "my-secret-passphrase")

The same passphrase always produces the same key — reports stay decryptable across reinstalls. Call logKey() once to retrieve the derived hex key for the CLI decryptor:

if (BuildConfig.DEBUG) Katch.logKey()

SHA-256 is a one-way function, so the hex key printed by logKey() cannot be reversed to recover the original passphrase.

Developer-supplied key

Pass your own 32-byte (AES-256) key:

Katch.init(this, encryptionKey = myKeyByteArray) // must be exactly 32 bytes

Passing a key of the wrong length throws IllegalArgumentException at startup.

Encrypted file format

When encryption is enabled, reports are written as .enc files:

/sdcard/Android/data/<your.package>/files/crash_logs/crash_YYYY-MM-DD_HH-mm-ss.enc

The binary layout is [1-byte version 0x01][12-byte IV][ciphertext + 16-byte GCM tag].

CLI decryptor

Decrypt a report on your development machine using the bundled CLI tool:

java -jar katch-decryptor.jar --key <hex-encoded-key> --input crash_report.enc
java -jar katch-decryptor.jar --key <hex-encoded-key> --input crash_report.enc --output decrypted.txt
  • --key — the AES-256 key as a 64-character hex string
  • --input — path to the .enc file
  • --output — optional; if omitted, decrypted content is printed to stdout

Build the JAR from impl/:

./gradlew :decryptor:jar
# output: impl/decryptor/build/libs/decryptor.jar

Testing integration

Use testCrash() to write a report without actually crashing your app. Gate it behind a debug check:

if (BuildConfig.DEBUG) {
    Katch.testCrash()
}

This writes a real report file with the current log buffer and a synthetic stack trace, so you can verify the output before shipping.


Included sample app

This repository includes a sample Android app at impl/sample-app/ that demonstrates a simple developer-facing integration.

The sample is intentionally basic and easy to read:

  • SampleApp initializes Katch in Application.onCreate() with a string passphrase, which Katch hashes with SHA-256 to derive the real AES key
  • the screen makes it clear that Katch.EncryptionKey.Auto is still the alternative if you want Katch-managed keys
  • the screen explains where Katch.d(), Katch.i(), Katch.w(), and Katch.e() belong in a real app
  • Copy Exported Key gives you the derived AES key needed for the decryptor workflow
  • Generate Test Report writes an encrypted .enc report without killing the app
  • Crash App triggers a real uncaught exception so you can validate the crash path end to end

Build it from impl/:

./gradlew :sample-app:assembleDebug

The UI uses a small dark developer-tool style, but the code path stays straightforward so the sample still reads like reference integration code.


License

MIT License — Copyright (c) 2026 Kevin Klein Rosales. See LICENSE for details.

About

A lightweight Android crash logging library written in Kotlin

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages