CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/kotlin-io-ktor--ktor-client-logging-macosx64

HTTP client logging plugin for Ktor framework with configurable log levels and header sanitization support

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Ktor Client Logging

Ktor Client Logging provides comprehensive HTTP client logging capabilities for the Ktor framework. It offers configurable logging levels, request/response filtering, header sanitization, and platform-specific logger implementations with full coroutine support.

Package Information

  • Package Name: io.ktor:ktor-client-logging-macosx64
  • Package Type: Kotlin Multiplatform Library (macOS x64)
  • Language: Kotlin
  • Installation: Add to your build.gradle.kts dependencies
  • Framework: Ktor HTTP Client Plugin
  • Platform: macOS x64 (Kotlin/Native)

Core Imports

import io.ktor.client.plugins.logging.*
import io.ktor.client.*

Basic Usage

import io.ktor.client.*
import io.ktor.client.plugins.logging.*

// Basic logging configuration
val client = HttpClient {
    install(Logging) {
        level = LogLevel.HEADERS
        logger = Logger.DEFAULT
    }
}

// Advanced configuration with filtering and sanitization
val client = HttpClient {
    install(Logging) {
        level = LogLevel.ALL
        logger = Logger.SIMPLE
        
        // Filter requests to only log specific URLs
        filter { request ->
            request.url.host.contains("api.example.com")
        }
        
        // Sanitize sensitive headers
        sanitizeHeader("***") { header ->
            header == "Authorization" || header == "API-Key"
        }
    }
}

// Make logged HTTP requests
client.get("https://api.example.com/users")

Architecture

Ktor Client Logging integrates with the Ktor HTTP client pipeline through several key components:

  • Plugin System: Implements HttpClientPlugin for seamless integration with Ktor clients
  • Pipeline Interception: Intercepts both request and response pipelines for comprehensive logging
  • Configurable Filtering: Request-level filtering to control what gets logged
  • Header Sanitization: Secure handling of sensitive header values
  • Platform Abstraction: Platform-specific logger implementations (SLF4J, Android Logcat, console)
  • Asynchronous Logging: Full coroutine support for non-blocking log operations
  • Content Observation: Advanced content streaming observation for body logging

Capabilities

Plugin Installation and Configuration

Main plugin class providing HTTP client logging capabilities with extensive configuration options.

/**
 * A client's plugin that provides the capability to log HTTP calls.
 */
class Logging private constructor(
    val logger: Logger,
    var level: LogLevel,
    var filters: List<(HttpRequestBuilder) -> Boolean> = emptyList()
) {
    companion object : HttpClientPlugin<Config, Logging> {
        override val key: AttributeKey<Logging>
        override fun prepare(block: Config.() -> Unit): Logging
        override fun install(plugin: Logging, scope: HttpClient)
    }
}

/**
 * A configuration for the Logging plugin.
 */
class Logging.Config {
    /** Specifies a Logger instance */
    var logger: Logger
    /** Specifies the logging level */
    var level: LogLevel
    
    /** Allows you to filter log messages for calls matching a predicate */
    fun filter(predicate: (HttpRequestBuilder) -> Boolean)
    
    /** Allows you to sanitize sensitive headers to avoid their values appearing in the logs */
    fun sanitizeHeader(placeholder: String = "***", predicate: (String) -> Boolean)
}

/**
 * Configures and installs Logging in HttpClient.
 */
fun HttpClientConfig<*>.Logging(block: Logging.Config.() -> Unit = {})

Logging Levels

Defines the verbosity and scope of HTTP logging operations.

/**
 * Logging log level.
 */
enum class LogLevel(
    val info: Boolean,
    val headers: Boolean,
    val body: Boolean
) {
    /** Log everything: request/response info, headers, and body content */
    ALL(true, true, true),
    
    /** Log request/response info and headers, but not body content */
    HEADERS(true, true, false),
    
    /** Log request/response info and body content, but not headers */
    BODY(true, false, true),
    
    /** Log only basic request/response information */
    INFO(true, false, false),
    
    /** Disable all logging */
    NONE(false, false, false)
}

