Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
KtorMonitor
https://github.com/cosminmihumdc/ktormonitor
Admin
Powerful tool to monitor Ktor Client and OkHttp requests and responses, making it easier to debug
...
Tokens:
1,567
Snippets:
16
Trust Score:
7.9
Update:
1 week ago
Context
Skills
Chat
Benchmark
84.2
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# KtorMonitor KtorMonitor is a powerful Kotlin Multiplatform library for monitoring and debugging HTTP network traffic from Ktor Client and OkHttp. It provides real-time interception and logging of network requests and responses with a built-in UI for viewing traffic details, making it easier to debug and analyze network communication in your applications. The library supports Android, iOS, Desktop (JVM), WebAssembly, and JavaScript platforms. Key features include header sanitization for security, configurable retention periods, content length limits, rich previews for JSON/XML/HTML/CSS/images, and support for WebSockets and Server-Sent Events (SSE). A no-op variant is available for production builds to ensure monitoring code is excluded from release artifacts. ## Installation ### Gradle Setup for Ktor Client (Kotlin Multiplatform) Add the KtorMonitor dependency to your Kotlin Multiplatform project for intercepting Ktor Client HTTP traffic. ```kotlin // build.gradle.kts kotlin { sourceSets { commonMain.dependencies { implementation("ro.cosminmihu.ktor:ktor-monitor-logging:1.11.1") } } } ``` ### Gradle Setup for Ktor Client (Android Only) Configure debug and release dependencies to exclude monitoring code from production builds. ```kotlin // build.gradle.kts dependencies { debugImplementation("ro.cosminmihu.ktor:ktor-monitor-logging:1.11.1") releaseImplementation("ro.cosminmihu.ktor:ktor-monitor-logging-no-op:1.11.1") } ``` ### Gradle Setup for OkHttp (Android & JVM) Add the OkHttp interceptor dependency for monitoring OkHttp network traffic. ```kotlin // build.gradle.kts dependencies { debugImplementation("ro.cosminmihu.ktor:ktor-monitor-okhttp-interceptor:1.11.1") releaseImplementation("ro.cosminmihu.ktor:ktor-monitor-okhttp-interceptor-no-op:1.11.1") } ``` ## KtorMonitorLogging Plugin The `KtorMonitorLogging` is a Ktor Client plugin that intercepts and logs all HTTP requests and responses. It supports filtering requests, sanitizing sensitive headers, configuring retention periods, and controlling notification behavior. ```kotlin import io.ktor.client.HttpClient import io.ktor.client.plugins.sse.SSE import io.ktor.client.plugins.websocket.WebSockets import io.ktor.client.request.get import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.http.ContentType import io.ktor.http.contentType import ro.cosminmihu.ktor.monitor.ContentLength import ro.cosminmihu.ktor.monitor.KtorMonitorLogging import ro.cosminmihu.ktor.monitor.RetentionPeriod // Create HttpClient with KtorMonitorLogging plugin val client = HttpClient { install(KtorMonitorLogging) { // Sanitize Authorization header - value will show as "***" sanitizeHeader { header -> header == "Authorization" } // Filter out requests to specific hosts filter { request -> !request.url.host.contains("internal.api.com") } // Enable/disable logging (default: true) isActive = true // Show notification on Android/iOS (default: true) showNotification = true // Set log retention period (default: 1 hour) retentionPeriod = RetentionPeriod.OneHour // Set max content length before truncation (default: 250,000) maxContentLength = ContentLength.Default } // Optional: Add WebSocket and SSE support install(WebSockets) install(SSE) } // Make HTTP requests - they will be automatically logged suspend fun fetchData() { // GET request val response = client.get("https://api.example.com/users") // POST request with JSON body client.post("https://api.example.com/users") { contentType(ContentType.Application.Json) setBody("""{"name": "John", "email": "john@example.com"}""") } } ``` ## KtorMonitorInterceptor for OkHttp The `KtorMonitorInterceptor` is an OkHttp network interceptor that provides the same monitoring capabilities for OkHttp-based HTTP clients. It must be added as a network interceptor to capture all traffic including redirects. ```kotlin import okhttp3.OkHttpClient import okhttp3.Request import ro.cosminmihu.ktor.monitor.ContentLength import ro.cosminmihu.ktor.monitor.KtorMonitorInterceptor import ro.cosminmihu.ktor.monitor.RetentionPeriod // Create OkHttpClient with KtorMonitorInterceptor val okHttpClient = OkHttpClient.Builder() .addNetworkInterceptor( KtorMonitorInterceptor { // Sanitize sensitive headers sanitizeHeader { header -> header == "Authorization" } sanitizeHeader(placeholder = "[REDACTED]") { header -> header == "X-Api-Key" } // Filter requests by URL filter { request -> !request.url.host.contains("analytics.com") } // Enable monitoring isActive = true // Show system notifications showNotification = true // Keep logs for one day retentionPeriod = RetentionPeriod.OneDay // Log full response bodies maxContentLength = ContentLength.Full } ) .build() // Make HTTP requests - they will be automatically logged fun fetchUsers() { val request = Request.Builder() .url("https://api.example.com/users") .header("Authorization", "Bearer token123") .build() okHttpClient.newCall(request).execute().use { response -> println("Response code: ${response.code}") println("Body: ${response.body?.string()}") } } ``` ## RetentionPeriod Configuration The `RetentionPeriod` object provides predefined durations for how long network logs are kept before automatic cleanup. ```kotlin import ro.cosminmihu.ktor.monitor.RetentionPeriod import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.days // Available predefined retention periods: val oneHour = RetentionPeriod.OneHour // 1 hour (default) val oneDay = RetentionPeriod.OneDay // 24 hours val oneWeek = RetentionPeriod.OneWeek // 7 days val forever = RetentionPeriod.Forever // Never deleted (Duration.INFINITE) // Custom retention period using Kotlin Duration val customRetention = 6.hours val customLongRetention = 30.days // Usage in configuration HttpClient { install(KtorMonitorLogging) { retentionPeriod = RetentionPeriod.OneWeek // Keep logs for 7 days } } ``` ## ContentLength Configuration The `ContentLength` object provides constants for controlling the maximum size of request/response bodies that will be logged. Bodies exceeding this limit are truncated. ```kotlin import ro.cosminmihu.ktor.monitor.ContentLength // Available content length options: val defaultLength = ContentLength.Default // 250,000 characters (default) val fullLength = ContentLength.Full // Int.MAX_VALUE (no truncation) // Custom content length val customLength = 100_000 // 100KB limit // Usage in configuration HttpClient { install(KtorMonitorLogging) { // Log full bodies without truncation (useful for debugging large responses) maxContentLength = ContentLength.Full } } OkHttpClient.Builder() .addNetworkInterceptor( KtorMonitorInterceptor { // Limit logged body size to 100KB maxContentLength = 100_000 } ) .build() ``` ## KtorMonitor Composable (Multiplatform) The `KtorMonitor` composable function is the main UI entry point for displaying the network monitor interface in Compose Multiplatform applications. It shows a list of all captured requests with detailed views for headers, bodies, and timing information. ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import ro.cosminmihu.ktor.monitor.KtorMonitor @Composable fun NetworkMonitorScreen() { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { // Display the KtorMonitor UI KtorMonitor( modifier = Modifier.fillMaxSize(), useKtorMonitorTheme = true // Use built-in theme (default: true) ) } } // Example: App with network monitor and automatic request generation @Composable fun App() { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { KtorMonitor() } // Launch network requests when composable is first displayed LaunchedEffect(Unit) { val client = httpClient() client.get("https://httpbin.org/get") client.post("https://httpbin.org/post") } } ``` ## KtorMonitorWindow (Desktop Compose) The `KtorMonitorWindow` composable creates a dedicated window for the network monitor on Desktop (JVM) platforms. It can be toggled on/off and integrates with system tray menus. ```kotlin import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.window.Tray import androidx.compose.ui.window.Window import androidx.compose.ui.window.application import org.jetbrains.compose.resources.painterResource import ro.cosminmihu.ktor.monitor.KtorMonitorMenuItem import ro.cosminmihu.ktor.monitor.KtorMonitorWindow fun main() = application { // State to control monitor window visibility var showKtorMonitor by rememberSaveable { mutableStateOf(false) } // System tray with menu item to open monitor Tray( icon = painterResource(Res.drawable.ic_launcher), menu = { KtorMonitorMenuItem { showKtorMonitor = true } } ) // KtorMonitor window (shown when showKtorMonitor is true) KtorMonitorWindow( show = showKtorMonitor, useLibraryTheme = true, onCloseRequest = { showKtorMonitor = false } ) // Main application window Window( onCloseRequest = ::exitApplication, title = "My Application", ) { MainAppContent() } } ``` ## KtorMonitorPanel (Desktop Swing) The `KtorMonitorPanel` is a Swing JPanel component for integrating the network monitor into Swing-based desktop applications. ```kotlin import ro.cosminmihu.ktor.monitor.KtorMonitorPanel import java.awt.BorderLayout import java.awt.Dimension import javax.swing.JFrame import javax.swing.SwingUtilities fun main() { // Launch network requests in background GlobalScope.launch { val client = httpClient() client.get("https://httpbin.org/get") client.get("https://httpbin.org/json") } // Create Swing UI on EDT SwingUtilities.invokeLater { val frame = JFrame("Network Monitor") frame.minimumSize = Dimension(800, 600) frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE // Add KtorMonitorPanel to the frame frame.add(KtorMonitorPanel, BorderLayout.CENTER) frame.pack() frame.isVisible = true } } ``` ## KtorMonitorViewController (iOS) The `KtorMonitorViewController` function creates a UIViewController for displaying the network monitor in iOS applications, compatible with SwiftUI through UIViewControllerRepresentable. ```kotlin // Kotlin (shared module) import ro.cosminmihu.ktor.monitor.KtorMonitorViewController import platform.UIKit.UIViewController fun MainViewController(): UIViewController = KtorMonitorViewController() ``` ```swift // Swift (iOS app) import SwiftUI 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() } } // Alternative: Navigation-based integration struct AppView: View { @State private var showMonitor = false var body: some View { NavigationStack { VStack { Button("Show Network Monitor") { showMonitor = true } } .sheet(isPresented: $showMonitor) { KtorMonitorView() } } } } ``` ## WebSocket Monitoring KtorMonitor automatically tracks WebSocket connections when the Ktor WebSockets plugin is installed. It logs all sent and received frames, providing full visibility into bidirectional traffic. ```kotlin import io.ktor.client.HttpClient import io.ktor.client.plugins.websocket.WebSockets import io.ktor.client.plugins.websocket.webSocket import io.ktor.websocket.Frame import io.ktor.websocket.readText import kotlinx.coroutines.delay import kotlinx.coroutines.flow.consumeAsFlow import kotlinx.coroutines.launch import kotlin.time.Duration.Companion.seconds import ro.cosminmihu.ktor.monitor.KtorMonitorLogging val client = HttpClient { install(KtorMonitorLogging) install(WebSockets) } suspend fun connectWebSocket() { client.webSocket(host = "echo.websocket.org") { // Receive frames in a coroutine launch { incoming.consumeAsFlow().collect { frame -> if (frame is Frame.Text) { println("Received: ${frame.readText()}") } } } // Send frames repeat(5) { index -> delay(1.seconds) send(Frame.Text("Message #$index")) } } } ``` ## Server-Sent Events (SSE) Monitoring KtorMonitor tracks Server-Sent Events when the Ktor SSE plugin is installed, logging all incoming events with their data and event types. ```kotlin import io.ktor.client.HttpClient import io.ktor.client.plugins.sse.SSE import io.ktor.client.plugins.sse.sse import ro.cosminmihu.ktor.monitor.KtorMonitorLogging val client = HttpClient { install(KtorMonitorLogging) install(SSE) } suspend fun connectSSE() { client.sse( scheme = "https", host = "api.example.com", path = "/events" ) { incoming.collect { event -> println("Event: ${event.event}") println("Data: ${event.data}") println("ID: ${event.id}") } } } ``` ## Web Platform Configuration (Wasm/JS) Web targets require additional webpack configuration to support the SQLite database used by KtorMonitor for storing logs. ```kotlin // build.gradle.kts kotlin { sourceSets { webMain.dependencies { implementation(devNpm("copy-webpack-plugin", "9.1.0")) } } } ``` ```javascript // 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' ] }) ); ``` ```kotlin // Main entry point for web import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.window.ComposeViewport import kotlinx.browser.document import ro.cosminmihu.ktor.monitor.KtorMonitor @OptIn(ExperimentalComposeUiApi::class) fun main() { ComposeViewport(document.body!!) { KtorMonitor() } } ``` ## Android Integration with Notifications On Android, KtorMonitor can display system notifications summarizing network activity. Tapping the notification opens the full monitor UI. This requires POST_NOTIFICATIONS permission on Android 13+. ```kotlin // AndroidManifest.xml // <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import io.ktor.client.HttpClient import ro.cosminmihu.ktor.monitor.KtorMonitor import ro.cosminmihu.ktor.monitor.KtorMonitorLogging class MainActivity : ComponentActivity() { private val client = HttpClient { install(KtorMonitorLogging) { // Enable notifications (requires POST_NOTIFICATIONS permission) showNotification = true retentionPeriod = RetentionPeriod.OneHour } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { // Display the network monitor KtorMonitor() } } } ``` ## Summary KtorMonitor is designed for developers who need comprehensive visibility into their application's network communication during development and debugging. The primary use cases include debugging API integration issues, monitoring request/response payloads, identifying slow network calls, and tracking real-time WebSocket and SSE traffic. The library's support for header sanitization ensures sensitive data like authorization tokens are never exposed in logs. Integration patterns vary by platform: Android and iOS apps can leverage system notifications for passive monitoring, desktop applications can use either Compose windows or Swing panels, and web applications require additional webpack configuration for SQLite support. The no-op variants enable seamless integration into debug builds while ensuring zero overhead in production. For teams using both Ktor and OkHttp, KtorMonitor provides a unified monitoring interface across both HTTP clients with identical configuration options.