0
# Utilities
1
2
Internal utility functions and components that provide core functionality for HTTP request/response logging and content handling.
3
4
## Capabilities
5
6
### Content Detection and Handling
7
8
Binary content detection and text extraction utilities for processing request/response bodies.
9
10
```kotlin { .api }
11
/**
12
* Safely attempts to read text content from a ByteReadChannel
13
* @param charset Character encoding to use for text decoding
14
* @return Decoded text string or null if reading fails
15
*/
16
internal suspend inline fun ByteReadChannel.tryReadText(charset: Charset): String?
17
```
18
19
**Usage Examples:**
20
21
```kotlin
22
import io.ktor.utils.io.charsets.*
23
24
// Safe text reading with fallback
25
val content: ByteReadChannel = response.rawContent
26
val text = content.tryReadText(Charsets.UTF_8) ?: "[content unavailable]"
27
```
28
29
### Logging Utilities
30
31
Helper functions for formatting and appending log output consistently across different logging scenarios.
32
33
```kotlin { .api }
34
/**
35
* Appends formatted headers to log output with sanitization support
36
* @param headers Set of header entries to log
37
* @param sanitizedHeaders List of header sanitization rules
38
*/
39
internal fun Appendable.logHeaders(
40
headers: Set<Map.Entry<String, List<String>>>,
41
sanitizedHeaders: List<SanitizedHeader>
42
)
43
44
/**
45
* Appends a single formatted header to log output
46
* @param key Header name
47
* @param value Header value (may be sanitized)
48
*/
49
internal fun Appendable.logHeader(key: String, value: String)
50
51
/**
52
* Formats and logs HTTP response header information
53
* @param log StringBuilder to append log content to
54
* @param response HttpResponse to extract headers from
55
* @param level Current logging level configuration
56
* @param sanitizedHeaders List of header sanitization rules
57
*/
58
internal fun logResponseHeader(
59
log: StringBuilder,
60
response: HttpResponse,
61
level: LogLevel,
62
sanitizedHeaders: List<SanitizedHeader>
63
)
64
```
65
66
### Response Body Logging
67
68
Specialized utilities for logging response body content with proper content type handling.
69
70
```kotlin { .api }
71
/**
72
* Extension function for HttpClientCallLogger to log response body content
73
* @param response HttpResponse containing the body to log
74
*/
75
internal suspend fun HttpClientCallLogger.logResponseBody(response: HttpResponse)
76
77
/**
78
* Appends formatted response body content to a StringBuilder
79
* @param contentType MIME type of the response content
80
* @param content ByteReadChannel containing the response body
81
*/
82
internal suspend fun StringBuilder.appendResponseBody(
83
contentType: ContentType?,
84
content: ByteReadChannel
85
)
86
```
87
88
**Usage Examples:**
89
90
```kotlin
91
// Internal usage within the logging plugin
92
val callLogger = HttpClientCallLogger(logger)
93
callLogger.logResponseBody(response)
94
95
// Manual response body formatting
96
val log = StringBuilder()
97
log.appendResponseBody(response.contentType(), response.rawContent)
98
```
99
100
### Internal Call Logger
101
102
The internal logger component that coordinates request and response logging with proper synchronization.
103
104
```kotlin { .api }
105
/**
106
* Internal logger for coordinating HTTP request/response logging
107
* Provides thread-safe logging with proper request/response correlation
108
*/
109
internal class HttpClientCallLogger(private val logger: Logger) {
110
/**
111
* Log request information
112
* @param message Request log message
113
*/
114
fun logRequest(message: String)
115
116
/**
117
* Log response header information
118
* @param message Response header log message
119
*/
120
fun logResponseHeader(message: String)
121
122
/**
123
* Log response exception information
124
* @param message Exception log message
125
*/
126
suspend fun logResponseException(message: String)
127
128
/**
129
* Log response body information
130
* @param message Response body log message
131
*/
132
suspend fun logResponseBody(message: String)
133
134
/**
135
* Close and flush request logging
136
*/
137
fun closeRequestLog()
138
139
/**
140
* Close and flush response logging
141
*/
142
suspend fun closeResponseLog()
143
}
144
```
145
146
**Usage Examples:**
147
148
```kotlin
149
// Internal usage within the logging plugin
150
val callLogger = HttpClientCallLogger(Logger.DEFAULT)
151
152
// Log request details
153
callLogger.logRequest("REQUEST: https://api.example.com/users")
154
callLogger.logRequest("METHOD: GET")
155
callLogger.closeRequestLog()
156
157
// Log response details
158
callLogger.logResponseHeader("RESPONSE: 200 OK")
159
callLogger.logResponseBody("{"users": []}")
160
callLogger.closeResponseLog()
161
```
162
163
## Implementation Notes
164
165
### Thread Safety
166
167
The `HttpClientCallLogger` uses atomic operations and coroutine synchronization to ensure thread-safe logging:
168
169
- Atomic flags prevent duplicate logging
170
- Job monitors coordinate request/response log timing
171
- Proper cleanup ensures resources are released
172
173
### Content Type Detection
174
175
The content detection utilities handle various scenarios:
176
177
- Binary content detection based on encoding headers
178
- Character encoding detection and fallback to UTF-8
179
- Malformed content handling with graceful degradation
180
- Memory-efficient streaming for large content
181
182
### Header Sanitization
183
184
The header logging utilities implement consistent sanitization:
185
186
- Configurable placeholder replacement
187
- Pattern-based header matching
188
- Sorted header output for consistent logs
189
- Efficient lookup using predicate functions
190
191
### Performance Considerations
192
193
These utilities are designed for production use:
194
195
- Lazy evaluation where possible
196
- Minimal memory allocation
197
- Efficient string building
198
- Proper resource cleanup