You need to configure logging in application.properties as below:
logging.level.<package path>.MyClient=DEBUG
If you're using application.yml then:
logging.level.<package path>.MyClient: DEBUG
The log level can be set to tell Feign how much to log.
Options are:
- NONE, No logging (DEFAULT)
- BASIC, Log only the request method and URL and the response status code and execution time
- HEADERS, Log the basic information along with request and response headers
- FULL, Log the headers, body, and metadata for both requests and responses
Example:
logLevel(feign.Logger.Level.NONE)
or
logLevel(feign.Logger.Level.BASIC)
or
logLevel(feign.Logger.Level.HEADERS)
or
logLevel(feign.Logger.Level.FULL)
For more details, you can refer this
Answer from Maverick on Stack OverflowYou need to configure logging in application.properties as below:
logging.level.<package path>.MyClient=DEBUG
If you're using application.yml then:
logging.level.<package path>.MyClient: DEBUG
The log level can be set to tell Feign how much to log.
Options are:
- NONE, No logging (DEFAULT)
- BASIC, Log only the request method and URL and the response status code and execution time
- HEADERS, Log the basic information along with request and response headers
- FULL, Log the headers, body, and metadata for both requests and responses
Example:
logLevel(feign.Logger.Level.NONE)
or
logLevel(feign.Logger.Level.BASIC)
or
logLevel(feign.Logger.Level.HEADERS)
or
logLevel(feign.Logger.Level.FULL)
For more details, you can refer this
This is how i was able to log using Custom Config class
Note Feign logging only responds to the DEBUG level.
Config Class
@Configuration
public class UserClientConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.HEADERS;
}
}
Client
@FeignClient(name = "User", url = "http://localhost:8080",configuration=UserClientConfig.class)
public interface UserClient {
@RequestMapping(method = RequestMethod.GET, value = "/user")
List<User> getAllUsers();
}
application.properties
logging.level.<pcakgepath>.UserClient: DEBUG
Feign has out of box logging mechanism and it can be achieved through simple steps.
If you are using spring-cloud-starter-feign
Feign using Slf4jLogger for logging.Feign logging documentation
As per doc, the below logging levels are available to configure,
NONE- No logging (DEFAULT).BASIC- Log only the request method and URL and the response status code and execution time.HEADERS- Log the basic information along with request and response headers.FULL- Log the headers, body, and metadata for both requests and responses.
Injecting the Logger.Level bean is enough.
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.BASIC;
}
OR
If you prefer using configuration properties to configured all @FeignClient, you can create configuration properties with default feign name.
feign:
client:
config:
default:
loggerLevel: basic
of if you are using a newer version (Spring Boot 3) the config will be like:
spring:
cloud:
openfeign:
client:
config:
default:
loggerLevel: full
If you are using 'io.github.openfeign:feign-core'
If you are constructing the Feign builder then you can mention logLevel(Level.BASIC) as
Feign.builder()
.logger(new Slf4jLogger())
.logLevel(Level.BASIC)
.target(SomeFeignClient.class, url);
We have the flexibility to customize the logging message
The default feign request and response logging
Request logging
Resopnse logging
we can customize the feign request, response logging pattern by overriding Logger#logRequest and Logger#logAndRebufferResponse methods. In the following example, we have customized request logging pattern
log(configKey, "---> %s %s HTTP/1.1 (%s-byte body) ", request.httpMethod().name(), request.url(), bodyLength);
and response logging pattern
log(configKey, "<--- %s %s HTTP/1.1 %s (%sms) ", request.httpMethod().name(), request.url(), status, elapsedTime);
The Full example is
import feign.Logger;
import feign.Request;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import static feign.Logger.Level.HEADERS;
@Slf4j
public class CustomFeignRequestLogging extends Logger {
@Override
protected void logRequest(String configKey, Level logLevel, Request request) {
if (logLevel.ordinal() >= HEADERS.ordinal()) {
super.logRequest(configKey, logLevel, request);
} else {
int bodyLength = 0;
if (request.requestBody().asBytes() != null) {
bodyLength = request.requestBody().asBytes().length;
}
log(configKey, "---> %s %s HTTP/1.1 (%s-byte body) ", request.httpMethod().name(), request.url(), bodyLength);
}
}
@Override
protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime)
throws IOException {
if (logLevel.ordinal() >= HEADERS.ordinal()) {
return super.logAndRebufferResponse(configKey, logLevel, response, elapsedTime);
} else {
int status = response.status();
Request request = response.request();
log(configKey, "<--- %s %s HTTP/1.1 %s (%sms) ", request.httpMethod().name(), request.url(), status, elapsedTime);
return response;
}
}
@Override
protected void log(String configKey, String format, Object... args) {
log.debug(format(configKey, format, args));
}
protected String format(String configKey, String format, Object... args) {
return String.format(methodTag(configKey) + format, args);
}
}
NOTE: Request payload can be easily logged through
String bodyText =
request.charset() != null ? new String(request.body(), request.charset()) : null;
but be careful writing the response payload after you are reading the input stream Util.toByteArray(response.body().asInputStream()) then you have to construct the response again like response.toBuilder().body(bodyData).build(). Otherwise, you will end up with the expection. The reason is response streams are read and always closed before returning, thats why the method is named as logAndRebufferResponse
How to use the custom CustomFeignRequestLogging?
If you are building feign client using just 'io.github.openfeign:feign-core'
Feign.builder()
.logger(new CustomFeignRequestLogging())
.logLevel(feign.Logger.Level.BASIC);
If you are using 'org.springframework.cloud:spring-cloud-starter-openfeign'
@Configuration
public class FeignLoggingConfiguration {
@Bean
public CustomFeignRequestLogging customFeignRequestLogging() {
return new CustomFeignRequestLogging();
}
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.BASIC;
}
}
The accepted answer did not work for me until I added the following settings to my application.yml file:
logging:
level:
com:
mypackage1:
mysubackage1:
mysubpackage2: DEBUG