Skip to content

CosminMihuMDC/KtorMonitor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

566 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Maven Central License Platforms Slack JetBrains Klibs.io Documentation API GitHub stars GitHub forks

KtorMonitor

Powerful tool to monitor Ktor Client, OkHttp and http4k requests and responses, making it easier to debug and analyze network communication.

ktormonitor

✨ Features

  • 🌐Ktor Network Monitoring: Real-time interception and logging of Ktor Client traffic.
  • 🌐OkHttp Network Monitoring: Real-time interception and logging of OkHttp traffic.
  • 🌐http4k Network Monitoring: Real-time interception and logging of http4k traffic.
  • πŸ“±Kotlin Multiplatform (KMP): Full support for Android, iOS, Desktop (JVM), Wasm, and JS.
  • πŸ› οΈHighly Configurable: Customize retention periods, content length limits, and notification behavior.
  • πŸ”’Security First: Redact sensitive headers (e.g., Authorization).
  • πŸ“‚Data Export: Save request/response details to local files for easier debugging or sharing.
  • 🎨Rich Previews: Built-in viewers for JSON, XML, HTML, CSS, YAML, MARKDOWN, Form Data, Image (JPG, PNG, SVG, GIF, WEBP).
  • πŸ“‘SSE & WebSockets: Track one-way streams (SSE) and bidirectional traffic (WebSockets).
  • πŸ›‘οΈProduction Safe: No-Op version to ensure monitoring code is excluded from your production builds.

πŸ“¦ Setup (Kotlin Multiplatform) for Ktor Client

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("ro.cosminmihu.ktor:ktor-monitor-logging:1.13.0")
        }
    }
}

For Release Builds (No-Op)

To isolate KtorMonitor from release builds, use the ktor-monitor-logging-no-op variant. This ensures the monitor code is not included in production artifact.

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("ro.cosminmihu.ktor:ktor-monitor-logging-no-op:1.13.0")
        }
    }
}

πŸ“¦ Setup (Android) for Ktor Client

dependencies {
    debugImplementation("ro.cosminmihu.ktor:ktor-monitor-logging:1.13.0")
    releaseImplementation("ro.cosminmihu.ktor:ktor-monitor-logging-no-op:1.13.0")
}

For Android minSdk < 26, Core Library Desugaring is required.

Install Ktor Client Plugin

HttpClient {
	
    install(KtorMonitorLogging) {  
        sanitizeHeader { header -> header == "Authorization" }  
        filter { request -> !request.url.host.contains("cosminmihu.ro") }  
        showNotification = true  
        retentionPeriod = RetentionPeriod.OneHour
        maxContentLength = ContentLength.Default
    }
}
  • sanitizeHeader - sanitize sensitive headers to avoid their values appearing in the logs
  • filter - filter logs for calls matching a predicate.
  • showNotification - Keep track of latest requests and responses into notification. Default is true. Android and iOS only. Notifications permission needs to be granted.
  • retentionPeriod - The retention period for the logs. Default is 1h.
  • maxContentLength - The maximum length of the content that will be logged. After this, body will be truncated. Default is 250_000. To log the entire body use ContentLength.Full.

πŸ“¦ Setup (Android & JVM) for OkHttp

dependencies {
    debugImplementation("`ro.cosminmihu.ktor:ktor-monitor-okhttp-interceptor:1.13.0")
    releaseImplementation("ro.cosminmihu.ktor:ktor-monitor-okhttp-interceptor-no-op:1.13.0")
}

For Android minSdk < 26, Core Library Desugaring is required.

Install OkHttp Interceptor

OkHttpClient.Builder()
    .addNetworkInterceptor(
        KtorMonitorInterceptor {
            sanitizeHeader { header -> header == "Authorization" }
            filter { request -> !request.url.host.contains("cosminmihu.ro") }
            showNotification = true
            retentionPeriod = RetentionPeriod.OneHour
            maxContentLength = ContentLength.Default
        }
    )
    .build()
  • sanitizeHeader - sanitize sensitive headers to avoid their values appearing in the logs
  • filter - filter logs for calls matching a predicate.
  • showNotification - Keep track of latest requests and responses into notification. Default is true. Android and iOS only. Notifications permission needs to be granted.
  • retentionPeriod - The retention period for the logs. Default is 1h.
  • maxContentLength - The maximum length of the content that will be logged. After this, body will be truncated. Default is 250_000. To log the entire body use ContentLength.Full.

πŸ“¦ Setup (Android & JVM) for http4k

dependencies {
    debugImplementation("ro.cosminmihu.ktor:ktor-monitor-http4k-filter:1.13.0")
    releaseImplementation("ro.cosminmihu.ktor:ktor-monitor-http4k-filter-no-op:1.13.0")
}

