Skip to content

Commit 7c7f70c

Browse files
authored
Provide a way to exclude headers from logs (#1530)
* Provide a way to exclude headers from logs * Make header filters optional (nullable), update README * Mistyping: sing -> sign * New implementation with overriding of filter methods * Fix javadocs, update README * Update README, fix removed newline
1 parent 64f4d9e commit 7c7f70c

File tree

5 files changed

+51
-13
lines changed

5 files changed

+51
-13
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,8 @@ public class Example {
765765
766766
The SLF4JLogger (see above) may also be of interest.
767767
768+
To filter out sensitive information like authorization or tokens
769+
override methods `shouldLogRequestHeader` or `shouldLogResponseHeader`.
768770
769771
#### Request Interceptors
770772
When you need to change all requests, regardless of their target, you'll want to configure a `RequestInterceptor`.

core/src/main/java/feign/Logger.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2020 The Feign Authors
2+
* Copyright 2012-2021 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -27,8 +27,7 @@
2727
public abstract class Logger {
2828

2929
protected static String methodTag(String configKey) {
30-
return new StringBuilder().append('[').append(configKey.substring(0, configKey.indexOf('(')))
31-
.append("] ").toString();
30+
return '[' + configKey.substring(0, configKey.indexOf('(')) + "] ";
3231
}
3332

3433
/**
@@ -41,13 +40,35 @@ protected static String methodTag(String configKey) {
4140
*/
4241
protected abstract void log(String configKey, String format, Object... args);
4342

43+
/**
44+
* Override to filter out request headers.
45+
*
46+
* @param header header name
47+
* @return true to log a request header
48+
*/
49+
protected boolean shouldLogRequestHeader(String header) {
50+
return true;
51+
}
52+
53+
/**
54+
* Override to filter out response headers.
55+
*
56+
* @param header header name
57+
* @return true to log a response header
58+
*/
59+
protected boolean shouldLogResponseHeader(String header) {
60+
return true;
61+
}
62+
4463
protected void logRequest(String configKey, Level logLevel, Request request) {
4564
log(configKey, "---> %s %s HTTP/1.1", request.httpMethod().name(), request.url());
4665
if (logLevel.ordinal() >= Level.HEADERS.ordinal()) {
4766

4867
for (String field : request.headers().keySet()) {
49-
for (String value : valuesOrEmpty(request.headers(), field)) {
50-
log(configKey, "%s: %s", field, value);
68+
if (shouldLogRequestHeader(field)) {
69+
for (String value : valuesOrEmpty(request.headers(), field)) {
70+
log(configKey, "%s: %s", field, value);
71+
}
5172
}
5273
}
5374

@@ -84,8 +105,10 @@ protected Response logAndRebufferResponse(String configKey,
84105
if (logLevel.ordinal() >= Level.HEADERS.ordinal()) {
85106

86107
for (String field : response.headers().keySet()) {
87-
for (String value : valuesOrEmpty(response.headers(), field)) {
88-
log(configKey, "%s: %s", field, value);
108+
if (shouldLogResponseHeader(field)) {
109+
for (String value : valuesOrEmpty(response.headers(), field)) {
110+
log(configKey, "%s: %s", field, value);
111+
}
89112
}
90113
}
91114

core/src/test/java/feign/LoggerTest.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2020 The Feign Authors
2+
* Copyright 2012-2021 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -49,7 +49,7 @@ public class LoggerTest {
4949
interface SendsStuff {
5050

5151
@RequestLine("POST /")
52-
@Headers("Content-Type: application/json")
52+
@Headers({"Content-Type: application/json", "X-Token: qwerty"})
5353
@Body("%7B\"customer_name\": \"{customer_name}\", \"user_name\": \"{user_name}\", \"password\": \"{password}\"%7D")
5454
String login(
5555
@Param("customer_name") String customer,
@@ -99,7 +99,7 @@ public static Iterable<Object[]> data() {
9999

100100
@Test
101101
public void levelEmits() {
102-
server.enqueue(new MockResponse().setBody("foo"));
102+
server.enqueue(new MockResponse().setHeader("Y-Powered-By", "Mock").setBody("foo"));
103103

104104
SendsStuff api = Feign.builder()
105105
.logger(logger)
@@ -383,9 +383,22 @@ public Retryer clone() {
383383

384384
private static final class RecordingLogger extends Logger implements TestRule {
385385

386+
private static final String PREFIX_X = "x-";
387+
private static final String PREFIX_Y = "y-";
388+
386389
private final List<String> messages = new ArrayList<>();
387390
private final List<String> expectedMessages = new ArrayList<>();
388391

392+
@Override
393+
protected boolean shouldLogRequestHeader(String header) {
394+
return !header.toLowerCase().startsWith(PREFIX_X);
395+
}
396+
397+
@Override
398+
protected boolean shouldLogResponseHeader(String header) {
399+
return !header.toLowerCase().startsWith(PREFIX_Y);
400+
}
401+
389402
void expectMessages(List<String> expectedMessages) {
390403
this.expectedMessages.addAll(expectedMessages);
391404
}

core/src/test/java/feign/MultipleLoggerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2020 The Feign Authors
2+
* Copyright 2012-2021 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -41,7 +41,7 @@ public void testAppendSeveralFilesToOneJavaLogger() throws Exception {
4141
}
4242

4343
@Test
44-
public void testJavaLoggerInstantationWithLoggerName() throws Exception {
44+
public void testJavaLoggerInstantiationWithLoggerName() throws Exception {
4545
Logger.JavaLogger l1 = new Logger.JavaLogger("First client")
4646
.appendToFile(tmp.newFile("1.log").getAbsolutePath());
4747
Logger.JavaLogger l2 = new Logger.JavaLogger("Second client")

slf4j/src/main/java/feign/slf4j/Slf4jLogger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2020 The Feign Authors
2+
* Copyright 2012-2021 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at

0 commit comments

Comments
 (0)