Skip to content

Commit

Permalink
add option to customise log formats
Browse files Browse the repository at this point in the history
  • Loading branch information
jenschude committed Jan 12, 2024
1 parent f79f7fd commit b06a407
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,15 @@ public ApiRootBuilder withInternalLoggerFactory(final InternalLoggerFactory inte
deprecationLogEvent, defaultExceptionLogEvent, exceptionLogEvents));
}

public ApiRootBuilder withInternalLoggerFactory(final InternalLoggerFactory internalLoggerFactory,
final Level responseLogEvent, final Level deprecationLogEvent, final Level defaultExceptionLogEvent,
final Map<Class<? extends Throwable>, Level> exceptionLogEvents,
final ResponseLogFormatter responseLogFormatter, final ErrorLogFormatter errorLogFormatter) {
return with(clientBuilder -> clientBuilder.withInternalLoggerFactory(internalLoggerFactory, responseLogEvent,

Check warning on line 662 in commercetools/commercetools-sdk-java-api/src/main/java/com/commercetools/api/defaultconfig/ApiRootBuilder.java

View check run for this annotation

Codecov / codecov/patch

commercetools/commercetools-sdk-java-api/src/main/java/com/commercetools/api/defaultconfig/ApiRootBuilder.java#L662

Added line #L662 was not covered by tests
deprecationLogEvent, defaultExceptionLogEvent, exceptionLogEvents, responseLogFormatter,
errorLogFormatter));
}

