Add LogFormatUtils

1. Helper method to eliminate duplication in formatting (de-)serialized
   values for logging introduced with prior commit #e62298.

2. Helper method for TRACE vs DEBUG logging with different details.

Issue: SPR-17254
This commit is contained in:
Rossen Stoyanchev
2018-09-14 14:38:11 -04:00
parent 41d4cb5cbf
commit db8e9eafb2
24 changed files with 212 additions and 289 deletions

View File

@@ -28,6 +28,7 @@ import reactor.core.publisher.Flux;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.log.LogFormatUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
@@ -68,15 +69,11 @@ public final class CharSequenceEncoder extends AbstractEncoder<CharSequence> {
Charset charset = getCharset(mimeType);
return Flux.from(inputStream).map(charSequence -> {
if (logger.isDebugEnabled() && !Hints.isLoggingSuppressed(hints)) {
String logPrefix = Hints.getLogPrefix(hints);
String s = logPrefix + "Writing " + formatValue(charSequence, logger.isTraceEnabled());
if (logger.isTraceEnabled()) {
logger.trace(s);
}
else {
logger.debug(s);
}
if (!Hints.isLoggingSuppressed(hints)) {
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(charSequence, !traceOn);
return Hints.getLogPrefix(hints) + "Writing " + formatted;
});
}
CharBuffer charBuffer = CharBuffer.wrap(charSequence);
ByteBuffer byteBuffer = charset.encode(charBuffer);
@@ -95,14 +92,6 @@ public final class CharSequenceEncoder extends AbstractEncoder<CharSequence> {
return charset;
}
private String formatValue(@Nullable Object value, boolean logFullValue) {
if (value == null) {
return "";
}
String s = value instanceof CharSequence ? "\"" + value + "\"" : value.toString();
return logFullValue || s.length() < 100 ? s : s.substring(0, 100) + " (truncated)...";
}
/**
* Create a {@code CharSequenceEncoder} that supports only "text/plain".

View File

@@ -33,6 +33,7 @@ import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.core.log.LogFormatUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
@@ -206,15 +207,10 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
CharBuffer charBuffer = charset.decode(dataBuffer.asByteBuffer());
DataBufferUtils.release(dataBuffer);
String value = charBuffer.toString();
if (logger.isDebugEnabled()) {
String s = Hints.getLogPrefix(hints) + "Decoded " + formatValue(value, logger.isTraceEnabled());
if (logger.isTraceEnabled()) {
logger.trace(s);
}
else {
logger.debug(s);
}
}
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(value, !traceOn);
return Hints.getLogPrefix(hints) + "Decoded " + formatted;
});
return value;
}
@@ -227,14 +223,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
}
}
private String formatValue(@Nullable Object value, boolean logFullValue) {
if (value == null) {
return "";
}
String s = value instanceof CharSequence ? "\"" + value + "\"" : value.toString();
return logFullValue || s.length() < 100 ? s : s.substring(0, 100) + " (truncated)...";
}
/**
* Create a {@code StringDecoder} for {@code "text/plain"}.

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2002-2018 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.core.log;
import java.util.function.Function;
import org.apache.commons.logging.Log;
import org.springframework.lang.Nullable;
/**
* Utility methods for formatting and logging messages.
*
* <p>Mainly for internal use within the framework with Apache Commons Logging,
* typically in the form of the {@code spring-jcl} bridge but also compatible
* with other Commons Logging bridges.
*
* @author Rossen Stoyanchev
* @since 5.1
*/
public final class LogFormatUtils {
private LogFormatUtils() {
}
/**
* Format the given value via {@code toString()}, quoting it if it is a
* {@link CharSequence}, and possibly truncating at 100 if limitLength is
* set to true.
* @param value the value to format
* @param limitLength whether to truncate large formatted values (over 100).
* @return the formatted value
* @since 5.1
*/
public static String formatValue(@Nullable Object value, boolean limitLength) {
if (value == null) {
return "";
}
String s = value instanceof CharSequence ? "\"" + value + "\"" : value.toString();
return limitLength && s.length() > 100 ? s.substring(0, 100) + " (truncated)..." : s;
}
/**
* Use this to log a message with different levels of detail (or different
* messages) at TRACE vs DEBUG log levels. Effectively, a substitute for:
* <pre class="code">
* if (logger.isDebugEnabled()) {
* String s = logger.isTraceEnabled() ? "..." : "...";
* if (logger.isTraceEnabled()) {
* logger.trace(s);
* }
* else {
* logger.debug(s);
* }
* }
* </pre>
* @param logger the logger to use to log the message
* @param messageFactory function that accepts a boolean set to the value
* of {@link Log#isTraceEnabled()}.
*/
public static void traceDebug(Log logger, Function<Boolean, String> messageFactory) {
if (logger.isDebugEnabled()) {
String logMessage = messageFactory.apply(logger.isTraceEnabled());
if (logger.isTraceEnabled()) {
logger.trace(logMessage);
}
else {
logger.debug(logMessage);
}
}
}
}