diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/LogFileWebEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/LogFileWebEndpointAutoConfiguration.java index dbb2c6326ee..54b0226bf35 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/LogFileWebEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/LogFileWebEndpointAutoConfiguration.java @@ -58,27 +58,20 @@ public class LogFileWebEndpointAutoConfiguration { private static class LogFileCondition extends SpringBootCondition { + @SuppressWarnings("deprecation") @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment environment = context.getEnvironment(); - String config = environment - .resolvePlaceholders("${" + LogFile.FILE_NAME_PROPERTY + ":}"); - if (!StringUtils.hasText(config)) { - config = environment - .resolvePlaceholders("${" + LogFile.FILE_PROPERTY + ":}"); - } + String config = getLogFileConfig(environment, LogFile.FILE_NAME_PROPERTY, + LogFile.FILE_PROPERTY); ConditionMessage.Builder message = ConditionMessage.forCondition("Log File"); if (StringUtils.hasText(config)) { return ConditionOutcome .match(message.found(LogFile.FILE_NAME_PROPERTY).items(config)); } - config = environment - .resolvePlaceholders("${" + LogFile.FILE_PATH_PROPERTY + ":}"); - if (!StringUtils.hasText(config)) { - config = environment - .resolvePlaceholders("${" + LogFile.PATH_PROPERTY + ":}"); - } + config = getLogFileConfig(environment, LogFile.FILE_PATH_PROPERTY, + LogFile.PATH_PROPERTY); if (StringUtils.hasText(config)) { return ConditionOutcome .match(message.found(LogFile.FILE_PATH_PROPERTY).items(config)); @@ -92,6 +85,15 @@ public class LogFileWebEndpointAutoConfiguration { return ConditionOutcome.noMatch(message.didNotFind("logging file").atAll()); } + private String getLogFileConfig(Environment environment, String configName, + String deprecatedConfigName) { + String config = environment.resolvePlaceholders("${" + configName + ":}"); + if (StringUtils.hasText(config)) { + return config; + } + return environment.resolvePlaceholders("${" + deprecatedConfigName + ":}"); + } + } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointTests.java index fd008fc1faf..4e8c6ecaf66 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-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. diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java index 6cd9f4f22cd..7ab47e7c86a 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-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. diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index af6f1f35b93..b1b0eedf422 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -37,12 +37,12 @@ content into your application. Rather, pick only the properties that you need. # LOGGING logging.config= # Location of the logging configuration file. For instance, `classpath:logback.xml` for Logback. logging.exception-conversion-word=%wEx # Conversion word used when logging exceptions. - logging.file.name= # Log file name (for instance, `myapp.log`). Names can be an exact location or relative to the current directory. logging.file.max-history=0 # Maximum of archive log files to keep. Only supported with the default logback setup. logging.file.max-size=10MB # Maximum log file size. Only supported with the default logback setup. + logging.file.name= # Log file name (for instance, `myapp.log`). Names can be an exact location or relative to the current directory. + logging.file.path= # Location of the log file. For instance, `/var/log`. logging.group.*= # Log groups to quickly change multiple loggers at the same time. For instance, `logging.level.db=org.hibernate,org.springframework.jdbc`. logging.level.*= # Log levels severity mapping. For instance, `logging.level.org.springframework=DEBUG`. - logging.file.path= # Location of the log file. For instance, `/var/log`. logging.pattern.console= # Appender pattern for output to the console. Supported only with the default Logback setup. logging.pattern.dateformat=yyyy-MM-dd HH:mm:ss.SSS # Appender pattern for log date format. Supported only with the default Logback setup. logging.pattern.file= # Appender pattern for output to a file. Supported only with the default Logback setup. diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index 4ca41939f96..5053592ffe5 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -164,9 +164,9 @@ use the following additional endpoints: |Yes |`logfile` -|Returns the contents of the logfile (if `logging.file.name` or `logging.file.path` properties have -been set). Supports the use of the HTTP `Range` header to retrieve part of the log file's -content. +|Returns the contents of the logfile (if `logging.file.name` or `logging.file.path` +properties have been set). Supports the use of the HTTP `Range` header to retrieve part of +the log file's content. |Yes |`prometheus` diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LogFile.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LogFile.java index e5f341741a9..c99d443fe66 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LogFile.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LogFile.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-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. @@ -131,19 +131,25 @@ public class LogFile { * @return a {@link LogFile} or {@code null} if the environment didn't contain any * suitable properties */ + @SuppressWarnings("deprecation") public static LogFile get(PropertyResolver propertyResolver) { - String file = propertyResolver.getProperty(FILE_NAME_PROPERTY); - String path = propertyResolver.getProperty(FILE_PATH_PROPERTY); - if (file == null) { - file = propertyResolver.getProperty(FILE_PROPERTY); - } - if (path == null) { - path = propertyResolver.getProperty(PATH_PROPERTY); - } + String file = getLogFileProperty(propertyResolver, FILE_NAME_PROPERTY, + FILE_PROPERTY); + String path = getLogFileProperty(propertyResolver, FILE_PATH_PROPERTY, + PATH_PROPERTY); if (StringUtils.hasLength(file) || StringUtils.hasLength(path)) { return new LogFile(file, path); } return null; } + private static String getLogFileProperty(PropertyResolver propertyResolver, + String propertyName, String deprecatedPropertyName) { + String property = propertyResolver.getProperty(propertyName); + if (property != null) { + return property; + } + return propertyResolver.getProperty(deprecatedPropertyName); + } + } diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 56759ba416b..dccde53dda6 100644 --- a/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -67,6 +67,15 @@ "defaultValue": "%wEx", "sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener" }, + { + "name": "logging.file", + "type": "java.lang.String", + "description": "Log file name (for instance, `myapp.log`). Names can be an exact location or relative to the current directory.", + "sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener", + "deprecation": { + "replacement": "logging.file.name" + } + }, { "name": "logging.file.name", "type": "java.lang.String", @@ -105,6 +114,15 @@ "description": "Log levels severity mapping. For instance, `logging.level.org.springframework=DEBUG`.", "sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener" }, + { + "name": "logging.path", + "type": "java.lang.String", + "description": "Location of the log file. For instance, `/var/log`.", + "sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener", + "deprecation": { + "replacement": "logging.file.path" + } + }, { "name": "logging.pattern.console", "type": "java.lang.String", @@ -332,28 +350,8 @@ "type": "java.lang.Integer", "description": "Application index.", "deprecation": { - "reason": "Application context ids are now unique by default.", - "level": "error" - } - }, - { - "name": "logging.file", - "type": "java.lang.String", - "description": "Log file name (for instance, `myapp.log`). Names can be an exact location or relative to the current directory.", - "sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener", - "deprecation": { - "replacement": "logging.file.name", - "level": "error" - } - }, - { - "name": "logging.path", - "type": "java.lang.String", - "description": "Location of the log file. For instance, `/var/log`.", - "sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener", - "deprecation": { - "replacement": "logging.file.path", - "level": "error" + "level": "error", + "reason": "Application context ids are now unique by default." } } ], @@ -366,6 +364,7 @@ "parameters": { "group": false } + } ] }, diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerTests.java index 4bf4b586325..d566e8d40c9 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerTests.java @@ -224,6 +224,22 @@ public class LoggingApplicationListenerTests { assertThat(output).startsWith("target/foo.log"); } + @Test + @Deprecated + public void addLogFilePropertyWithDeprecatedProperty() { + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, + "logging.config=classpath:logback-nondefault.xml", + "logging.file=target/foo.log"); + this.initializer.initialize(this.context.getEnvironment(), + this.context.getClassLoader()); + Log logger = LogFactory.getLog(LoggingApplicationListenerTests.class); + String existingOutput = this.outputCapture.toString(); + logger.info("Hello world"); + String output = this.outputCapture.toString().substring(existingOutput.length()) + .trim(); + assertThat(output).startsWith("target/foo.log"); + } + @Test public void addLogFilePropertyWithDefault() { assertThat(new File("target/foo.log").exists()).isFalse(); @@ -236,6 +252,19 @@ public class LoggingApplicationListenerTests { assertThat(new File("target/foo.log").exists()).isTrue(); } + @Test + @Deprecated + public void addLogFilePropertyWithDefaultAndDeprecatedProperty() { + assertThat(new File("target/foo.log").exists()).isFalse(); + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, + "logging.file=target/foo.log"); + this.initializer.initialize(this.context.getEnvironment(), + this.context.getClassLoader()); + Log logger = LogFactory.getLog(LoggingApplicationListenerTests.class); + logger.info("Hello world"); + assertThat(new File("target/foo.log").exists()).isTrue(); + } + @Test public void addLogPathProperty() { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, @@ -251,6 +280,21 @@ public class LoggingApplicationListenerTests { assertThat(output).startsWith("target/foo/spring.log"); } + @Test + public void addLogPathPropertyWithDeprecatedProperty() { + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, + "logging.config=classpath:logback-nondefault.xml", + "logging.path=target/foo/"); + this.initializer.initialize(this.context.getEnvironment(), + this.context.getClassLoader()); + Log logger = LogFactory.getLog(LoggingApplicationListenerTests.class); + String existingOutput = this.outputCapture.toString(); + logger.info("Hello world"); + String output = this.outputCapture.toString().substring(existingOutput.length()) + .trim(); + assertThat(output).startsWith("target/foo/spring.log"); + } + @Test public void parseDebugArg() { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, "debug"); @@ -516,24 +560,13 @@ public class LoggingApplicationListenerTests { @Deprecated public void systemPropertiesAreSetForLoggingConfigurationWithDeprecatedProperties() { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, - "logging.exception-conversion-word=conversion", "logging.file=target/log", - "logging.path=path", "logging.pattern.console=console", - "logging.pattern.file=file", "logging.pattern.level=level"); + "logging.file=target/log", "logging.path=path"); this.initializer.initialize(this.context.getEnvironment(), this.context.getClassLoader()); - assertThat(System.getProperty(LoggingSystemProperties.CONSOLE_LOG_PATTERN)) - .isEqualTo("console"); - assertThat(System.getProperty(LoggingSystemProperties.FILE_LOG_PATTERN)) - .isEqualTo("file"); - assertThat(System.getProperty(LoggingSystemProperties.EXCEPTION_CONVERSION_WORD)) - .isEqualTo("conversion"); assertThat(System.getProperty(LoggingSystemProperties.LOG_FILE)) .isEqualTo("target/log"); - assertThat(System.getProperty(LoggingSystemProperties.LOG_LEVEL_PATTERN)) - .isEqualTo("level"); assertThat(System.getProperty(LoggingSystemProperties.LOG_PATH)) .isEqualTo("path"); - assertThat(System.getProperty(LoggingSystemProperties.PID_KEY)).isNotNull(); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/LogFileTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/LogFileTests.java index 197fe0d5ca7..81c3c647407 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/LogFileTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/LogFileTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-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. @@ -16,6 +16,7 @@ package org.springframework.boot.logging; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; @@ -39,28 +40,27 @@ public class LogFileTests { @Test public void noProperties() { - PropertyResolver resolver = getPropertyResolver(null, null); + PropertyResolver resolver = getPropertyResolver(Collections.emptyMap()); LogFile logFile = LogFile.get(resolver); assertThat(logFile).isNull(); } @Test public void loggingFile() { - PropertyResolver resolver = getPropertyResolver("log.file", null); - LogFile logFile = LogFile.get(resolver); - Properties properties = new Properties(); - logFile.applyTo(properties); - assertThat(logFile.toString()).isEqualTo("log.file"); - assertThat(properties.getProperty(LoggingSystemProperties.LOG_FILE)) - .isEqualTo("log.file"); - assertThat(properties.getProperty(LoggingSystemProperties.LOG_PATH)).isNull(); + PropertyResolver resolver = getPropertyResolver( + Collections.singletonMap("logging.file.name", "log.file")); + testLoggingFile(resolver); } @Test @Deprecated public void loggingFileWithDeprecatedProperties() { - PropertyResolver resolver = getPropertyResolverWithDeprecatedProperties( - "log.file", null); + PropertyResolver resolver = getPropertyResolver( + Collections.singletonMap("logging.file", "log.file")); + testLoggingFile(resolver); + } + + private void testLoggingFile(PropertyResolver resolver) { LogFile logFile = LogFile.get(resolver); Properties properties = new Properties(); logFile.applyTo(properties); @@ -72,22 +72,20 @@ public class LogFileTests { @Test public void loggingPath() { - PropertyResolver resolver = getPropertyResolver(null, "logpath"); - LogFile logFile = LogFile.get(resolver); - Properties properties = new Properties(); - logFile.applyTo(properties); - assertThat(logFile.toString()).isEqualTo("logpath/spring.log"); - assertThat(properties.getProperty(LoggingSystemProperties.LOG_FILE)) - .isEqualTo("logpath/spring.log"); - assertThat(properties.getProperty(LoggingSystemProperties.LOG_PATH)) - .isEqualTo("logpath"); + PropertyResolver resolver = getPropertyResolver( + Collections.singletonMap("logging.file.path", "logpath")); + testLoggingPath(resolver); } @Test @Deprecated public void loggingPathWithDeprecatedProperties() { - PropertyResolver resolver = getPropertyResolverWithDeprecatedProperties(null, - "logpath"); + PropertyResolver resolver = getPropertyResolver( + Collections.singletonMap("logging.path", "logpath")); + testLoggingPath(resolver); + } + + private void testLoggingPath(PropertyResolver resolver) { LogFile logFile = LogFile.get(resolver); Properties properties = new Properties(); logFile.applyTo(properties); @@ -100,22 +98,24 @@ public class LogFileTests { @Test public void loggingFileAndPath() { - PropertyResolver resolver = getPropertyResolver("log.file", "logpath"); - LogFile logFile = LogFile.get(resolver); - Properties properties = new Properties(); - logFile.applyTo(properties); - assertThat(logFile.toString()).isEqualTo("log.file"); - assertThat(properties.getProperty(LoggingSystemProperties.LOG_FILE)) - .isEqualTo("log.file"); - assertThat(properties.getProperty(LoggingSystemProperties.LOG_PATH)) - .isEqualTo("logpath"); + Map properties = new LinkedHashMap<>(); + properties.put("logging.file.name", "log.file"); + properties.put("logging.file.path", "logpath"); + PropertyResolver resolver = getPropertyResolver(properties); + testLoggingFileAndPath(resolver); } @Test @Deprecated public void loggingFileAndPathWithDeprecatedProperties() { - PropertyResolver resolver = getPropertyResolverWithDeprecatedProperties( - "log.file", "logpath"); + Map properties = new LinkedHashMap<>(); + properties.put("logging.file", "log.file"); + properties.put("logging.path", "logpath"); + PropertyResolver resolver = getPropertyResolver(properties); + testLoggingFileAndPath(resolver); + } + + private void testLoggingFileAndPath(PropertyResolver resolver) { LogFile logFile = LogFile.get(resolver); Properties properties = new Properties(); logFile.applyTo(properties); @@ -126,23 +126,7 @@ public class LogFileTests { .isEqualTo("logpath"); } - private PropertyResolver getPropertyResolver(String file, String path) { - Map properties = new LinkedHashMap<>(); - properties.put("logging.file.name", file); - properties.put("logging.file.path", path); - PropertySource propertySource = new MapPropertySource("properties", - properties); - MutablePropertySources propertySources = new MutablePropertySources(); - propertySources.addFirst(propertySource); - return new PropertySourcesPropertyResolver(propertySources); - } - - @Deprecated - private PropertyResolver getPropertyResolverWithDeprecatedProperties(String file, - String path) { - Map properties = new LinkedHashMap<>(); - properties.put("logging.file", file); - properties.put("logging.path", path); + private PropertyResolver getPropertyResolver(Map properties) { PropertySource propertySource = new MapPropertySource("properties", properties); MutablePropertySources propertySources = new MutablePropertySources();