or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-config.mdconfiguration.mdindex.mdlevels-formats.mdloggers.mdplatform-features.md

advanced-config.mddocs/

0

# Advanced Configuration Features

1

2

The Ktor Client Logging plugin provides advanced security and filtering capabilities for fine-tuned control over logging behavior.

3

4

## Required Imports

5

6

```kotlin

7

import io.ktor.client.*

8

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

9

import io.ktor.client.request.*

10

import io.ktor.http.*

11

```

12

13

## Request Filtering

14

15

Filter which HTTP requests get logged based on custom criteria.

16

17

```kotlin { .api }

18

fun LoggingConfig.filter(predicate: (HttpRequestBuilder) -> Boolean)

19

```

20

21

**Parameters:**

22

- `predicate`: Function that receives an `HttpRequestBuilder` and returns `true` if the request should be logged

23

24

Multiple filters can be added and they work with OR logic - if any filter returns `true`, the request will be logged.

25

26

### Common Filtering Patterns

27

28

#### Host-Based Filtering

29

```kotlin

30

Logging {

31

// Only log requests to specific hosts

32

filter { request ->

33

request.url.host in listOf("api.production.com", "auth.production.com")

34

}

35

36

// Exclude localhost requests

37

filter { request ->

38

!request.url.host.contains("localhost")

39

}

40

}

41

```

42

43

#### Method-Based Filtering

44

```kotlin

45

Logging {

46

// Only log non-GET requests

47

filter { request ->

48

request.method != HttpMethod.Get

49

}

50

51

// Only log specific methods

52

filter { request ->

53

request.method in listOf(HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete)

54

}

55

}

56

```

57

58

#### Path-Based Filtering

59

```kotlin

60

Logging {

61

// Only log API endpoints

62

filter { request ->

63

request.url.pathSegments.any { it == "api" }

64

}

65

66

// Exclude health check endpoints

67

filter { request ->

68

!request.url.encodedPath.contains("/health")

69

}

70

71

// Log only specific resource types

72

filter { request ->

73

request.url.pathSegments.any { segment ->

74

segment in listOf("users", "orders", "products")

75

}

76

}

77

}

78

```

79

80

#### Header-Based Filtering

81

```kotlin

82

Logging {

83

// Only log requests with specific headers

84

filter { request ->

85

request.headers.contains("X-Debug-Mode")

86

}

87

88

// Only log authenticated requests

89

filter { request ->

90

request.headers.contains(HttpHeaders.Authorization)

91

}

92

}

93

```

94

95

#### Complex Filtering Logic

96

```kotlin

97

Logging {

98

// Multiple conditions

99

filter { request ->

100

request.url.host == "api.production.com" &&

101

request.method == HttpMethod.Post &&

102

request.url.pathSegments.contains("sensitive-operation")

103

}

104

105

// Environment-based filtering

106

filter { request ->

107

System.getProperty("logging.level") == "debug" ||

108

request.headers["X-Debug-Session"] != null

109

}

110

}

111

```

112

113

### Multiple Filters

114

```kotlin

115

Logging {

116

// All these filters work with OR logic

117

filter { it.url.host == "api.example.com" } // Log api.example.com

118

filter { it.method == HttpMethod.Post } // OR log all POST requests

119

filter { it.headers.contains("X-Debug") } // OR log requests with debug header

120

}

121

```

122

123

## Header Sanitization

124

125

Prevent sensitive header values from appearing in logs by replacing them with placeholder text.

126

127

```kotlin { .api }

128

fun LoggingConfig.sanitizeHeader(

129

placeholder: String = "***",

130

predicate: (String) -> Boolean

131

)

132

```

133

134

**Parameters:**

135

- `placeholder`: String to replace sensitive header values (default: "***")

136

- `predicate`: Function that receives a header name and returns `true` if it should be sanitized

137

138

Multiple sanitization rules can be added with different placeholders for different header types.

139

140

### Common Sanitization Patterns

141

142

#### Authentication Headers

143

```kotlin

144

Logging {

145

// Standard authentication headers

146

sanitizeHeader { headerName ->

147

headerName.equals(HttpHeaders.Authorization, ignoreCase = true)

148

}

149

150

// API key headers

151

sanitizeHeader("████") { headerName ->

152

headerName.lowercase().contains("api-key") ||

153

headerName.lowercase().contains("x-api")

154

}

155

}

156

```

157

158

#### Custom Security Headers

159

```kotlin

160

Logging {

161

// Custom security tokens

162

sanitizeHeader("[REDACTED]") { headerName ->

163

headerName.startsWith("X-Secret-") ||

164

headerName.endsWith("-Token") ||

165

headerName.contains("Password", ignoreCase = true)

166

}

167

168

// Session identifiers

169

sanitizeHeader("████████") { headerName ->

170

headerName.lowercase() in listOf("cookie", "set-cookie", "x-session-id")

171

}

172

}

173

```