For Android minSdk < 26, Core Library Desugaring is required.

Install http4k Filter

KtorMonitorFilter {
    sanitizeHeader { header -> header == "Authorization" }
    filter { request -> !request.uri.host.contains("cosminmihu.ro") }
    showNotification = true
    retentionPeriod = RetentionPeriod.OneHour
    maxContentLength = ContentLength.Default
}.then(JavaHttpClient())
  • sanitizeHeader - sanitize sensitive headers to avoid their values appearing in the logs
  • filter - filter logs for calls matching a predicate.
  • showNotification - Keep track of latest requests and responses into notification. Default is true. Android only. Notifications permission needs to be granted.
  • retentionPeriod - The retention period for the logs. Default is 1h.
  • maxContentLength - The maximum length of the content that will be logged. After this, body will be truncated. Default is 250_000. To log the entire body use ContentLength.Full.

🧩 Integration

Add the UI component to your application based on your targeted platform.

Compose Multiplatform (Common)
  • Use KtorMonitor Composable
@Composable
fun Composable() {
    KtorMonitor()
}
Android
  • If showNotifcation = true and android.permission.POST_NOTIFICATIONS is granted, the library will display a notification showing a summary of ongoing KTOR activity. Tapping on the notification launches the full KtorMonitor.
  • Apps can optionally use the KtorMonitor() Composable directly into own Composable code.
  • For Android minSdk < 26, Core Library Desugaring is required.
iOS
  • If showNotifcation = true and notification permission is granted, the library will display a notification showing a summary of ongoing KTOR activity.

  • Use KtorMonitorViewController

fun MainViewController() = KtorMonitorViewController()
struct KtorMonitorView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        MainViewControllerKt.MainViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}

struct ContentView: View {
    var body: some View {
        KtorMonitorView()
                .ignoresSafeArea()
    }
}
Desktop (Compose)
  • Use KtorMonitorWindow Composable
fun main() = application {

    var showKtorMonitor by rememberSaveable { mutableStateOf(false) }
    KtorMonitorWindow(
        onCloseRequest = { showKtorMonitor = false },
        show = showKtorMonitor
    )

}
  • Use KtorMonitorWindow Composable with KtorMonitorMenuItem
fun main() = application {

    var showKtorMonitor by rememberSaveable { mutableStateOf(false) }
    Tray(
        icon = painterResource(Res.drawable.ic_launcher),
        menu = {
            KtorMonitorMenuItem { showKtorMonitor = true }
        }
    )

    KtorMonitorWindow(
        show = showKtorMonitor,
        onCloseRequest = { showKtorMonitor = false }
    )

}
Desktop (Swing)
  • Use KtorMonitorPanel Swing Panel
fun main() = application {

    SwingUtilities.invokeLater {
        val frame = JFrame()
        frame.add(KtorMonitorPanel, BorderLayout.CENTER)
        frame.isVisible = true
    }

}
Wasm / Js
  • Web targets require a few additional webpack steps.
kotlin {
    sourceSets {
        webMain.dependencies {
            implementation(devNpm("copy-webpack-plugin", "9.1.0"))
        }
    }
}
// {project}/webpack.config.d/sqljs.js
config.resolve = {
    fallback: {
        fs: false,
        path: false,
        crypto: false,
    }
};

const CopyWebpackPlugin = require('copy-webpack-plugin');
config.plugins.push(
    new CopyWebpackPlugin({
        patterns: [
            '../../node_modules/sql.js/dist/sql-wasm.wasm'
        ]
    })
);
ComposeViewport {
    App()
}

✍️ Feedback

Found a bug or have a feature request? File an issue.

πŸ™Œ Acknowledgments

Kotlin Compose Multiplatform Android Ktor OkHttp http4k SQLDelight

Community discussions on Slack β€” join us in the #ktormonitor channel.
Documentation is available at KtorMonitor Documentation.
API is available at KtorMonitor API.
KtorMonitor is available also on JetBrains' klibs.io.
KtorMonitor on Context7.

Some parts of this project are reusing ideas that are originally coming from Chucker.
Thanks to ChuckerTeam for Chucker!
Thanks to JetBrains for Ktor and Kotlin!

Medium article: Ktor Monitor

πŸ’Έ Sponsors

KtorMonitor is maintained and improved during nights, weekends and whenever team has free time. If you use KtorMonitor in your project, please consider sponsoring us.

You can sponsor us by clicking β™₯ Sponsor.
Buy Me A Coffee

πŸ™πŸ» Credits

KtorMonitor is brought to you by these contributors.

Sponsor this project

  •  

Packages

 
 
 

Contributors