diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultFeignLoggerFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultFeignLoggerFactory.java new file mode 100644 index 00000000..d7ca25d1 --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultFeignLoggerFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.netflix.feign; + +import feign.Logger; +import feign.slf4j.Slf4jLogger; + +/** + * @author Venil Noronha + */ +public class DefaultFeignLoggerFactory implements FeignLoggerFactory { + + private Logger logger; + + public DefaultFeignLoggerFactory(Logger logger) { + this.logger = logger; + } + + @Override + public Logger create(Class type) { + return this.logger != null ? this.logger : new Slf4jLogger(type); + } + +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java index e5fcffc7..bf21845f 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java @@ -39,7 +39,6 @@ import feign.Target.HardCodedTarget; import feign.codec.Decoder; import feign.codec.Encoder; import feign.codec.ErrorDecoder; -import feign.slf4j.Slf4jLogger; import lombok.Data; import lombok.EqualsAndHashCode; @@ -83,11 +82,8 @@ class FeignClientFactoryBean implements FactoryBean, InitializingBean, } protected Feign.Builder feign(FeignContext context) { - Logger logger = getOptional(context, Logger.class); - - if (logger == null) { - logger = new Slf4jLogger(this.type); - } + FeignLoggerFactory loggerFactory = get(context, FeignLoggerFactory.class); + Logger logger = loggerFactory.create(this.type); // @formatter:off Feign.Builder builder = get(context, Feign.Builder.class) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java index ee4cf568..606cbbb5 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java @@ -19,7 +19,6 @@ package org.springframework.cloud.netflix.feign; import java.util.ArrayList; import java.util.List; -import org.apache.http.client.HttpClient; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -39,16 +38,16 @@ import org.springframework.format.support.FormattingConversionService; import com.netflix.hystrix.HystrixCommand; -import feign.Client; import feign.Contract; import feign.Feign; +import feign.Logger; import feign.codec.Decoder; import feign.codec.Encoder; -import feign.httpclient.ApacheHttpClient; import feign.hystrix.HystrixFeign; /** * @author Dave Syer + * @author Venil Noronha */ @Configuration public class FeignClientsConfiguration { @@ -62,6 +61,9 @@ public class FeignClientsConfiguration { @Autowired(required = false) private List feignFormatterRegistrars = new ArrayList<>(); + @Autowired(required = false) + private Logger logger; + @Bean @ConditionalOnMissingBean public Decoder feignDecoder() { @@ -108,4 +110,10 @@ public class FeignClientsConfiguration { return Feign.builder(); } + @Bean + @ConditionalOnMissingBean(FeignLoggerFactory.class) + public FeignLoggerFactory feignLoggerFactory() { + return new DefaultFeignLoggerFactory(logger); + } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignLoggerFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignLoggerFactory.java new file mode 100644 index 00000000..9440fdf0 --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignLoggerFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.netflix.feign; + +import feign.Logger; + +/** + * Allows an application to use a custom Feign {@link Logger}. + * + * @author Venil Noronha + */ +public interface FeignLoggerFactory { + + /** + * Factory method to provide a {@link Logger} for a given {@link Class}. + * + * @param type the {@link Class} for which a {@link Logger} instance is to be created + * @return a {@link Logger} instance + */ + public Logger create(Class type); + +} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignLoggerFactoryTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignLoggerFactoryTests.java new file mode 100644 index 00000000..c773ab4d --- /dev/null +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignLoggerFactoryTests.java @@ -0,0 +1,126 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.netflix.feign; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import feign.Logger; +import feign.slf4j.Slf4jLogger; + +/** + * @author Venil Noronha + */ +public class FeignLoggerFactoryTests { + + @Test + public void testDefaultLogger() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration1.class); + FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class); + assertNotNull(loggerFactory); + Logger logger = loggerFactory.create(Object.class); + assertNotNull(logger); + assertTrue(logger instanceof Slf4jLogger); + context.close(); + } + + @Configuration + @Import(FeignClientsConfiguration.class) + protected static class SampleConfiguration1 { + + } + + @Test + public void testCustomLogger() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration2.class); + FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class); + assertNotNull(loggerFactory); + Logger logger = loggerFactory.create(Object.class); + assertNotNull(logger); + assertTrue(logger instanceof LoggerImpl1); + context.close(); + } + + @Configuration + @Import(FeignClientsConfiguration.class) + protected static class SampleConfiguration2 { + + @Bean + public Logger logger() { + return new LoggerImpl1(); + } + + } + + static class LoggerImpl1 extends Logger { + + @Override + protected void log(String arg0, String arg1, Object... arg2) { + // noop + } + + } + + @Test + public void testCustomLoggerFactory() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration3.class); + FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class); + assertNotNull(loggerFactory); + assertTrue(loggerFactory instanceof LoggerFactoryImpl); + Logger logger = loggerFactory.create(Object.class); + assertNotNull(logger); + assertTrue(logger instanceof LoggerImpl2); + context.close(); + } + + @Configuration + @Import(FeignClientsConfiguration.class) + protected static class SampleConfiguration3 { + + @Bean + public FeignLoggerFactory feignLoggerFactory() { + return new LoggerFactoryImpl(); + } + + } + + static class LoggerFactoryImpl implements FeignLoggerFactory { + + @Override + public Logger create(Class type) { + return new LoggerImpl2(); + } + + } + + static class LoggerImpl2 extends Logger { + + @Override + protected void log(String arg0, String arg1, Object... arg2) { + // noop + } + + } + +}