174

175

#### Pattern-Based Sanitization

176

```kotlin

177

Logging {

178

// Headers starting with specific prefixes

179

sanitizeHeader { headerName ->

180

val sensitive = listOf("X-Private-", "X-Internal-", "X-Auth-")

181

sensitive.any { prefix -> headerName.startsWith(prefix, ignoreCase = true) }

182

}

183

184

// Headers containing sensitive keywords

185

sanitizeHeader("[HIDDEN]") { headerName ->

186

val keywords = listOf("secret", "private", "token", "key", "password", "credential")

187

keywords.any { keyword -> headerName.contains(keyword, ignoreCase = true) }

188

}

189

}

190

```

191

192

#### Different Placeholders for Different Types

193

```kotlin

194

Logging {

195

// Different visual indicators for different security levels

196

sanitizeHeader("🔐") { it.equals("Authorization", ignoreCase = true) }

197

sanitizeHeader("🗝️") { it.contains("api-key", ignoreCase = true) }

198

sanitizeHeader("🚫") { it.contains("private", ignoreCase = true) }

199

sanitizeHeader("[CLASSIFIED]") { it.startsWith("X-Secret-") }

200

}

201

```

202

203

### Sanitization Output Examples

204

205

**Before sanitization:**

206

```

207

-> Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

208

-> X-API-Key: sk_live_51HqJKaBC123...

209

-> X-Secret-Token: supersecretvalue123

210

```

211

212

**After sanitization:**

213

```

214

-> Authorization: ***

215

-> X-API-Key: ████

216

-> X-Secret-Token: [REDACTED]

217

```

218

219

## Combined Advanced Configuration

220

221

```kotlin

222

val client = HttpClient {

223

install(Logging) {

224

// Basic configuration

225

level = LogLevel.HEADERS

226

format = LoggingFormat.OkHttp

227

logger = Logger.DEFAULT

228

229

/* Request Filtering */

230

231

// Only log production API calls

232

filter { request ->

233

request.url.host == "api.production.com"

234

}

235

236

// Or log debug requests from any host

237

filter { request ->

238

request.headers.contains("X-Debug-Mode")

239

}

240

241

// Or log error-prone operations

242

filter { request ->

243

request.method in listOf(HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete) &&

244

request.url.pathSegments.any { it in listOf("users", "payments", "orders") }

245

}

246

247

/* Header Sanitization */

248

249

// Standard auth headers

250

sanitizeHeader { it.equals("Authorization", ignoreCase = true) }

251

252

// API keys with different placeholder

253

sanitizeHeader("████") { headerName ->

254

listOf("x-api-key", "api-key", "x-auth-token").any {

255

headerName.equals(it, ignoreCase = true)

256

}

257

}

258

259

// Custom security headers

260

sanitizeHeader("[CLASSIFIED]") { headerName ->

261

headerName.startsWith("X-Secret-", ignoreCase = true) ||

262

headerName.startsWith("X-Private-", ignoreCase = true) ||

263

headerName.contains("password", ignoreCase = true)

264

}

265

266

// Session and cookie data

267

sanitizeHeader("🍪") { headerName ->

268

headerName.lowercase() in listOf("cookie", "set-cookie", "x-session-id")

269

}

270

}

271

}

272

```

273

274

## Security Best Practices

275

276

### Header Sanitization Guidelines

277

278

1. **Always sanitize authentication headers**: Authorization, API keys, tokens

279

2. **Use descriptive placeholders**: Different placeholders help identify header types

280

3. **Be comprehensive**: Consider all variations (X-API-Key, Api-Key, API_KEY, etc.)

281

4. **Review regularly**: Update sanitization rules as your API evolves

282

283

### Filtering Guidelines

284

285

1. **Filter in production**: Avoid logging all requests in production environments

286

2. **Use specific filters**: Target specific endpoints or operations rather than broad filtering

287

3. **Consider performance**: Complex filter predicates run for every request

288

4. **Test thoroughly**: Ensure important requests aren't accidentally filtered out

289

290

### Example Security-First Configuration

291

292

```kotlin

293

Logging {

294

// Conservative logging level for production

295

level = LogLevel.INFO

296

format = LoggingFormat.OkHttp

297

298

// Only log errors and important operations

299

filter { request ->

300

// Log authentication attempts

301

request.url.pathSegments.contains("auth") ||

302

// Log payment operations

303

request.url.pathSegments.contains("payments") ||

304

// Log admin operations

305

request.headers.contains("X-Admin-Request")

306

}

307

308

// Comprehensive header sanitization

309

sanitizeHeader { headerName ->

310

val sensitivePatterns = listOf(

311

"auth", "token", "key", "secret", "password",

312

"credential", "private", "session", "cookie"

313

)

314

sensitivePatterns.any { pattern ->

315

headerName.contains(pattern, ignoreCase = true)

316

}

317

}

318

}

319

```