Logger Interface and Implementations

Core logging abstraction with platform-specific implementations.

/**
 * HttpClient Logger interface.
 */
interface Logger {
    /** Add message to log */
    fun log(message: String)
    
    companion object
}

Logger Factory Methods

/**
 * Default logger to use (platform-specific implementation).
 */
val Logger.Companion.DEFAULT: Logger

/**
 * Logger using println for simple console output.
 */
val Logger.Companion.SIMPLE: Logger

/**
 * Empty Logger for test purposes - logs nothing.
 */
val Logger.Companion.EMPTY: Logger

Platform-Specific Logger Extensions

Native/macOS Platform
/**
 * Message Length Limiting Logger: Breaks up log messages into multiple logs no longer than maxLength.
 * Useful for platforms with log message length limitations.
 */
class MessageLengthLimitingLogger(
    private val maxLength: Int = 4000,
    private val minLength: Int = 3000,
    private val delegate: Logger = Logger.DEFAULT
) : Logger {
    override fun log(message: String)
}

Types

Core Data Types

/**
 * HTTP request builder type for filtering predicates.
 */
typealias HttpRequestBuilder = io.ktor.client.request.HttpRequestBuilder

Usage Examples

Basic Request Logging

import io.ktor.client.*
import io.ktor.client.plugins.logging.*
import io.ktor.client.request.*

val client = HttpClient {
    install(Logging) {
        level = LogLevel.INFO
    }
}

// This will log basic request/response information
val response = client.get("https://httpbin.org/get")

Comprehensive Logging with Headers and Body

val client = HttpClient {
    install(Logging) {
        level = LogLevel.ALL
        logger = Logger.SIMPLE
    }
}

// This will log complete request/response including headers and body
val response = client.post("https://httpbin.org/post") {
    setBody("Request body content")
}

Filtered Logging with Header Sanitization

val client = HttpClient {
    install(Logging) {
        level = LogLevel.HEADERS
        logger = Logger.DEFAULT
        
        // Only log requests to specific domains
        filter { request ->
            request.url.host.endsWith("example.com")
        }
        
        // Sanitize authorization headers
        sanitizeHeader("***") { headerName ->
            headerName.equals("Authorization", ignoreCase = true)
        }
        
        // Sanitize multiple header types
        sanitizeHeader("[REDACTED]") { headerName ->
            headerName in listOf("API-Key", "X-Auth-Token", "Cookie")
        }
    }
}

Native/macOS-Specific Logging

// On Native platforms, use simple console logging
val client = HttpClient {
    install(Logging) {
        level = LogLevel.HEADERS
        logger = Logger.SIMPLE  // Console logging for Native platforms
    }
}

Custom Logger Implementation

class CustomLogger : Logger {
    override fun log(message: String) {
        // Custom logging logic - could write to file, send to analytics, etc.
        println("[CUSTOM] $message")
    }
}

val client = HttpClient {
    install(Logging) {
        level = LogLevel.ALL
        logger = CustomLogger()
    }
}

Multiple Filter Conditions

val client = HttpClient {
    install(Logging) {
        level = LogLevel.HEADERS
        
        // Log only successful responses
        filter { request ->
            // This will be evaluated for each request
            request.url.host.contains("api")
        }
        
        // Add multiple filters
        filter { request ->
            request.method.value == "POST"
        }
    }
}

Error Handling

The Logging plugin handles errors gracefully:

  • Request logging failures: If request logging fails, the request continues normally
  • Response logging failures: Response processing continues even if logging fails
  • Content reading errors: Body content that can't be read is logged as "[request/response body omitted]"
  • Logger exceptions: Plugin catches and suppresses logger implementation exceptions to prevent request failures

Platform Compatibility

  • macOS x64 (Kotlin/Native): Uses simple console logging with println
  • Native platforms: Support for custom logger implementations
  • Cross-platform: Same API surface across all Kotlin Multiplatform targets

docs

index.md

tile.json