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;
    }
}

Answer from Prasanth Rajendran on Stack Overflow
Top answer
1 of 6
83

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;
    }
}

2 of 6
13

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
🌐
Spring Cloud
cloud.spring.io › spring-cloud-openfeign › 2.2.x › reference › html
Spring Cloud OpenFeign
BASIC, Log only the request method and URL and the response status code and execution time.
🌐
Medium
bvn13.medium.com › normalized-logger-for-openfeign-8727b4e5d776
Normalized Logger for OpenFeign. Standard Feign logger provides the only… | by Vyacheslav Boyko | Medium
August 12, 2022 - The whole communication (request and response parts) is combined into one log entry. 2022-07-25 14:16:06.217 INFO 1057053 --- [Executor] me.bvn13.openfeign.logger.NormalizedFeignLogger : normalized feign request {AuthApi#login(LoginRequestD...
🌐
GitHub
github.com › OpenFeign › feign › issues › 1035
Log request (and response) in single batch · Issue #1035 · OpenFeign/feign
August 8, 2019 - Feign's Logger is logging once per request / response line item. For example, JavaLogger will log the following request / response pair by invoking java.util.logging.Logger 7 times: [SendsStuff#log...
Author: OpenFeign
🌐
GitHub
github.com › OpenFeign › feign › blob › master › core › src › main › java › feign › Logger.java
feign/core/src/main/java/feign/Logger.java at master · OpenFeign/feign
/** Log only the request method and URL and the response status code and execution time. */ BASIC, /** Log the basic information along with request and response headers. */ HEADERS, /** Log the headers, body, and metadata for both requests and responses.
🌐
Baeldung
baeldung.com › home › spring › spring boot › feign logging configuration
Feign Logging Configuration | Baeldung
February 26, 2025 - In the first part of the log, we can see the request logged; The URL endpoint with his HTTP GET method. In this case, as it is a GET request, we don’t have a request body. The second part contains the response. It shows the headers and the body of the response.
🌐
Poznachowski
blog.poznachowski.pl › posts › feign-slf4j-logger
Feign Slf4j Logger you wish you had // It's SOAP's Fault...
August 17, 2021 - spring-cloudspring-cloud-openfeignfeignslf4jlogger · When it comes to Feign and logging its requests and responses, it provides Logger - an abstraction layer with dedicated set of log Levels: Most popular Feign Logger implementation is the SLF4j that outputs Feign information to DEBUG level ...
🌐
GitHub
github.com › bvn13 › OpenFeign-NormalizedLogger
GitHub - bvn13/OpenFeign-NormalizedLogger: Normalized Logger for OpenFeign · GitHub
The whole communication (request and response parts) is combined into one log entry. 2022-07-25 14:16:06.217 INFO 1057053 --- [Executor] me.bvn13.openfeign.logger.NormalizedFeignLogger : normalized feign request {AuthApi#login(LoginRequestD...
Author: bvn13
Find elsewhere
🌐
GitHub
github.com › OpenFeign › feign › issues › 1215
Allow masking of request and response data when logging · Issue #1215 · OpenFeign/feign
April 24, 2020 - The logging of request/response headers and bodies is a very useful feature. However, sometimes those log events contain sensitive data. It would be nice to have a mechanism for masking the values ...
Author: OpenFeign
🌐
GitHub
github.com › OpenFeign › feign › issues › 874
Log details as one message · Issue #874 · OpenFeign/feign
January 11, 2019 - tl;dr: Call log() only once for each request and response? I'm using feign.client.config.default.loggerLevel: full to log payload of an application deployed to Cloud Foundry in a dev/test environment. In Cloud Foundry, every line of log ...
Author: OpenFeign
🌐
Javadoc.io
javadoc.io › static › io.github.openfeign › feign-core › 10.7.0 › feign › Logger.html
Logger (Feign Core 10.7.0 API)
Messages will be http request and response text. ... protected Response logAndRebufferResponse(String configKey, Logger.Level logLevel, Response response, long elapsedTime) throws IOException ... protected IOException logIOException(String configKey, Logger.Level logLevel, IOException ioe, long elapsedTime) ... Copyright © 2012–2019 OpenFeign...
🌐
Apps Developer Blog
appsdeveloperblog.com › home › spring framework › spring cloud › feign client logging
Feign Client Logging - Apps Developer Blog
November 9, 2022 - BASIC, Log only the request method and URL and the response status code and execution time.
🌐
Medium
medium.com › @somarouthu.sivaprasads › spring-cloud-feign-858c225e2341
Spring Cloud Feign. Logging: | by SivaprasadS | Medium
March 15, 2019 - logging.level.com.ssp.microservices.springcloudfeign.feignClients.DummyRestApiClient = DEBUG · Custom Request and Response Logging: class CustomFeignLogger extends Slf4jLogger { @Override protected void logRequest(String configKey, Level logLevel, Request request) { FeignRequest feignRequest = new FeignRequest(); feignRequest.setMethod(request.method()); feignRequest.setUrl(request.url()); if (logLevel.ordinal() >= Level.HEADERS.ordinal()) { for (String field : request.headers().keySet()) { for (String value : valuesOrEmpty(request.headers(), field)) { feignRequest.addHeader(field, value); } } if (request.body() != null && logLevel.ordinal() >= Level.FULL.ordinal()) { feignRequest.setBody(request.charset() != null ?
🌐
Baeldung
baeldung.com › home › spring › spring cloud › introduction to spring cloud openfeign
Introduction to Spring Cloud OpenFeign | Baeldung
February 19, 2026 - If we have both Configuration bean and configuration properties, configuration properties will override Configuration bean values. Adding interceptors is another useful feature provided by Feign. The interceptors can perform a variety of implicit tasks, from authentication to logging, for every HTTP request/response. In this section, we’ll implement our own interceptor, as well as use the one provided by the Spring Cloud OpenFeign out-of-the-box.
🌐
Medium
medium.com › @reetesh043 › handling-logging-in-spring-boot-feignclient-a-complete-guide-0831676b8526
Handling Logging in Spring Boot FeignClient: A Complete Guide | by Reetesh Kumar | Medium
August 5, 2025 - This post shows you how to enable and customize FeignClient logging in Spring Boot, with working code snippets and configuration examples. Feign abstracts away HTTP calls. That’s great for cleaner code. But it also means you don’t see raw HTTP requests or responses unless you explicitly log them.
🌐
Tabnine
tabnine.com › home › code library
Code Library - Tabnine
July 25, 2024 - The Tabnine Code Library is no longer available — but you can still get the answers and suggestions you need from our AI code assistant.
🌐
GitHub
github.com › OpenFeign › feign › issues › 598
How to log the server name which the request was sent to? · Issue #598 · OpenFeign/feign
November 3, 2017 - Disclaimer: I posted this question on StackOverflow 3 weeks ago, but have not yet had a response, so I am trying here .... I am using a Feign Client to call a REST endpoint with success, and have logging turned on to FULL. This is helpfully shows me the request sent and the response received.
Author: OpenFeign