Logging plugin for Ktor HTTP client that provides comprehensive request and response logging capabilities with configurable loggers, levels, and sanitization for sensitive data
—
Internal utility functions and components that provide core functionality for HTTP request/response logging and content handling.
Binary content detection and text extraction utilities for processing request/response bodies.
/**
* Safely attempts to read text content from a ByteReadChannel
* @param charset Character encoding to use for text decoding
* @return Decoded text string or null if reading fails
*/
internal suspend inline fun ByteReadChannel.tryReadText(charset: Charset): String?Usage Examples:
import io.ktor.utils.io.charsets.*
// Safe text reading with fallback
val content: ByteReadChannel = response.rawContent
val text = content.tryReadText(Charsets.UTF_8) ?: "[content unavailable]"Helper functions for formatting and appending log output consistently across different logging scenarios.
/**
* Appends formatted headers to log output with sanitization support
* @param headers Set of header entries to log
* @param sanitizedHeaders List of header sanitization rules
*/
internal fun Appendable.logHeaders(
headers: Set<Map.Entry<String, List<String>>>,
sanitizedHeaders: List<SanitizedHeader>
)
/**
* Appends a single formatted header to log output
* @param key Header name
* @param value Header value (may be sanitized)
*/
internal fun Appendable.logHeader(key: String, value: String)
/**
* Formats and logs HTTP response header information
* @param log StringBuilder to append log content to
* @param response HttpResponse to extract headers from
* @param level Current logging level configuration
* @param sanitizedHeaders List of header sanitization rules
*/
internal fun logResponseHeader(
log: StringBuilder,
response: HttpResponse,
level: LogLevel,
sanitizedHeaders: List<SanitizedHeader>
)Specialized utilities for logging response body content with proper content type handling.
/**
* Extension function for HttpClientCallLogger to log response body content
* @param response HttpResponse containing the body to log
*/
internal suspend fun HttpClientCallLogger.logResponseBody(response: HttpResponse)
/**
* Appends formatted response body content to a StringBuilder
* @param contentType MIME type of the response content
* @param content ByteReadChannel containing the response body
*/
internal suspend fun StringBuilder.appendResponseBody(
contentType: ContentType?,
content: ByteReadChannel
)Usage Examples:
// Internal usage within the logging plugin
val callLogger = HttpClientCallLogger(logger)
callLogger.logResponseBody(response)
// Manual response body formatting
val log = StringBuilder()
log.appendResponseBody(response.contentType(), response.rawContent)The internal logger component that coordinates request and response logging with proper synchronization.
/**
* Internal logger for coordinating HTTP request/response logging
* Provides thread-safe logging with proper request/response correlation
*/
internal class HttpClientCallLogger(private val logger: Logger) {
/**
* Log request information
* @param message Request log message
*/
fun logRequest(message: String)
/**
* Log response header information
* @param message Response header log message
*/
fun logResponseHeader(message: String)
/**
* Log response exception information
* @param message Exception log message
*/
suspend fun logResponseException(message: String)
/**
* Log response body information
* @param message Response body log message
*/
suspend fun logResponseBody(message: String)
/**
* Close and flush request logging
*/
fun closeRequestLog()
/**
* Close and flush response logging
*/
suspend fun closeResponseLog()
}Usage Examples:
// Internal usage within the logging plugin
val callLogger = HttpClientCallLogger(Logger.DEFAULT)
// Log request details
callLogger.logRequest("REQUEST: https://api.example.com/users")
callLogger.logRequest("METHOD: GET")
callLogger.closeRequestLog()
// Log response details
callLogger.logResponseHeader("RESPONSE: 200 OK")
callLogger.logResponseBody("{"users": []}")
callLogger.closeResponseLog()The HttpClientCallLogger uses atomic operations and coroutine synchronization to ensure thread-safe logging:
The content detection utilities handle various scenarios:
The header logging utilities implement consistent sanitization:
These utilities are designed for production use:
Install with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-client-logging