CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-client-core-jvm

Ktor HTTP client core library providing asynchronous HTTP client capabilities for Kotlin multiplatform applications

Pending
Overview
Eval results
Files

events-monitoring.mddocs/

Events and Monitoring

Client lifecycle events and monitoring hooks for observing request/response processing, error handling, and performance monitoring throughout the HTTP client lifecycle.

Capabilities

Client Events

Predefined event definitions for monitoring HTTP client operations.

/**
 * Container for HTTP client event definitions
 */
object ClientEvents {
    /** Fired when HTTP request is created */
    val HttpRequestCreated: EventDefinition<HttpRequestBuilder>
    
    /** Fired when HTTP request is ready for sending */
    val HttpRequestIsReadyForSending: EventDefinition<HttpRequestBuilder>
    
    /** Fired when HTTP response is received */
    val HttpResponseReceived: EventDefinition<HttpResponse>
    
    /** Fired when HTTP response receive fails */
    val HttpResponseReceiveFailed: EventDefinition<HttpResponseReceiveFail>
    
    /** Fired when HTTP response is cancelled */
    val HttpResponseCancelled: EventDefinition<HttpResponse>
}

Event Data Types

Data structures for event information.

/**
 * Information about failed response receive
 * @param request - The original HTTP request
 * @param cause - Exception that caused the failure
 */
data class HttpResponseReceiveFail(
    val request: HttpRequest,
    val cause: Throwable
)

/**
 * Event definition for typed events
 * @param T - Type of event data
 */
interface EventDefinition<T>

Event Monitoring

Subscribe to client events for monitoring and logging.

/**
 * Event monitoring interface
 */
interface Events {
    /** Subscribe to an event */
    fun <T> subscribe(definition: EventDefinition<T>, handler: suspend (T) -> Unit)
    
    /** Unsubscribe from an event */
    fun <T> unsubscribe(definition: EventDefinition<T>, handler: suspend (T) -> Unit)
    
    /** Raise an event */
    suspend fun <T> raise(definition: EventDefinition<T>, value: T)
}

// Access events through HttpClient
val HttpClient.monitor: Events

Usage Examples:

import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.utils.*

val client = HttpClient()

// Subscribe to request creation events
client.monitor.subscribe(ClientEvents.HttpRequestCreated) { request ->
    println("Request created: ${request.method.value} ${request.url}")
}

// Subscribe to response events
client.monitor.subscribe(ClientEvents.HttpResponseReceived) { response ->
    println("Response received: ${response.status} from ${response.call.request.url}")
}

// Subscribe to failure events
client.monitor.subscribe(ClientEvents.HttpResponseReceiveFailed) { failure ->
    println("Request failed: ${failure.request.url} - ${failure.cause.message}")
}

// Subscribe to cancellation events
client.monitor.subscribe(ClientEvents.HttpResponseCancelled) { response ->
    println("Response cancelled: ${response.call.request.url}")
}

// Make requests - events will be fired automatically
val response = client.get("https://api.example.com/users")

Custom Event Definitions

Create custom event definitions for application-specific monitoring.

/**
 * Create custom event definition
 */
fun <T> EventDefinition(): EventDefinition<T>

Custom Events Example:

import io.ktor.client.*
import io.ktor.client.utils.*

// Define custom events
val CustomRequestStart = EventDefinition<String>()
val CustomRequestComplete = EventDefinition<Pair<String, Long>>()

val client = HttpClient()

// Subscribe to custom events
client.monitor.subscribe(CustomRequestStart) { url ->
    println("Starting custom operation for: $url")
}

client.monitor.subscribe(CustomRequestComplete) { (url, duration) ->
    println("Completed custom operation for: $url in ${duration}ms")
}

