diff --git a/README.md b/README.md
index 8ecf44c..a28782e 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.3.3
+ 2.3.4
```
@@ -59,7 +59,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.3.3
+ 2.3.4
com.squareup.okhttp3
@@ -432,6 +432,17 @@ retrofit:
如果需要修改日志打印行为,继承`LoggingInterceptor`,并将其配置成Spring bean即可!
+#### 聚合日志打印
+
+如果需要将同一个请求的日志聚合在一起打印,可配置`AggregateLoggingInterceptor`。
+
+```java
+ @Bean
+public LoggingInterceptor loggingInterceptor(RetrofitProperties retrofitProperties){
+ return new AggregateLoggingInterceptor(retrofitProperties.getGlobalLog());
+ }
+```
+
### 请求重试
组件支持支持全局重试和声明式重试。
diff --git a/pom.xml b/pom.xml
index 0307e88..5163ebc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.3.3
+ 2.3.4
retrofit-spring-boot-starter
retrofit-spring-boot-starter
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/AggregateLoggingInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/AggregateLoggingInterceptor.java
new file mode 100644
index 0000000..8834c9a
--- /dev/null
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/AggregateLoggingInterceptor.java
@@ -0,0 +1,55 @@
+package com.github.lianjiatech.retrofit.spring.boot.log;
+
+import java.io.IOException;
+
+import okhttp3.Response;
+import okhttp3.logging.HttpLoggingInterceptor;
+
+/**
+ * 同一个请求的日志聚合在一起打印。 The logs of the same request are aggregated and printed together.
+ * @author 陈添明
+ * @since 2022/5/31 10:49 上午
+ */
+public class AggregateLoggingInterceptor extends LoggingInterceptor {
+
+ public AggregateLoggingInterceptor(GlobalLogProperty globalLogProperty) {
+ super(globalLogProperty);
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Logging logging = findLogging(chain);
+ if (!needLog(logging)) {
+ return chain.proceed(chain.request());
+ }
+ LogLevel logLevel = logging == null ? globalLogProperty.getLogLevel() : logging.logLevel();
+ LogStrategy logStrategy = logging == null ? globalLogProperty.getLogStrategy() : logging.logStrategy();
+ BufferingLogger bufferingLogger = new BufferingLogger(matchLogger(logLevel));
+ HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(bufferingLogger)
+ .setLevel(HttpLoggingInterceptor.Level.valueOf(logStrategy.name()));
+ Response response = httpLoggingInterceptor.intercept(chain);
+ bufferingLogger.flush();
+ return response;
+ }
+
+ private static class BufferingLogger implements HttpLoggingInterceptor.Logger {
+
+ private StringBuilder buffer = new StringBuilder(System.lineSeparator());
+
+ private final HttpLoggingInterceptor.Logger delegate;
+
+ public BufferingLogger(HttpLoggingInterceptor.Logger delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void log(String message) {
+ buffer.append(message).append(System.lineSeparator());
+ }
+
+ public void flush() {
+ delegate.log(buffer.toString());
+ buffer = new StringBuilder(System.lineSeparator());
+ }
+ }
+}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java
index 4f7a621..52b1f66 100644
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java
@@ -8,7 +8,6 @@
import lombok.extern.slf4j.Slf4j;
import okhttp3.Interceptor;
-import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Invocation;
@@ -28,19 +27,22 @@ public LoggingInterceptor(GlobalLogProperty globalLogProperty) {
@Override
public Response intercept(Chain chain) throws IOException {
- Request request = chain.request();
- Method method = Objects.requireNonNull(request.tag(Invocation.class)).method();
- Logging logging = AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), Logging.class);
+ Logging logging = findLogging(chain);
if (!needLog(logging)) {
- return chain.proceed(request);
+ return chain.proceed(chain.request());
}
LogLevel logLevel = logging == null ? globalLogProperty.getLogLevel() : logging.logLevel();
LogStrategy logStrategy = logging == null ? globalLogProperty.getLogStrategy() : logging.logStrategy();
- HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(matchLogger(logLevel));
- httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.valueOf(logStrategy.name()));
+ HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(matchLogger(logLevel))
+ .setLevel(HttpLoggingInterceptor.Level.valueOf(logStrategy.name()));
return httpLoggingInterceptor.intercept(chain);
}
+ protected Logging findLogging(Chain chain) {
+ Method method = Objects.requireNonNull(chain.request().tag(Invocation.class)).method();
+ return AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), Logging.class);
+ }
+
protected boolean needLog(Logging logging) {
if (globalLogProperty.isEnable()) {
if (logging == null) {
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitStarterTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitStarterTest.java
index fc465d4..0c971fc 100644
--- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitStarterTest.java
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitStarterTest.java
@@ -8,6 +8,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
+import java.util.stream.IntStream;
import org.junit.After;
import org.junit.Assert;
@@ -19,6 +20,7 @@
import org.springframework.test.context.junit4.SpringRunner;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person;
@@ -107,6 +109,40 @@ public void testGetPersonBody() throws Exception {
System.out.println(personBody);
}
+ @Test
+ public void testAggregateLoggingInterceptor() {
+ IntStream.range(1, 1000)
+ .parallel()
+ .forEach(i -> {
+ // mock
+ Person mockPerson = new Person().setId(1L)
+ .setName("test")
+ .setAge(10);
+ Result mockResult = new Result<>()
+ .setCode(0)
+ .setMsg("ok")
+ .setData(mockPerson);
+ MockResponse response = null;
+ try {
+ response = new MockResponse()
+ .setResponseCode(200)
+ .addHeader("Content-Type", "application/json; charset=utf-8")
+ .addHeader("Cache-Control", "no-cache")
+ .setBody(objectMapper.writeValueAsString(mockResult));
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ server.enqueue(response);
+
+ Person person = new Person();
+ person.setId(100L)
+ .setAge(10)
+ .setName("xx");
+ Result personBody = httpApi2.getPersonBody(person);
+ System.out.println(personBody);
+ });
+ }
+
@Test
public void testRetrofitConfigRef() throws IOException {
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java
index de7c7d0..43270fd 100644
--- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java
@@ -3,6 +3,10 @@
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;
+import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitProperties;
+import com.github.lianjiatech.retrofit.spring.boot.log.AggregateLoggingInterceptor;
+import com.github.lianjiatech.retrofit.spring.boot.log.LoggingInterceptor;
+
import lombok.extern.slf4j.Slf4j;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.jaxb.JaxbConverterFactory;
@@ -32,4 +36,10 @@ public JaxbConverterFactory jaxbConverterFactory() {
public InvalidRespErrorDecoder invalidRespErrorDecoder() {
return new InvalidRespErrorDecoder();
}
+
+ @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
+ @Bean
+ public LoggingInterceptor loggingInterceptor(RetrofitProperties retrofitProperties) {
+ return new AggregateLoggingInterceptor(retrofitProperties.getGlobalLog());
+ }
}