42

I'm trying to get logging working for each request from a Feign rest client.

However I cannot get the logging to work, while 'standard' Slf4j logging does work.

I have the following:

public MyClient() {
    initConnectionProperties();
    this.service = Feign.builder()
        .contract(new JAXRSContract())
        .decoder(getJacksonDecoder())
        .encoder(getJacksonEncoder())
        .requestInterceptor(new BasicAuthRequestInterceptor(user, password))
        .logger(new Slf4jLogger(MyClient.class)) //not working
        .logLevel(feign.Logger.Level.BASIC)
        .target(MyClient.class, this.url);
    logger.info("Connection parameters: url = " + url + ", user = " + user); // working
}
ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
Magick
  • 4,603
  • 22
  • 66
  • 103
  • Do you have any configuration file for the SLF4J that may be ignoring the logs for the MyClient class? – Sigrist Apr 20 '17 at 19:24
  • 1
    In my Spring Boot app Feign's logging is configured in application.yml as ```logging.level.com.mycompany.admintool.external.persons.resource.CustomerResource: DEBUG``` – Igor Bljahhin Jun 26 '17 at 08:48
  • I'm having the same problem here. did you find any solution? – Ali M Feb 02 '18 at 22:14

9 Answers9

35

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

Maverick
  • 1,519
  • 18
  • 32
20

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
Niraj Sonawane
  • 10,225
  • 10
  • 75
  • 104
  • You should remove Configuration annotation from UserClientConfig, because it works well without Configuration. But @Configuration can apply beans application-wide and break you application if for example you add jackson beans there. – roma2341 Dec 29 '22 at 10:50
14

First you need to set the logging level for your feign client class to DEBUG, as Maverick already mentioned in his answer.

Then if you use Spring Boot, beside the option to create @Configuration classes as Niraj already mentioned in his answer, you can configure each client individually in you application properties/yml config file:

feign:
  client:
    config:
      the_name_of_your_feign_client:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic

Or use default instead of the_name_of_your_feign_client to configure all your feign clients in the same way:

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic
aSemy
  • 5,485
  • 2
  • 25
  • 51
Roland
  • 758
  • 1
  • 7
  • 13
  • 1
    Following this answer, I managed to increase the logging level adding these lines to my application.properties: `feign.client.config..loggerLevel=full` and `logging.level..=DEBUG` – dbaltor Jul 13 '20 at 12:10
  • 1
    Important note, where the name is the value of `@FeignClient(name = "fiegn-client-name")` parameter – Artem Ptushkin Jun 03 '21 at 15:54
6

I hadn't set a client, and my client calls were failing, and logging wasn't working.. once I added OkHttpClient and changed logback.xml file, worked fine

    MyApi myApi = Feign.builder()
            .client(new OkHttpClient())
            .decoder(new JacksonDecoder())
            .encoder(new JacksonEncoder())
            .logger(new Slf4jLogger())
            .logLevel(feign.Logger.Level.FULL)
            .target(MyApi.class, "http://localhost:8082");

this is logback.xml

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d %green([%thread]) %highlight(%level) %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    <logger name="feign.Logger" level="DEBUG" />
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>
Tony Murphy
  • 711
  • 9
  • 22
5
private void setup() {
    //...
    feignBuilder.logger(new MyLogger());
    feignBuilder.logLevel(Logger.Level.FULL);
}

private static class MyLogger extends Logger {
    @Override
    protected void log(String s, String s1, Object... objects) {
        System.out.println(String.format(s + s1, objects)); // Change me!
    }
}
  • fyi: This worked for me. I am using logback, and not getting any output in my unit test. I had `feignBuilder.logLevel(Logger.Level.FULL)` but not a logger specified. Adding `feignBuilder.logger(new Slf4JLogger());` then I get output. – Alper Akture Oct 24 '19 at 02:35
  • Thank you! Finally an answer that doesn't lead me down Yet Another Rabbit Hole, and let me see what's going on without further searches. One of my complaints about modern software development is that we've added endless layer upon endless layer. Just configuring debugging leads you down several potential rabbit holes of "ok, where do I put THAT file" and "Ok, where do I find THAT library", and "Ok, which class am I supposed to import for THAT object where nobody specified the import". Or "Ok, where do I add THAT annotation". This example is simple, complete, and easy. – Steve Sether Jun 07 '21 at 18:41
4

You may also need to configure your log4j logging level for feign to DEBUG. If you are using spring boot, what worked for me is:

curl -X POST http://localhost/loggers/feign -H 'Content-Type: application/json' -d '{"configuredLevel": "DEBUG"}'
Stimp
  • 567
  • 1
  • 7
  • 11
2

Below code changes worked for me in kotlin:

import feign.Logger
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class FeignLoggingConfiguration {

    @Bean
    fun feignLoggerLevel(): Logger.Level {
        return Logger.Level.HEADERS
    }
}

add this configuration class in client:

@FeignClient(name = "yourClient", url = "\${base-url}", configuration = [FeignLoggingConfiguration::class])
interface yourClient 

Note: please make sure logging level for yourClient class is DEBUG

Loggin level supported by feign :

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

hitesh
  • 176
  • 1
  • 3
2

I'm kinda late from here but let me try to help fellow people finding this thread.

There are two things we have to distinguish. Feign logging when using plain Feign and when using it with Spring Cloud OpenFeign.

With plain Feign, you gotta do a few things do make things work:

  1. You have to set the log level for your client
  2. You have to configure the appropriate log adapter of your choice
  3. You have to set the feign logger to DEBUG

Let me show you how to do it:

Feign.builder()
     .logLevel(Logger.Level.FULL)
     .logger(new Slf4jLogger())
     .target(MyClient.class, "http://localhost:8081");

In this particular case, I'm using SLF4J as the logging adapter. This configuration took care of step 1 and 2. Now let's configure the logger. And don't forget, this may vary depending on your logging setup, I'll show you one with Spring Boot:

application.properties:

logging.level.feign=DEBUG

But this could be done with plain Logback in your logback.xml, log4j, whatever logging system you have. The only important thing is to configure the feign named logger to DEBUG.

This is due to the fact that the Feign library logs everything with the feign logger and not with the class name of the target clients.

With Spring Cloud OpenFeign, it changes a little bit because Spring uses the client's class name to set up the logger.

For this case, we only have to do 2 things - if you're using the @FeignClient annotation.

  1. Configure the log level for the clients
  2. Configure the appropriate client logger to DEBUG

The first can be done this way:

@Configuration
public class FeignConfiguration {
    @Bean
    public Logger.Level loggerLevel() {
        return Logger.Level.FULL;
    }
}

This will configure the log level for all the Feign clients unless you use a specific configuration in the @FeignClient annotation.

Second thing, enable DEBUG logging for the client's class/package.

application.properties:

logging.level.com.example.MyClient=DEBUG

If you're struggling with Feign configuration, you might wanna take a look at my articles or my course.

Cheers.

Arnold Galovics
  • 3,246
  • 3
  • 22
  • 33
0

U can put log level in bootstrap/application property it will give u all the debug logs for your spring boot application for example:- logging.leve.root=debug