All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
reactivefeign.client.log.DefaultReactiveLogger Maven / Gradle / Ivy
package reactivefeign.client.log;
import feign.MethodMetadata;
import feign.Target;
import org.reactivestreams.Publisher;
import org.slf4j.LoggerFactory;
import reactivefeign.client.ReactiveHttpRequest;
import reactivefeign.client.ReactiveHttpResponse;
import reactivefeign.utils.Pair;
import reactivefeign.utils.SerializedFormData;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Clock;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* Default slf4j implementation
*
* @author Sergii Karpenko
*/
public class DefaultReactiveLogger implements ReactiveLoggerListener{
private final org.slf4j.Logger logger;
private final Clock clock;
public DefaultReactiveLogger(Clock clock) {
this(clock, LoggerFactory.getLogger(DefaultReactiveLogger.class));
}
public DefaultReactiveLogger(Clock clock, org.slf4j.Logger logger) {
this.clock = clock;
this.logger = logger;
}
@Override
public LogContext requestStarted(ReactiveHttpRequest request, Target target, MethodMetadata methodMetadata) {
LogContext logContext = new LogContext(request, target, methodMetadata, clock);
if (logger.isDebugEnabled()) {
logger.debug("[{}]--->{} {} HTTP/1.1", logContext.feignMethodKey, request.method(),
request.uri());
}
if (logger.isTraceEnabled()) {
logRequestHeaders(request, logContext.feignMethodKey);
}
return logContext;
}
@Override
public boolean logRequestBody() {
return logger.isTraceEnabled();
}
private void logRequestHeaders(ReactiveHttpRequest request, String feignMethodTag) {
if (logger.isTraceEnabled()) {
logger.trace("[{}] REQUEST HEADERS\n{}", feignMethodTag,
msg(() -> request.headers().entrySet().stream()
.map(entry -> String.format("%s:%s", entry.getKey(),
entry.getValue()))
.collect(Collectors.joining("\n"))));
}
}
@Override
public void bodySent(Object body, LogContext logContext) {
if (logger.isTraceEnabled()) {
Publisher requestBody = logContext.request.body();
if (requestBody instanceof Mono) {
logger.trace("[{}] REQUEST BODY\n{}", logContext.feignMethodKey, body);
} else if (requestBody instanceof Flux) {
logger.trace("[{}] REQUEST BODY ELEMENT\n{}", logContext.feignMethodKey, body);
} else if(requestBody instanceof SerializedFormData){
logger.trace("[{}] REQUEST BODY FORM DATA\n{}", logContext.feignMethodKey, body);
}
else {
throw new IllegalArgumentException("Unsupported publisher type: " + requestBody.getClass());
}
}
}
@Override
public void responseReceived(ReactiveHttpResponse response, LogContext logContext) {
logContext.setResponse(response);
logResponseHeaders(response, logContext.feignMethodKey, logContext.timeSpent());
}
@Override
public void errorReceived(Throwable throwable, LogContext logContext) {
if (logger.isErrorEnabled()) {
logger.error("[{}]--->{} {} HTTP/1.1", logContext.feignMethodKey,
logContext.request.method(), logContext.request.uri(), throwable);
}
}
@Override
public boolean logResponseBody() {
return logger.isTraceEnabled();
}
private void logResponseHeaders(ReactiveHttpResponse> httpResponse, String feignMethodTag,
long elapsedTime) {
if (logger.isTraceEnabled()) {
logger.trace("[{}] RESPONSE HEADERS\n{}", feignMethodTag,
msg(() -> httpResponse.headers().entrySet().stream()
.flatMap(entry -> entry.getValue().stream()
.map(value -> new Pair<>(entry.getKey(), value)))
.map(pair -> String.format("%s:%s", pair.left, pair.right))
.collect(Collectors.joining("\n"))));
}
if (logger.isDebugEnabled()) {
logger.debug("[{}]<--- headers takes {} milliseconds", feignMethodTag,
elapsedTime);
}
}
@Override
public void bodyReceived(Object body, LogContext logContext) {
if (logger.isTraceEnabled()) {
if(logContext.getResponse().body() instanceof Mono) {
logger.trace("[{}] RESPONSE BODY\n{}", logContext.feignMethodKey, body);
} else {
logger.trace("[{}] RESPONSE BODY ELEMENT\n{}", logContext.feignMethodKey, body);
}
}
if (logger.isDebugEnabled()) {
logger.debug("[{}]<--- body takes {} milliseconds", logContext.feignMethodKey, logContext.timeSpent());
}
}
static class LogContext{
private final ReactiveHttpRequest request;
private final Target target;
private final MethodMetadata methodMetadata;
private final Clock clock;
private final long startTime;
private final String feignMethodKey;
private ReactiveHttpResponse response;
public LogContext(ReactiveHttpRequest request, Target target, MethodMetadata methodMetadata, Clock clock) {
this.request = request;
this.target = target;
this.methodMetadata = methodMetadata;
this.clock = clock;
this.startTime = clock.millis();
this.feignMethodKey = methodMetadata.configKey();
}
public long timeSpent(){
return clock.millis() - startTime;
}
public ReactiveHttpResponse getResponse() {
return response;
}
public void setResponse(ReactiveHttpResponse response) {
this.response = response;
}
}
private static MessageSupplier msg(Supplier> supplier) {
return new MessageSupplier(supplier);
}
static class MessageSupplier {
private Supplier> supplier;
public MessageSupplier(Supplier> supplier) {
this.supplier = supplier;
}
@Override
public String toString() {
return supplier.get().toString();
}
}
}