diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/StartupInfoLogger.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/StartupInfoLogger.java index 7c64418492..42081e3b58 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/StartupInfoLogger.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/StartupInfoLogger.java @@ -25,6 +25,7 @@ import org.apache.commons.logging.Log; import org.springframework.boot.system.ApplicationHome; import org.springframework.boot.system.ApplicationPid; import org.springframework.context.ApplicationContext; +import org.springframework.core.log.LogMessage; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StopWatch; @@ -44,51 +45,48 @@ class StartupInfoLogger { this.sourceClass = sourceClass; } - public void logStarting(Log log) { - Assert.notNull(log, "Log must not be null"); - if (log.isInfoEnabled()) { - log.info(getStartupMessage()); - } - if (log.isDebugEnabled()) { - log.debug(getRunningMessage()); + public void logStarting(Log applicationLog) { + Assert.notNull(applicationLog, "Log must not be null"); + applicationLog.info(LogMessage.of(this::getStartingMessage)); + applicationLog.debug(LogMessage.of(this::getRunningMessage)); + } + + public void logStarted(Log applicationLog, StopWatch stopWatch) { + if (applicationLog.isInfoEnabled()) { + applicationLog.info(getStartedMessage(stopWatch)); } } - public void logStarted(Log log, StopWatch stopWatch) { - if (log.isInfoEnabled()) { - log.info(getStartedMessage(stopWatch)); - } - } - - private String getStartupMessage() { + private CharSequence getStartingMessage() { StringBuilder message = new StringBuilder(); message.append("Starting "); - message.append(getApplicationName()); - message.append(getVersion(this.sourceClass)); - message.append(getOn()); - message.append(getPid()); - message.append(getContext()); - return message.toString(); - } - - private StringBuilder getRunningMessage() { - StringBuilder message = new StringBuilder(); - message.append("Running with Spring Boot"); - message.append(getVersion(getClass())); - message.append(", Spring"); - message.append(getVersion(ApplicationContext.class)); + appendApplicationName(message); + appendVersion(message, this.sourceClass); + appendOn(message); + appendPid(message); + appendContext(message); return message; } - private StringBuilder getStartedMessage(StopWatch stopWatch) { + private CharSequence getRunningMessage() { + StringBuilder message = new StringBuilder(); + message.append("Running with Spring Boot"); + appendVersion(message, getClass()); + message.append(", Spring"); + appendVersion(message, ApplicationContext.class); + return message; + } + + private CharSequence getStartedMessage(StopWatch stopWatch) { StringBuilder message = new StringBuilder(); message.append("Started "); - message.append(getApplicationName()); + appendApplicationName(message); message.append(" in "); message.append(stopWatch.getTotalTimeSeconds()); + message.append(" seconds"); try { double uptime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000.0; - message.append(" seconds (JVM running for ").append(uptime).append(")"); + message.append(" (JVM running for ").append(uptime).append(")"); } catch (Throwable ex) { // No JVM time available @@ -96,56 +94,64 @@ class StartupInfoLogger { return message; } - private String getApplicationName() { - return (this.sourceClass != null) ? ClassUtils.getShortName(this.sourceClass) - : "application"; + private void appendApplicationName(StringBuilder message) { + String name = (this.sourceClass != null) + ? ClassUtils.getShortName(this.sourceClass) : "application"; + message.append(name); } - private String getVersion(Class source) { - return getValue(" v", () -> source.getPackage().getImplementationVersion(), ""); + private void appendVersion(StringBuilder message, Class source) { + append(message, "v", () -> source.getPackage().getImplementationVersion()); } - private String getOn() { - return getValue(" on ", () -> InetAddress.getLocalHost().getHostName()); + private void appendOn(StringBuilder message) { + append(message, "on ", () -> InetAddress.getLocalHost().getHostName()); } - private String getPid() { - return getValue(" with PID ", () -> new ApplicationPid().toString()); + private void appendPid(StringBuilder message) { + append(message, "with PID ", () -> new ApplicationPid()); } - private String getContext() { - String startedBy = getValue("started by ", () -> System.getProperty("user.name")); - String in = getValue("in ", () -> System.getProperty("user.dir")); + private void appendContext(StringBuilder message) { + StringBuilder context = new StringBuilder(); ApplicationHome home = new ApplicationHome(this.sourceClass); - String path = (home.getSource() != null) ? home.getSource().getAbsolutePath() - : ""; - if (startedBy == null && path == null) { - return ""; + if (home.getSource() != null) { + context.append(home.getSource().getAbsolutePath()); } - if (StringUtils.hasLength(startedBy) && StringUtils.hasLength(path)) { - startedBy = " " + startedBy; + append(context, "started by ", () -> System.getProperty("user.name")); + append(context, "in ", () -> System.getProperty("user.dir")); + if (context.length() > 0) { + message.append(" ("); + message.append(context); + message.append(")"); } - if (StringUtils.hasLength(in) && StringUtils.hasLength(startedBy)) { - in = " " + in; - } - return " (" + path + startedBy + in + ")"; } - private String getValue(String prefix, Callable call) { - return getValue(prefix, call, ""); + private void append(StringBuilder message, String prefix, Callable call) { + append(message, prefix, call, ""); } - private String getValue(String prefix, Callable call, String defaultValue) { + private void append(StringBuilder message, String prefix, Callable call, + String defaultValue) { + Object result = callIfPossible(call); + String value = (result != null) ? result.toString() : null; + if (!StringUtils.hasLength(value)) { + value = defaultValue; + } + if (StringUtils.hasLength(value)) { + message.append(message.length() > 0 ? " " : ""); + message.append(prefix); + message.append(value); + } + } + + private Object callIfPossible(Callable call) { try { - Object value = call.call(); - if (value != null && StringUtils.hasLength(value.toString())) { - return prefix + value; - } + return call.call(); } catch (Exception ex) { - // Swallow and continue + return null; } - return defaultValue; } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/StartUpLoggerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/StartUpLoggerTests.java index 395eb5240a..e4f2eb668a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/StartUpLoggerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/StartUpLoggerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2019 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. @@ -18,8 +18,9 @@ package org.springframework.boot; import org.apache.commons.logging.Log; import org.junit.Test; +import org.mockito.ArgumentCaptor; -import static org.mockito.ArgumentMatchers.startsWith; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -38,7 +39,10 @@ public class StartUpLoggerTests { public void sourceClassIncluded() { given(this.log.isInfoEnabled()).willReturn(true); new StartupInfoLogger(getClass()).logStarting(this.log); - verify(this.log).info(startsWith("Starting " + getClass().getSimpleName())); + ArgumentCaptor captor = ArgumentCaptor.forClass(Object.class); + verify(this.log).info(captor.capture()); + assertThat(captor.getValue().toString()) + .startsWith("Starting " + getClass().getSimpleName()); } }