public ApiRootBuilder withApiBaseUrl(String apiBaseUrl) {
return with(clientBuilder -> clientBuilder.withApiBaseUrl(apiBaseUrl));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,15 @@ public HistoryApiRootBuilder withInternalLoggerFactory(final InternalLoggerFacto
return this;
}

public HistoryApiRootBuilder withInternalLoggerFactory(final InternalLoggerFactory internalLoggerFactory,
final Level responseLogEvent, final Level deprecationLogEvent, final Level defaultExceptionLogEvent,
final Map<Class<? extends Throwable>, Level> exceptionLogEvents,
final ResponseLogFormatter responseLogFormatter, final ErrorLogFormatter errorLogFormatter) {
return with(clientBuilder -> clientBuilder.withInternalLoggerFactory(internalLoggerFactory, responseLogEvent,

Check warning on line 396 in commercetools/commercetools-sdk-java-history/src/main/java/com/commercetools/history/defaultconfig/HistoryApiRootBuilder.java

View check run for this annotation

Codecov / codecov/patch

commercetools/commercetools-sdk-java-history/src/main/java/com/commercetools/history/defaultconfig/HistoryApiRootBuilder.java#L396

Added line #L396 was not covered by tests
deprecationLogEvent, defaultExceptionLogEvent, exceptionLogEvents, responseLogFormatter,
errorLogFormatter));
}

public HistoryApiRootBuilder withApiBaseUrl(String apiBaseUrl) {
builder.withApiBaseUrl(apiBaseUrl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,15 @@ public ImportApiRootBuilder withInternalLoggerFactory(final InternalLoggerFactor
return this;
}

public ImportApiRootBuilder withInternalLoggerFactory(final InternalLoggerFactory internalLoggerFactory,
final Level responseLogEvent, final Level deprecationLogEvent, final Level defaultExceptionLogEvent,
final Map<Class<? extends Throwable>, Level> exceptionLogEvents,
final ResponseLogFormatter responseLogFormatter, final ErrorLogFormatter errorLogFormatter) {
return with(clientBuilder -> clientBuilder.withInternalLoggerFactory(internalLoggerFactory, responseLogEvent,

Check warning on line 396 in commercetools/commercetools-sdk-java-importapi/src/main/java/com/commercetools/importapi/defaultconfig/ImportApiRootBuilder.java

View check run for this annotation

Codecov / codecov/patch

commercetools/commercetools-sdk-java-importapi/src/main/java/com/commercetools/importapi/defaultconfig/ImportApiRootBuilder.java#L396

Added line #L396 was not covered by tests
deprecationLogEvent, defaultExceptionLogEvent, exceptionLogEvents, responseLogFormatter,
errorLogFormatter));
}

public ImportApiRootBuilder withApiBaseUrl(String apiBaseUrl) {
builder.withApiBaseUrl(apiBaseUrl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

import java.util.Map;

import io.vrap.rmf.base.client.http.ErrorLogFormatter;
import io.vrap.rmf.base.client.http.InternalLoggerFactory;
import io.vrap.rmf.base.client.http.ResponseLogFormatter;

import org.slf4j.event.Level;

Expand All @@ -17,7 +19,7 @@
*
* <p>The {@link io.vrap.rmf.base.client.ClientBuilder} allows the customization of the log levels used for different events. By default responses
* will be logged with {@link org.slf4j.event.Level#INFO} and errors with {@link org.slf4j.event.Level#ERROR}. The
* {@link io.vrap.rmf.base.client.ClientBuilder#withInternalLoggerFactory(InternalLoggerFactory, Level, Level, Level, Map)} method can be used
* {@link io.vrap.rmf.base.client.ClientBuilder#withInternalLoggerFactory(InternalLoggerFactory, Level, Level, Level, Map, ResponseLogFormatter, ErrorLogFormatter)} method can be used
* to change these defaults. Please see also {@link io.vrap.rmf.base.client.http.InternalLoggerMiddleware} for further details</p>
*
* {@include.example example.ExamplesTest#loggingConfiguration}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,24 @@ public ClientBuilder withInternalLoggerFactory(final InternalLoggerFactory inter
deprecationLogEvent, defaultExceptionLogEvent, exceptionLogEvents));
}

/**
* @param internalLoggerFactory {@link InternalLoggerFactory} creates the logger for request & responses
* @param responseLogEvent {@link Level} for logging responses.
* @param deprecationLogEvent {@link Level} for logging {@link ApiHttpHeaders#X_DEPRECATION_NOTICE}
* @param defaultExceptionLogEvent {@link Level} for logging errors
* @param exceptionLogEvents {@link Level} for logging by exception class
* @param responseLogFormatter {@link ResponseLogFormatter} response log formatter
* @return ClientBuilder instance
*/
public ClientBuilder withInternalLoggerFactory(final InternalLoggerFactory internalLoggerFactory,
final Level responseLogEvent, final Level deprecationLogEvent, final Level defaultExceptionLogEvent,
final Map<Class<? extends Throwable>, Level> exceptionLogEvents,
final ResponseLogFormatter responseLogFormatter, final ErrorLogFormatter errorLogFormatter) {
return withInternalLoggerMiddleware(
InternalLoggerMiddleware.of(internalLoggerFactory, responseLogEvent, deprecationLogEvent,

Check warning on line 1398 in rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/ClientBuilder.java

View check run for this annotation

Codecov / codecov/patch

rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/ClientBuilder.java#L1397-L1398

Added lines #L1397 - L1398 were not covered by tests
defaultExceptionLogEvent, exceptionLogEvents, responseLogFormatter, errorLogFormatter));
}

/**
* @param apiBaseUrl base URI for calling the API
* @return ClientBuilder instance
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

package io.vrap.rmf.base.client.http;

import io.vrap.rmf.base.client.ApiHttpRequest;

@FunctionalInterface
public interface ErrorLogFormatter {
public String format(ApiHttpRequest request, Throwable throwable, long executionTime);
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ static InternalLoggerMiddleware of(final InternalLoggerFactory internalLoggerFac
return new InternalLoggerMiddlewareImpl(internalLoggerFactory, responseLogEvent, deprecationLogEvent,
defaultExceptionLogEvent, exceptionLogEvents);
}

static InternalLoggerMiddleware of(final InternalLoggerFactory internalLoggerFactory, final Level responseLogEvent,
final Level deprecationLogEvent, final Level defaultExceptionLogEvent,
final Map<Class<? extends Throwable>, Level> exceptionLogEvents,
final ResponseLogFormatter responseLogFormatter, final ErrorLogFormatter errorLogFormatter) {
return new InternalLoggerMiddlewareImpl(internalLoggerFactory, responseLogEvent, deprecationLogEvent,

Check warning on line 47 in rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/InternalLoggerMiddleware.java

View check run for this annotation

Codecov / codecov/patch

rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/InternalLoggerMiddleware.java#L47

Added line #L47 was not covered by tests
defaultExceptionLogEvent, exceptionLogEvents, responseLogFormatter, errorLogFormatter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class InternalLoggerMiddlewareImpl implements InternalLoggerMiddleware {
private final Level responseLogEvent;
private final Level defaultExceptionLogEvent;
private final Map<Class<? extends Throwable>, Level> exceptionLogEvents;
private final ResponseLogFormatter responseLogFormatter;
private final ErrorLogFormatter errorLogFormatter;

public InternalLoggerMiddlewareImpl(final InternalLoggerFactory factory) {
this(factory, Level.INFO, Level.INFO);
Expand All @@ -34,17 +36,28 @@ public InternalLoggerMiddlewareImpl(final InternalLoggerFactory factory) {
public InternalLoggerMiddlewareImpl(final InternalLoggerFactory factory, final Level responseLogEvent,
Level deprecationLogEvent) {
this(factory, responseLogEvent, deprecationLogEvent, Level.ERROR,
Collections.singletonMap(ConcurrentModificationException.class, Level.INFO));
Collections.singletonMap(ConcurrentModificationException.class, Level.INFO), LogFormatter::formatResponse,
LogFormatter::formatError);
}

public InternalLoggerMiddlewareImpl(final InternalLoggerFactory factory, final Level responseLogEvent,
final Level deprecationLogEvent, final Level defaultExceptionLogEvent,
final Map<Class<? extends Throwable>, Level> exceptionLogEvents) {
this(factory, responseLogEvent, deprecationLogEvent, defaultExceptionLogEvent, exceptionLogEvents,
LogFormatter::formatResponse, LogFormatter::formatError);
}

public InternalLoggerMiddlewareImpl(final InternalLoggerFactory factory, final Level responseLogEvent,
final Level deprecationLogEvent, final Level defaultExceptionLogEvent,
final Map<Class<? extends Throwable>, Level> exceptionLogEvents,
final ResponseLogFormatter responseLogFormatter, final ErrorLogFormatter errorLogFormatter) {
this.factory = factory;
this.responseLogEvent = responseLogEvent;
this.deprecationLogEvent = deprecationLogEvent;
this.defaultExceptionLogEvent = defaultExceptionLogEvent;
this.exceptionLogEvents = exceptionLogEvents;
this.responseLogFormatter = responseLogFormatter;
this.errorLogFormatter = errorLogFormatter;
}

@Override
Expand Down Expand Up @@ -105,14 +118,7 @@ public CompletableFuture<ApiHttpResponse<byte[]>> invoke(final ApiHttpRequest re
.findFirst()
.map(Map.Entry::getValue)
.orElse(defaultExceptionLogEvent);
responseLogger.log(level, () -> String
.format("%s %s %s %s %s %s", request.getMethod().name(), request.getUrl(),
errorResponse.getStatusCode(), executionTime,
Optional.ofNullable(errorResponse.getHeaders().getFirst(ApiHttpHeaders.SERVER_TIMING))
.orElse("-"),
Optional.ofNullable(
errorResponse.getHeaders().getFirst(ApiHttpHeaders.X_CORRELATION_ID)).orElse("-"))
.trim());
responseLogger.log(level, () -> responseLogFormatter.format(request, errorResponse, executionTime));
final List<Map.Entry<String, String>> notices = errorResponse.getHeaders()
.getHeaders(ApiHttpHeaders.X_DEPRECATION_NOTICE);
if (notices != null) {
Expand All @@ -133,19 +139,16 @@ public CompletableFuture<ApiHttpResponse<byte[]>> invoke(final ApiHttpRequest re
.findFirst()
.map(Map.Entry::getValue)
.orElse(defaultExceptionLogEvent);
responseLogger.log(level, throwable::getCause, throwable);
responseLogger.log(level, () -> errorLogFormatter.format(request, cause, executionTime), cause);

Check warning on line 142 in rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/InternalLoggerMiddlewareImpl.java

View check run for this annotation

Codecov / codecov/patch

rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/InternalLoggerMiddlewareImpl.java#L142

Added line #L142 was not covered by tests
}
requestContext.ifPresent(c -> MDC.clear());
}
else {
final Optional<MDCContext> responseContext = Optional.ofNullable(response.getContext(MDCContext.class));
responseContext.ifPresent(c -> MDC.setContextMap(c.getValue()));

responseLogger.log(responseLogEvent, () -> String.format("%s %s %s %s %s %s",
request.getMethod().name(), request.getUrl(), response.getStatusCode(), executionTime,
Optional.ofNullable(response.getHeaders().getFirst(ApiHttpHeaders.SERVER_TIMING)).orElse("-"),
Optional.ofNullable(response.getHeaders().getFirst(ApiHttpHeaders.X_CORRELATION_ID)).orElse("-"))
.trim());
responseLogger.log(responseLogEvent,
() -> responseLogFormatter.format(request, response, executionTime));
final List<Map.Entry<String, String>> notices = response.getHeaders()
.getHeaders(ApiHttpHeaders.X_DEPRECATION_NOTICE);
if (notices != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

package io.vrap.rmf.base.client.http;

import java.util.Optional;

import io.vrap.rmf.base.client.ApiHttpHeaders;
import io.vrap.rmf.base.client.ApiHttpRequest;
import io.vrap.rmf.base.client.ApiHttpResponse;

public class LogFormatter {

Check warning on line 10 in rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/LogFormatter.java

View check run for this annotation

Codecov / codecov/patch

rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/LogFormatter.java#L10

Added line #L10 was not covered by tests
public static String formatResponse(ApiHttpRequest request, ApiHttpResponse<byte[]> response, long executionTime) {
return String
.format("%s %s %s %s %s %s", request.getMethod().name(), request.getUrl(), response.getStatusCode(),
executionTime,
Optional.ofNullable(response.getHeaders().getFirst(ApiHttpHeaders.SERVER_TIMING)).orElse("-"),
Optional.ofNullable(response.getHeaders().getFirst(ApiHttpHeaders.X_CORRELATION_ID)).orElse("-"))
.trim();
}

public static String formatError(ApiHttpRequest request, Throwable throwable, long executionTime) {
return throwable.toString();

Check warning on line 21 in rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/LogFormatter.java

View check run for this annotation

Codecov / codecov/patch

rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/LogFormatter.java#L21

Added line #L21 was not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

package io.vrap.rmf.base.client.http;

import io.vrap.rmf.base.client.ApiHttpRequest;
import io.vrap.rmf.base.client.ApiHttpResponse;

@FunctionalInterface
public interface ResponseLogFormatter {
public String format(ApiHttpRequest request, ApiHttpResponse<byte[]> response, long executionTime);
}

0 comments on commit b06a407

Please sign in to comment.