Merge pull request #6352 from vpavic/gh-5590
* pr/6352: Polish SizeAndTimeBasedRollingPolicy changes Use SizeAndTimeBasedRollingPolicy file appender
This commit is contained in:
commit
7c5d2fadd3
|
|
@ -41,6 +41,8 @@ content into your application; rather pick only the properties that you need.
|
||||||
logging.config= # Location of the logging configuration file. For instance `classpath:logback.xml` for Logback
|
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.exception-conversion-word=%wEx # Conversion word used when logging exceptions.
|
||||||
logging.file= # Log file name. For instance `myapp.log`
|
logging.file= # Log file name. For instance `myapp.log`
|
||||||
|
logging.file.max-history= # Maximum of archive log files to keep. Only supported with the default logback setup.
|
||||||
|
logging.file.max-size= # Maximum log file size. Only supported with the default logback setup.
|
||||||
logging.level.*= # Log levels severity mapping. For instance `logging.level.org.springframework=DEBUG`
|
logging.level.*= # Log levels severity mapping. For instance `logging.level.org.springframework=DEBUG`
|
||||||
logging.path= # Location of the log file. For instance `/var/log`
|
logging.path= # Location of the log file. For instance `/var/log`
|
||||||
logging.pattern.console= # Appender pattern for output to the console. Only supported with the default logback setup.
|
logging.pattern.console= # Appender pattern for output to the console. Only supported with the default logback setup.
|
||||||
|
|
|
||||||
|
|
@ -1533,7 +1533,9 @@ relative to the current directory.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
Log files rotate when they reach 10 MB and, as with console output, `ERROR`-level,
|
Log files rotate when they reach 10 MB and, as with console output, `ERROR`-level,
|
||||||
`WARN`-level, and `INFO`-level messages are logged by default.
|
`WARN`-level, and `INFO`-level messages are logged by default. Size limits can be changed
|
||||||
|
using the `logging.file.max-size` property. Previously rotated files are archived
|
||||||
|
indefinitely unless the `logging.file.max-history` property has been set.
|
||||||
|
|
||||||
NOTE: The logging system is initialized early in the application lifecycle. Consequently,
|
NOTE: The logging system is initialized early in the application lifecycle. Consequently,
|
||||||
logging properties are not found in property files loaded through `@PropertySource`
|
logging properties are not found in property files loaded through `@PropertySource`
|
||||||
|
|
@ -1620,6 +1622,16 @@ To help with the customization, some other properties are transferred from the S
|
||||||
|`LOG_FILE`
|
|`LOG_FILE`
|
||||||
|If defined, it is used in the default log configuration.
|
|If defined, it is used in the default log configuration.
|
||||||
|
|
||||||
|
|`logging.file.max-size`
|
||||||
|
|`LOG_FILE_MAX_SIZE`
|
||||||
|
|Maximum log file size (if LOG_FILE enabled). (Only supported with the default logback
|
||||||
|
setup.)
|
||||||
|
|
||||||
|
|`logging.file.max-history`
|
||||||
|
|`LOG_FILE_MAX_HISTORY`
|
||||||
|
|Maximum number of archive log files to keep (if LOG_FILE enabled). (Only supported with
|
||||||
|
the default logback setup.)
|
||||||
|
|
||||||
|`logging.path`
|
|`logging.path`
|
||||||
|`LOG_PATH`
|
|`LOG_PATH`
|
||||||
|If defined, it is used in the default log configuration.
|
|If defined, it is used in the default log configuration.
|
||||||
|
|
@ -1645,7 +1657,6 @@ To help with the customization, some other properties are transferred from the S
|
||||||
environment variable).
|
environment variable).
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
|
||||||
All the supported logging systems can consult System properties when parsing their
|
All the supported logging systems can consult System properties when parsing their
|
||||||
configuration files. See the default configurations in `spring-boot.jar` for examples:
|
configuration files. See the default configurations in `spring-boot.jar` for examples:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import org.springframework.util.Assert;
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Madhura Bhave
|
* @author Madhura Bhave
|
||||||
|
* @author Vedran Pavic
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
public class LoggingSystemProperties {
|
public class LoggingSystemProperties {
|
||||||
|
|
@ -63,6 +64,16 @@ public class LoggingSystemProperties {
|
||||||
*/
|
*/
|
||||||
public static final String FILE_LOG_PATTERN = "FILE_LOG_PATTERN";
|
public static final String FILE_LOG_PATTERN = "FILE_LOG_PATTERN";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the System property that contains the file log max history.
|
||||||
|
*/
|
||||||
|
public static final String FILE_MAX_HISTORY = "LOG_FILE_MAX_HISTORY";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the System property that contains the file log max size.
|
||||||
|
*/
|
||||||
|
public static final String FILE_MAX_SIZE = "LOG_FILE_MAX_SIZE";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the System property that contains the log level pattern.
|
* The name of the System property that contains the log level pattern.
|
||||||
*/
|
*/
|
||||||
|
|
@ -89,6 +100,8 @@ public class LoggingSystemProperties {
|
||||||
"exception-conversion-word");
|
"exception-conversion-word");
|
||||||
setSystemProperty(resolver, CONSOLE_LOG_PATTERN, "pattern.console");
|
setSystemProperty(resolver, CONSOLE_LOG_PATTERN, "pattern.console");
|
||||||
setSystemProperty(resolver, FILE_LOG_PATTERN, "pattern.file");
|
setSystemProperty(resolver, FILE_LOG_PATTERN, "pattern.file");
|
||||||
|
setSystemProperty(resolver, FILE_MAX_HISTORY, "file.max-history");
|
||||||
|
setSystemProperty(resolver, FILE_MAX_SIZE, "file.max-size");
|
||||||
setSystemProperty(resolver, LOG_LEVEL_PATTERN, "pattern.level");
|
setSystemProperty(resolver, LOG_LEVEL_PATTERN, "pattern.level");
|
||||||
setSystemProperty(PID_KEY, new ApplicationPid().toString());
|
setSystemProperty(PID_KEY, new ApplicationPid().toString());
|
||||||
if (logFile != null) {
|
if (logFile != null) {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
|
||||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
import ch.qos.logback.core.Appender;
|
import ch.qos.logback.core.Appender;
|
||||||
import ch.qos.logback.core.ConsoleAppender;
|
import ch.qos.logback.core.ConsoleAppender;
|
||||||
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
|
import ch.qos.logback.core.CoreConstants;
|
||||||
import ch.qos.logback.core.rolling.RollingFileAppender;
|
import ch.qos.logback.core.rolling.RollingFileAppender;
|
||||||
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
|
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
|
||||||
import ch.qos.logback.core.util.FileSize;
|
import ch.qos.logback.core.util.FileSize;
|
||||||
import ch.qos.logback.core.util.OptionHelper;
|
import ch.qos.logback.core.util.OptionHelper;
|
||||||
|
|
||||||
|
|
@ -45,6 +45,7 @@ import org.springframework.util.ReflectionUtils;
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Madhura Bhave
|
* @author Madhura Bhave
|
||||||
|
* @author Vedran Pavic
|
||||||
* @since 1.1.2
|
* @since 1.1.2
|
||||||
*/
|
*/
|
||||||
class DefaultLogbackConfiguration {
|
class DefaultLogbackConfiguration {
|
||||||
|
|
@ -57,6 +58,8 @@ class DefaultLogbackConfiguration {
|
||||||
private static final String FILE_LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss.SSS} "
|
private static final String FILE_LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss.SSS} "
|
||||||
+ "${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}";
|
+ "${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}";
|
||||||
|
|
||||||
|
private static final String MAX_FILE_SIZE = "10MB";
|
||||||
|
|
||||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
private final PropertyResolver patterns;
|
private final PropertyResolver patterns;
|
||||||
|
|
@ -140,34 +143,35 @@ class DefaultLogbackConfiguration {
|
||||||
config.start(encoder);
|
config.start(encoder);
|
||||||
appender.setFile(logFile);
|
appender.setFile(logFile);
|
||||||
setRollingPolicy(appender, config, logFile);
|
setRollingPolicy(appender, config, logFile);
|
||||||
setMaxFileSize(appender, config);
|
|
||||||
config.appender("FILE", appender);
|
config.appender("FILE", appender);
|
||||||
return appender;
|
return appender;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRollingPolicy(RollingFileAppender<ILoggingEvent> appender,
|
private void setRollingPolicy(RollingFileAppender<ILoggingEvent> appender,
|
||||||
LogbackConfigurator config, String logFile) {
|
LogbackConfigurator config, String logFile) {
|
||||||
FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
|
SizeAndTimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new SizeAndTimeBasedRollingPolicy<>();
|
||||||
rollingPolicy.setFileNamePattern(logFile + ".%i");
|
rollingPolicy.setFileNamePattern(logFile + ".%d{yyyy-MM-dd}.%i.gz");
|
||||||
|
setMaxFileSize(rollingPolicy,
|
||||||
|
this.patterns.getProperty("logging.file.max-size", MAX_FILE_SIZE));
|
||||||
|
rollingPolicy.setMaxHistory(this.patterns.getProperty("logging.file.max-history",
|
||||||
|
Integer.class, CoreConstants.UNBOUND_HISTORY));
|
||||||
appender.setRollingPolicy(rollingPolicy);
|
appender.setRollingPolicy(rollingPolicy);
|
||||||
rollingPolicy.setParent(appender);
|
rollingPolicy.setParent(appender);
|
||||||
config.start(rollingPolicy);
|
config.start(rollingPolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMaxFileSize(RollingFileAppender<ILoggingEvent> appender,
|
private void setMaxFileSize(
|
||||||
LogbackConfigurator config) {
|
SizeAndTimeBasedRollingPolicy<ILoggingEvent> rollingPolicy,
|
||||||
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
|
String maxFileSize) {
|
||||||
try {
|
try {
|
||||||
triggeringPolicy.setMaxFileSize(FileSize.valueOf("10MB"));
|
rollingPolicy.setMaxFileSize(FileSize.valueOf(maxFileSize));
|
||||||
}
|
}
|
||||||
catch (NoSuchMethodError ex) {
|
catch (NoSuchMethodError ex) {
|
||||||
// Logback < 1.1.8 used String configuration
|
// Logback < 1.1.8 used String configuration
|
||||||
Method method = ReflectionUtils.findMethod(SizeBasedTriggeringPolicy.class,
|
Method method = ReflectionUtils.findMethod(
|
||||||
"setMaxFileSize", String.class);
|
SizeAndTimeBasedRollingPolicy.class, "setMaxFileSize", String.class);
|
||||||
ReflectionUtils.invokeMethod(method, triggeringPolicy, "10MB");
|
ReflectionUtils.invokeMethod(method, rollingPolicy, maxFileSize);
|
||||||
}
|
}
|
||||||
appender.setTriggeringPolicy(triggeringPolicy);
|
|
||||||
config.start(triggeringPolicy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,20 @@
|
||||||
"description": "Name of the log file. Names can be an exact location or relative to the current directory.",
|
"description": "Name of the log file. Names can be an exact location or relative to the current directory.",
|
||||||
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener"
|
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "logging.file.max-size",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "Maximum log file size. Only supported with the default logback setup.",
|
||||||
|
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener",
|
||||||
|
"defaultValue": "10MB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "logging.file.max-history",
|
||||||
|
"type": "java.lang.Integer",
|
||||||
|
"description": "Maximum number of archive log files to keep. Only supported with the default logback setup.",
|
||||||
|
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "logging.level",
|
"name": "logging.level",
|
||||||
"type": "java.util.Map<java.lang.String,java.lang.String>",
|
"type": "java.util.Map<java.lang.String,java.lang.String>",
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,10 @@ initialization performed by Boot
|
||||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
<file>${LOG_FILE}</file>
|
<file>${LOG_FILE}</file>
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
<fileNamePattern>${LOG_FILE}.%i</fileNamePattern>
|
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
|
||||||
|
<maxFileSize>${MAX_FILE_SIZE:-10MB}</maxFileSize>
|
||||||
|
<maxHistory>${MAX_HISTORY:-0}</maxHistory>
|
||||||
</rollingPolicy>
|
</rollingPolicy>
|
||||||
<triggeringPolicy
|
|
||||||
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
|
||||||
<MaxFileSize>10MB</MaxFileSize>
|
|
||||||
</triggeringPolicy>
|
|
||||||
</appender>
|
</appender>
|
||||||
</included>
|
</included>
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,10 @@ import ch.qos.logback.classic.Level;
|
||||||
import ch.qos.logback.classic.Logger;
|
import ch.qos.logback.classic.Logger;
|
||||||
import ch.qos.logback.classic.LoggerContext;
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
import ch.qos.logback.classic.spi.LoggerContextListener;
|
import ch.qos.logback.classic.spi.LoggerContextListener;
|
||||||
|
import ch.qos.logback.core.ConsoleAppender;
|
||||||
|
import ch.qos.logback.core.CoreConstants;
|
||||||
|
import ch.qos.logback.core.rolling.RollingFileAppender;
|
||||||
|
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.impl.SLF4JLogFactory;
|
import org.apache.commons.logging.impl.SLF4JLogFactory;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
|
|
@ -48,6 +52,7 @@ import org.springframework.boot.logging.LoggingSystem;
|
||||||
import org.springframework.boot.testsupport.assertj.Matched;
|
import org.springframework.boot.testsupport.assertj.Matched;
|
||||||
import org.springframework.boot.testsupport.rule.OutputCapture;
|
import org.springframework.boot.testsupport.rule.OutputCapture;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
|
@ -66,6 +71,7 @@ import static org.mockito.Mockito.verify;
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @author Ben Hale
|
* @author Ben Hale
|
||||||
* @author Madhura Bhave
|
* @author Madhura Bhave
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
||||||
|
|
||||||
|
|
@ -120,15 +126,16 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
||||||
assertThat(getLineWithText(output, "Hello world")).contains("INFO");
|
assertThat(getLineWithText(output, "Hello world")).contains("INFO");
|
||||||
assertThat(file.exists()).isTrue();
|
assertThat(file.exists()).isTrue();
|
||||||
assertThat(getLineWithText(file, "Hello world")).contains("INFO");
|
assertThat(getLineWithText(file, "Hello world")).contains("INFO");
|
||||||
|
assertThat(ReflectionTestUtils.getField(getRollingPolicy(), "maxFileSize")
|
||||||
|
.toString()).isEqualTo("10 MB");
|
||||||
|
assertThat(getRollingPolicy().getMaxHistory())
|
||||||
|
.isEqualTo(CoreConstants.UNBOUND_HISTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicConfigLocation() throws Exception {
|
public void testBasicConfigLocation() throws Exception {
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
|
assertThat(getConsoleAppender()).isNotNull();
|
||||||
LoggerContext context = (LoggerContext) factory;
|
|
||||||
Logger root = context.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
|
||||||
assertThat(root.getAppender("CONSOLE")).isNotNull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -339,6 +346,35 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
||||||
assertThat(getLineWithText(file, "Hello world")).doesNotContain("INFO");
|
assertThat(getLineWithText(file, "Hello world")).doesNotContain("INFO");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMaxFileSizeProperty() throws Exception {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("logging.file.max-size", "100MB");
|
||||||
|
LoggingInitializationContext loggingInitializationContext = new LoggingInitializationContext(
|
||||||
|
environment);
|
||||||
|
File file = new File(tmpDir(), "logback-test.log");
|
||||||
|
LogFile logFile = getLogFile(file.getPath(), null);
|
||||||
|
this.loggingSystem.initialize(loggingInitializationContext, null, logFile);
|
||||||
|
this.logger.info("Hello world");
|
||||||
|
assertThat(getLineWithText(file, "Hello world")).contains("INFO");
|
||||||
|
assertThat(ReflectionTestUtils.getField(getRollingPolicy(), "maxFileSize")
|
||||||
|
.toString()).isEqualTo("100 MB");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMaxHistoryProperty() throws Exception {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("logging.file.max-history", "30");
|
||||||
|
LoggingInitializationContext loggingInitializationContext = new LoggingInitializationContext(
|
||||||
|
environment);
|
||||||
|
File file = new File(tmpDir(), "logback-test.log");
|
||||||
|
LogFile logFile = getLogFile(file.getPath(), null);
|
||||||
|
this.loggingSystem.initialize(loggingInitializationContext, null, logFile);
|
||||||
|
this.logger.info("Hello world");
|
||||||
|
assertThat(getLineWithText(file, "Hello world")).contains("INFO");
|
||||||
|
assertThat(getRollingPolicy().getMaxHistory()).isEqualTo(30);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void exceptionsIncludeClassPackaging() throws Exception {
|
public void exceptionsIncludeClassPackaging() throws Exception {
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
|
|
@ -404,6 +440,24 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
||||||
verify(listener, times(2)).onReset(loggerContext);
|
verify(listener, times(2)).onReset(loggerContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Logger getRootLogger() {
|
||||||
|
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
|
||||||
|
LoggerContext context = (LoggerContext) factory;
|
||||||
|
return context.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ConsoleAppender getConsoleAppender() {
|
||||||
|
return (ConsoleAppender) getRootLogger().getAppender("CONSOLE");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RollingFileAppender getFileAppender() {
|
||||||
|
return (RollingFileAppender) getRootLogger().getAppender("FILE");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SizeAndTimeBasedRollingPolicy getRollingPolicy() {
|
||||||
|
return (SizeAndTimeBasedRollingPolicy) getFileAppender().getRollingPolicy();
|
||||||
|
}
|
||||||
|
|
||||||
private String getLineWithText(File file, String outputSearch) throws Exception {
|
private String getLineWithText(File file, String outputSearch) throws Exception {
|
||||||
return getLineWithText(FileCopyUtils.copyToString(new FileReader(file)),
|
return getLineWithText(FileCopyUtils.copyToString(new FileReader(file)),
|
||||||
outputSearch);
|
outputSearch);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue