Java 在logback中将日志参数转换为字符串

Java 在logback中将日志参数转换为字符串,java,logback,Java,Logback,与大多数其他日志框架一样,logback在日志语句中使用带有对象参数的字符串,因此只有在实际需要生成/打印日志消息时,才可以将其惰性地转换为日志消息: // Calls String.valueOf(morningOrDayOrEvening) and String.valueOf(visitor) LOG.info("Good {}, {}", morningOrDayOrEvening, visitor); 现在 我想将s记录为日志消息的一部分。我希望它们的格式与自定义格式一致,而不是它们

与大多数其他日志框架一样,logback在日志语句中使用带有对象参数的字符串,因此只有在实际需要生成/打印日志消息时,才可以将其惰性地转换为日志消息:

// Calls String.valueOf(morningOrDayOrEvening) and String.valueOf(visitor)
LOG.info("Good {}, {}", morningOrDayOrEvening, visitor);
现在 我想将s记录为日志消息的一部分。我希望它们的格式与自定义格式一致,而不是它们的字符串表示形式。下面是一个例子:

Instant nextExecutionTime = Instant.now().plusSeconds(60);
LOG.info("Next execution at {}", nextExecutionTime);

// Actual output: Next execution at 2016-08-18T13:14:32.895Z
// Wanted output: Next execution at 2016-08-18 15:14:32.895
(我正在使用一个包含日志消息的where
%msg


我不想像建议的那样为实例创建包装器对象,因为这很容易忘记,并且会降低代码的可读性。

只要没有答案,我就使用这个类:

public class Times {

    /** Standard date time formatter */
    private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter()
            .withChronology(IsoChronology.INSTANCE)
            .withZone(ZoneId.systemDefault());

    /**
     * Returns a wrapper that holds a {@link Temporal} used for the {@link 
     * Object#toString()} implementation. The string representation is
     * evaluated lazily and thus good for log statements.
     * @param temporal time to format
     * @return an object with a specific {@link Object#toString()} impl
     */
    public static Object format(Temporal temporal) {
        return new Object() {
            @Override
            public String toString() {
                return FORMATTER.format(temporal);
            }
        };
    }
}
日志语句示例:

LOG.info("next execution at {}", Times.format(nextExecutionInstant));
// Prints "next execution at 2016-08-18 15:14:32.895"
这实际上比急切地格式化瞬间要快得多。我为持续时间实现了类似的功能,因此它们看起来确实是这样的:

LOG.info("execution took {}", Times.format(executionTime));
// Prints "execution took 2m 12s"

只要没有答案,我就使用这个类:

public class Times {

    /** Standard date time formatter */
    private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter()
            .withChronology(IsoChronology.INSTANCE)
            .withZone(ZoneId.systemDefault());

    /**
     * Returns a wrapper that holds a {@link Temporal} used for the {@link 
     * Object#toString()} implementation. The string representation is
     * evaluated lazily and thus good for log statements.
     * @param temporal time to format
     * @return an object with a specific {@link Object#toString()} impl
     */
    public static Object format(Temporal temporal) {
        return new Object() {
            @Override
            public String toString() {
                return FORMATTER.format(temporal);
            }
        };
    }
}
日志语句示例:

LOG.info("next execution at {}", Times.format(nextExecutionInstant));
// Prints "next execution at 2016-08-18 15:14:32.895"
这实际上比急切地格式化瞬间要快得多。我为持续时间实现了类似的功能,因此它们看起来确实是这样的:

LOG.info("execution took {}", Times.format(executionTime));
// Prints "execution took 2m 12s"