Correlate data buffers to request log messages
HttpMessageWriter implementations now attach the request log prefix as a hint to created data buffers when the logger associated with the writer is at DEBUG level. Closes gh-26230
This commit is contained in:
@@ -57,6 +57,9 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
|
||||
|
||||
private static final Log logger = HttpLogging.forLogName(EncoderHttpMessageWriter.class);
|
||||
|
||||
|
||||
private final Encoder<T> encoder;
|
||||
|
||||
private final List<MediaType> mediaTypes;
|
||||
@@ -125,6 +128,7 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
|
||||
return message.setComplete().then(Mono.empty());
|
||||
}))
|
||||
.flatMap(buffer -> {
|
||||
Hints.touchDataBuffer(buffer, hints, logger);
|
||||
message.getHeaders().setContentLength(buffer.readableByteCount());
|
||||
return message.writeWith(Mono.just(buffer)
|
||||
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release));
|
||||
@@ -132,10 +136,15 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
|
||||
}
|
||||
|
||||
if (isStreamingMediaType(contentType)) {
|
||||
return message.writeAndFlushWith(body.map(buffer ->
|
||||
Mono.just(buffer).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release)));
|
||||
return message.writeAndFlushWith(body.map(buffer -> {
|
||||
Hints.touchDataBuffer(buffer, hints, logger);
|
||||
return Mono.just(buffer).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
|
||||
}));
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger));
|
||||
}
|
||||
return message.writeWith(body);
|
||||
}
|
||||
|
||||
@@ -166,6 +175,9 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
|
||||
return main;
|
||||
}
|
||||
|
||||
private static void touch(DataBuffer buffer, Map<String, Object> hints) {
|
||||
}
|
||||
|
||||
private boolean isStreamingMediaType(@Nullable MediaType mediaType) {
|
||||
if (mediaType == null || !(this.encoder instanceof HttpMessageEncoder)) {
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -132,6 +132,9 @@ public class ResourceHttpMessageWriter implements HttpMessageWriter<Resource> {
|
||||
Mono<Resource> input = Mono.just(resource);
|
||||
DataBufferFactory factory = message.bufferFactory();
|
||||
Flux<DataBuffer> body = this.encoder.encode(input, factory, type, resourceMediaType, hints);
|
||||
if (logger.isDebugEnabled()) {
|
||||
body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger));
|
||||
}
|
||||
return message.writeWith(body);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -35,6 +36,7 @@ import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferFactory;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.PooledDataBuffer;
|
||||
import org.springframework.http.HttpLogging;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ReactiveHttpOutputMessage;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
@@ -57,6 +59,8 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
|
||||
|
||||
private static final List<MediaType> WRITABLE_MEDIA_TYPES = Collections.singletonList(MediaType.TEXT_EVENT_STREAM);
|
||||
|
||||
private static final Log logger = HttpLogging.forLogName(ServerSentEventHttpMessageWriter.class);
|
||||
|
||||
|
||||
@Nullable
|
||||
private final Encoder<?> encoder;
|
||||
@@ -167,9 +171,11 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
|
||||
if (this.encoder == null) {
|
||||
throw new CodecException("No SSE encoder configured and the data is not String.");
|
||||
}
|
||||
DataBuffer buffer = ((Encoder<T>) this.encoder).encodeValue(data, factory, dataType, mediaType, hints);
|
||||
Hints.touchDataBuffer(buffer, hints, logger);
|
||||
return Flux.just(factory.join(Arrays.asList(
|
||||
encodeText(eventContent, mediaType, factory),
|
||||
((Encoder<T>) this.encoder).encodeValue(data, factory, dataType, mediaType, hints),
|
||||
buffer,
|
||||
encodeText("\n\n", mediaType, factory))));
|
||||
}
|
||||
|
||||
|
||||
@@ -199,6 +199,10 @@ public class MultipartHttpMessageWriter extends MultipartWriterSupport
|
||||
.concatWith(generateLastLine(boundary, bufferFactory))
|
||||
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger));
|
||||
}
|
||||
|
||||
return outputMessage.writeWith(body);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,10 @@ public class PartHttpMessageWriter extends MultipartWriterSupport implements Htt
|
||||
.concatWith(generateLastLine(boundary, outputMessage.bufferFactory()))
|
||||
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger));
|
||||
}
|
||||
|
||||
return outputMessage.writeWith(body);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user