0
# Logger Implementations
1
2
The Ktor Client Logging plugin provides a pluggable logger system with multiple built-in implementations optimized for different platforms and use cases.
3
4
## Required Imports
5
6
```kotlin
7
import io.ktor.client.*
8
import io.ktor.client.plugins.logging.*
9
import org.slf4j.LoggerFactory // JVM only
10
import android.util.Log // Android only
11
```
12
13
## Logger Interface
14
15
```kotlin { .api }
16
interface Logger {
17
fun log(message: String)
18
19
companion object
20
}
21
```
22
23
The core logger interface that all logging implementations must implement.
24
25
### Methods
26
27
#### log(message)
28
Outputs a log message using the logger's implementation-specific mechanism.
29
30
**Parameters:**
31
- `message`: The string message to log
32
33
## Built-in Logger Implementations
34
35
### Default Logger
36
37
```kotlin { .api }
38
val Logger.Companion.DEFAULT: Logger
39
```
40
41
Platform-specific default logger implementation:
42
43
- **JVM**: Uses SLF4J with HttpClient class logger
44
- **JavaScript/WASM**: Uses `Logger.SIMPLE`
45
- **Native/Posix**: Uses `Logger.SIMPLE`
46
47
**JVM Implementation Details:**
48
```kotlin
49
// Uses SLF4J LoggerFactory
50
private val delegate = LoggerFactory.getLogger(HttpClient::class.java)
51
override fun log(message: String) {
52
delegate.info(message)
53
}
54
```
55
56
**Usage:**
57
```kotlin
58
Logging {
59
logger = Logger.DEFAULT
60
}
61
```
62
63
### Simple Logger
64
65
```kotlin { .api }
66
val Logger.Companion.SIMPLE: Logger
67
```
68
69
Basic logger implementation that outputs to console using `println`.
70
71
**Implementation:**
72
```kotlin
73
override fun log(message: String) {
74
println("HttpClient: $message")
75
}
76
```
77
78
**Usage:**
79
```kotlin
80
Logging {
81
logger = Logger.SIMPLE
82
}
83
```
84
85
### Empty Logger
86
87
```kotlin { .api }
88
val Logger.Companion.EMPTY: Logger
89
```
90
91
No-operation logger for testing purposes. Discards all log messages.
92
93
**Usage:**
94
```kotlin
95
Logging {
96
logger = Logger.EMPTY // For testing
97
}
98
```
99
100
## JVM-Specific Loggers
101
102
### Android Logger
103
104
```kotlin { .api }
105
val Logger.Companion.ANDROID: Logger
106
```
107
108
Android-optimized logger with the following features:
109
110
- **Logcat Integration**: Uses Android's `android.util.Log` when available
111
- **SLF4J Fallback**: Falls back to SLF4J logging when Logcat is unavailable
112
- **Message Length Limiting**: Automatically breaks long messages for Android's log limits
113
- **Lazy Initialization**: Logger is created on first access
114
115
**Features:**
116
- Maximum message length: 4000 characters
117
- Minimum length for newline breaking: 3000 characters
118
- Tag: "Ktor Client"
119
- Graceful fallback to SLF4J if Android Log class is not found
120
121
**Usage:**
122
```kotlin
123
Logging {
124
logger = Logger.ANDROID
125
}
126
```
127
128
### Message Length Limiting Logger
129
130
```kotlin { .api }
131
class MessageLengthLimitingLogger(
132
private val maxLength: Int = 4000,
133
private val minLength: Int = 3000,
134
private val delegate: Logger = Logger.DEFAULT
135
) : Logger
136
```
137
138
Wrapper logger that breaks long messages into multiple log entries. Particularly useful for platforms with message length restrictions.
139
140
**Constructor Parameters:**
141
- `maxLength`: Maximum allowed length for a single log message (default: 4000)
142
- `minLength`: If message exceeds maxLength, try to break at newline between minLength and maxLength (default: 3000)
143
- `delegate`: Underlying logger to delegate broken-up messages to (default: `Logger.DEFAULT`)
144
145
**Methods:**
146
147
```kotlin { .api }
148
override fun log(message: String)
149
```
150
151
Logs the message, breaking it into chunks if it exceeds `maxLength`. Uses recursive tail-call optimization for processing long messages.
152
153
**Breaking Algorithm:**
154
1. If message ≤ maxLength: log directly
155
2. If message > maxLength:
156
- Take substring from 0 to maxLength
157
- Look for last newline between minLength and maxLength
158
- If newline found: break there, skip the newline character
159
- If no newline: break at maxLength
160
- Log the first part, recursively process remainder
161
162
**Usage Examples:**
163
164
```kotlin
165
// Default configuration
166
Logging {
167
logger = MessageLengthLimitingLogger()
168
}
169
170
// Custom length limits
171
Logging {
172
logger = MessageLengthLimitingLogger(
173
maxLength = 2000,
174
minLength = 1500
175
)
176
}
177
178
// Custom delegate logger
179
Logging {
180
logger = MessageLengthLimitingLogger(
181
maxLength = 3000,
182
delegate = Logger.SIMPLE
183
)
184
}
185
186
// Android-optimized with custom limits
187
Logging {
188
logger = MessageLengthLimitingLogger(
189
maxLength = 3500,
190
minLength = 2500,
191
delegate = Logger.ANDROID
192
)
193
}
194
```
195
196
## Custom Logger Implementation
197
198
You can create custom logger implementations by implementing the `Logger` interface:
199
200
```kotlin
201
class CustomFileLogger(private val filePath: String) : Logger {
202
override fun log(message: String) {
203
File(filePath).appendText("${Date()}: $message\n")
204
}
205
}
206
207
// Usage
208
Logging {
209
logger = CustomFileLogger("/path/to/logfile.txt")
210
}
211
```
212
213
## Platform-Specific Considerations
214
215
### JVM Platform
216
- **SLF4J Integration**: Default logger uses SLF4J, respects your logging configuration
217
- **Android Support**: Special Android logger handles Logcat integration and message limits
218
- **Thread Safety**: All built-in loggers are thread-safe
219
220
### JavaScript/WASM Platform
221
- **Console Output**: Uses browser console or Node.js console
222
- **Simple Implementation**: Falls back to basic println-style logging
223
224
### Native/Posix Platform
225
- **Standard Output**: Uses platform's standard output mechanisms
226
- **Simple Implementation**: Falls back to basic println-style logging
227
228
## Logger Selection Guide
229
230
| Use Case | Recommended Logger | Reason |
231
|----------|-------------------|---------|
232
| JVM Production | `Logger.DEFAULT` | SLF4J integration with your logging framework |
233
| Android Apps | `Logger.ANDROID` | Logcat integration + message length handling |
234
| Development/Testing | `Logger.SIMPLE` | Simple console output |
235
| Unit Tests | `Logger.EMPTY` | No output, faster tests |
236
| Long Messages | `MessageLengthLimitingLogger` | Handles message truncation gracefully |
237
| Custom Requirements | Custom implementation | Full control over output destination and format |