// Raise custom events
suspend fun monitoredRequest(url: String) {
    client.monitor.raise(CustomRequestStart, url)
    val start = System.currentTimeMillis()
    
    try {
        val response = client.get(url)
        val duration = System.currentTimeMillis() - start
        client.monitor.raise(CustomRequestComplete, url to duration)
    } catch (e: Exception) {
        // Handle error and still fire completion event
        val duration = System.currentTimeMillis() - start
        client.monitor.raise(CustomRequestComplete, url to duration)
        throw e
    }
}

Event-Based Logging

Implement comprehensive logging using event monitoring.

import io.ktor.client.*
import io.ktor.client.utils.*
import kotlinx.coroutines.*

class HttpClientLogger(private val client: HttpClient) {
    
    init {
        setupEventMonitoring()
    }
    
    private fun setupEventMonitoring() {
        // Log all requests
        client.monitor.subscribe(ClientEvents.HttpRequestCreated) { request ->
            println("[REQUEST] ${request.method.value} ${request.url}")
            request.headers.entries().forEach { (name, values) ->
                println("[REQUEST-HEADER] $name: ${values.joinToString(", ")}")
            }
        }
        
        // Log successful responses
        client.monitor.subscribe(ClientEvents.HttpResponseReceived) { response ->
            println("[RESPONSE] ${response.status.value} ${response.status.description}")
            println("[TIMING] Request: ${response.requestTime}, Response: ${response.responseTime}")
        }
        
        // Log failures
        client.monitor.subscribe(ClientEvents.HttpResponseReceiveFailed) { failure ->
            println("[ERROR] Request to ${failure.request.url} failed: ${failure.cause.message}")
            failure.cause.printStackTrace()
        }
        
        // Log cancellations
        client.monitor.subscribe(ClientEvents.HttpResponseCancelled) { response ->
            println("[CANCELLED] Request to ${response.call.request.url} was cancelled")
        }
    }
}

// Usage
val client = HttpClient()
val logger = HttpClientLogger(client)

// All requests will now be logged automatically
val response = client.get("https://api.example.com/users")

Performance Monitoring

Use events for performance tracking and metrics collection.

import io.ktor.client.*
import io.ktor.client.utils.*

class HttpPerformanceMonitor(private val client: HttpClient) {
    private val requestTimes = mutableMapOf<HttpRequest, Long>()
    
    init {
        // Track request start times
        client.monitor.subscribe(ClientEvents.HttpRequestIsReadyForSending) { request ->
            requestTimes[request] = System.currentTimeMillis()
        }
        
        // Calculate and log response times
        client.monitor.subscribe(ClientEvents.HttpResponseReceived) { response ->
            val startTime = requestTimes.remove(response.call.request)
            if (startTime != null) {
                val duration = System.currentTimeMillis() - startTime
                println("Request to ${response.call.request.url} took ${duration}ms")
                
                // Could send to metrics system here
                recordMetric("http.request.duration", duration, 
                    mapOf("url" to response.call.request.url.toString(),
                          "method" to response.call.request.method.value,
                          "status" to response.status.value.toString()))
            }
        }
        
        // Clean up on failures
        client.monitor.subscribe(ClientEvents.HttpResponseReceiveFailed) { failure ->
            requestTimes.remove(failure.request)
        }
    }
    
    private fun recordMetric(name: String, value: Long, tags: Map<String, String>) {
        // Implementation for your metrics system
        println("METRIC: $name = $value, tags = $tags")
    }
}

Event Lifecycle

  1. HttpRequestCreated - Fired when HttpRequestBuilder is created and configured
  2. HttpRequestIsReadyForSending - Fired just before the request is sent to the engine
  3. HttpResponseReceived - Fired when a successful response is received
  4. HttpResponseReceiveFailed - Fired when response receiving fails
  5. HttpResponseCancelled - Fired when response processing is cancelled

Events provide a clean way to implement cross-cutting concerns like logging, metrics, caching, and debugging without modifying core client code.

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-core-jvm

docs

client-configuration.md

content-handling.md

engine-architecture.md

events-monitoring.md

http-statement.md

index.md

plugin-system.md

request-building.md

response-handling.md

websocket-support.md

tile.json