You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ja...@apache.org on 2016/10/20 13:25:58 UTC
lucene-solr:branch_6x: SOLR-99570: Various log tidying at Solr startup
Repository: lucene-solr
Updated Branches:
refs/heads/branch_6x 22b0d5f4d -> ed3b268d6
SOLR-99570: Various log tidying at Solr startup
(cherry picked from commit 9776196)
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/ed3b268d
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ed3b268d
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ed3b268d
Branch: refs/heads/branch_6x
Commit: ed3b268d62f23e212c410cb35aa4318afa088f55
Parents: 22b0d5f
Author: Jan H�ydahl <ja...@apache.org>
Authored: Thu Oct 20 14:47:32 2016 +0200
Committer: Jan H�ydahl <ja...@apache.org>
Committed: Thu Oct 20 15:14:27 2016 +0200
----------------------------------------------------------------------
solr/CHANGES.txt | 15 +-
solr/bin/solr | 18 +-
solr/bin/solr.cmd | 28 +-
.../src/java/org/apache/solr/util/SolrCLI.java | 271 ++++++++++++++++++-
.../org/apache/solr/util/UtilsToolTest.java | 185 +++++++++++++
5 files changed, 479 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ed3b268d/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 4e68c55..1b1c9cb 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -42,8 +42,12 @@ Upgrade Notes
prefix, then you will now get an error as these options are incompatible with numeric faceting.
* Solr's logging verbosity at the INFO level has been greatly reduced, and
- you may need to update the log configs to use the DEBUG level to get the
- same logging messages as before.
+ you may need to update the log configs to use the DEBUG level to see all the
+ logging messages you used to see at INFO level before.
+
+* We are no longer backing up solr.log and solr_gc.log files in date-stamped copies forever. If you relied on
+ the solr_log_<date> or solr_gc_log_<date> being in the logs folder that will no longer be the case.
+ See SOLR-9570 for details.
* The create/deleteCollection methods on MiniSolrCloudCluster have been
deprecated. Clients should instead use the CollectionAdminRequest API. In
@@ -272,6 +276,13 @@ Other Changes
* SOLR-7850: Moved defaults within bin/solr.in.sh (and bin/solr.in.cmd on Windows) to bin/solr (and bin/solr.cmd)
such that the default state of these files is to set nothing. This makes Solr work better with Docker. (David Smiley)
+* SOLR-9570: Various log tidying now happens at Solr startup:
+ Old solr_log_<date> and solr_gc_log_<date> files are removed, avoiding disks to fill up,
+ solr.log.X files are rotated, preserving solr.log from last run in solr.log.1, solr.log.1 => solr.log.2 etc
+ solr-*-console.log files are moved into $SOLR_LOGS_DIR/archived/ instead of being overwritten
+ Last JVM garbage collection log solr_gc.log is moved into $SOLR_LOGS_DIR/archived/
+ (janhoy)
+
================== 6.2.1 ==================
Bug Fixes
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ed3b268d/solr/bin/solr
----------------------------------------------------------------------
diff --git a/solr/bin/solr b/solr/bin/solr
index df6b4d0..6aa5709 100755
--- a/solr/bin/solr
+++ b/solr/bin/solr
@@ -1387,20 +1387,10 @@ if [ ! -e "$SOLR_HOME" ]; then
exit 1
fi
-# backup the log files before starting
-if [ -f "$SOLR_LOGS_DIR/solr.log" ]; then
- if $verbose ; then
- echo "Backing up $SOLR_LOGS_DIR/solr.log"
- fi
- mv "$SOLR_LOGS_DIR/solr.log" "$SOLR_LOGS_DIR/solr_log_$(date +"%Y%m%d_%H%M")"
-fi
-
-if [ -f "$SOLR_LOGS_DIR/solr_gc.log" ]; then
- if $verbose ; then
- echo "Backing up $SOLR_LOGS_DIR/solr_gc.log"
- fi
- mv "$SOLR_LOGS_DIR/solr_gc.log" "$SOLR_LOGS_DIR/solr_gc_log_$(date +"%Y%m%d_%H%M")"
-fi
+run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" -remove_old_solr_logs 7 || echo "Failed removing old solr logs"
+run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" -archive_gc_logs || echo "Failed archiving old GC logs"
+run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" -archive_console_logs || echo "Failed archiving old console logs"
+run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" -rotate_solr_logs 9 || echo "Failed rotating old solr logs"
java_ver_out=`echo "$("$JAVA" -version 2>&1)"`
JAVA_VERSION=`echo $java_ver_out | grep "java version" | awk '{ print substr($3, 2, length($3)-2); }'`
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ed3b268d/solr/bin/solr.cmd
----------------------------------------------------------------------
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index 10ea6d6..317a789 100644
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -860,19 +860,11 @@ IF ERRORLEVEL 1 (
set IS_64bit=true
)
-REM backup log files (use current timestamp for backup name)
-For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
-For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b)
-set now_ts=!mydate!_!mytime!
-IF EXIST "!SOLR_LOGS_DIR!\solr.log" (
- echo Backing up !SOLR_LOGS_DIR!\solr.log
- move /Y "!SOLR_LOGS_DIR!\solr.log" "!SOLR_LOGS_DIR!\solr_log_!now_ts!"
-)
-
-IF EXIST "!SOLR_LOGS_DIR!\solr_gc.log" (
- echo Backing up !SOLR_LOGS_DIR!\solr_gc.log
- move /Y "!SOLR_LOGS_DIR!\solr_gc.log" "!SOLR_LOGS_DIR!\solr_gc_log_!now_ts!"
-)
+REM Clean up and rotate logs
+call :run_utils "-remove_old_solr_logs 7" || echo "Failed removing old solr logs"
+call :run_utils "-archive_gc_logs" || echo "Failed archiving old GC logs"
+call :run_utils "-archive_console_logs" || echo "Failed archiving old console logs"
+call :run_utils "-rotate_solr_logs 9" || echo "Failed rotating old solr logs"
IF NOT "%ZK_HOST%"=="" set SOLR_MODE=solrcloud
@@ -1136,6 +1128,16 @@ goto done
org.apache.solr.util.SolrCLI version
goto done
+:run_utils
+set "TOOL_CMD=%~1"
+"%JAVA%" %SOLR_SSL_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dlog4j.configuration="file:%DEFAULT_SERVER_DIR%\scripts\cloud-scripts\log4j.properties" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI utils -s "%DEFAULT_SERVER_DIR%" -l "%SOLR_LOGS_DIR%" %TOOL_CMD%
+if errorlevel 1 (
+ exit /b 1
+)
+goto done
+
:parse_create_args
IF [%1]==[] goto run_create
IF "%1"=="-c" goto set_create_name
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ed3b268d/solr/core/src/java/org/apache/solr/util/SolrCLI.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
index a60620e..351638f 100644
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -30,7 +30,10 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.FileOwnerAttributeView;
+import java.time.Instant;
+import java.time.Period;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -45,6 +48,8 @@ import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -114,7 +119,6 @@ import static org.apache.solr.common.params.CommonParams.NAME;
* Command-line utility for working with Solr.
*/
public class SolrCLI {
-
/**
* Defines the interface to a Solr tool that can be run from this command-line app.
*/
@@ -235,7 +239,6 @@ public class SolrCLI {
};
private static void exit(int exitStatus) {
- // TODO: determine if we're running in a test and don't exit
try {
System.exit(exitStatus);
} catch (java.lang.SecurityException secExc) {
@@ -261,6 +264,17 @@ public class SolrCLI {
exit(0);
}
+ Tool tool = findTool(args);
+ CommandLine cli = parseCmdLine(args, tool.getOptions());
+ System.exit(tool.runTool(cli));
+ }
+
+ public static Tool findTool(String[] args) throws Exception {
+ String toolType = args[0].trim().toLowerCase(Locale.ROOT);
+ return newTool(toolType);
+ }
+
+ public static CommandLine parseCmdLine(String[] args, Option[] toolOptions) throws Exception {
String configurerClassName = System.getProperty("solr.authentication.httpclient.configurer");
if (configurerClassName!=null) {
try {
@@ -274,10 +288,6 @@ public class SolrCLI {
}
}
- // Determine the tool
- String toolType = args[0].trim().toLowerCase(Locale.ROOT);
- Tool tool = newTool(toolType);
-
// the parser doesn't like -D props
List<String> toolArgList = new ArrayList<String>();
List<String> dashDList = new ArrayList<String>();
@@ -293,7 +303,7 @@ public class SolrCLI {
// process command-line args to configure this application
CommandLine cli =
- processCommandLineArgs(joinCommonAndToolOptions(tool.getOptions()), toolArgs);
+ processCommandLineArgs(joinCommonAndToolOptions(toolOptions), toolArgs);
List argList = cli.getArgList();
argList.addAll(dashDList);
@@ -305,8 +315,7 @@ public class SolrCLI {
checkSslStoreSysProp(solrInstallDir, "trustStore");
}
- // run the tool
- exit(tool.runTool(cli));
+ return cli;
}
protected static void checkSslStoreSysProp(String solrInstallDir, String key) {
@@ -370,6 +379,8 @@ public class SolrCLI {
return new ZkLsTool();
else if ("assert".equals(toolType))
return new AssertTool();
+ else if ("utils".equals(toolType))
+ return new UtilsTool();
// If you add a built-in tool to this class, add it here to avoid
// classpath scanning
@@ -3342,4 +3353,246 @@ public class SolrCLI {
}
}
} // end AssertTool class
+
+ public static class UtilsTool extends ToolBase {
+ private Path serverPath;
+ private Path logsPath;
+ private boolean beQuiet;
+
+ public UtilsTool() { this(System.out); }
+ public UtilsTool(PrintStream stdout) { super(stdout); }
+
+ public String getName() {
+ return "prestart";
+ }
+
+ @SuppressWarnings("static-access")
+ public Option[] getOptions() {
+ return new Option[]{
+ OptionBuilder
+ .withArgName("path")
+ .hasArg()
+ .withDescription("Path to server dir. Required if logs path is relative")
+ .create("s"),
+ OptionBuilder
+ .withArgName("path")
+ .hasArg()
+ .withDescription("Path to logs dir. If relative, also provide server dir with -s")
+ .create("l"),
+ OptionBuilder
+ .withDescription("Be quiet, don't print to stdout, only return exit codes")
+ .create("q"),
+ OptionBuilder
+ .withArgName("daysToKeep")
+ .hasArg()
+ .withType(Integer.class)
+ .withDescription("Path to logs directory")
+ .create("remove_old_solr_logs"),
+ OptionBuilder
+ .withArgName("generations")
+ .hasArg()
+ .withType(Integer.class)
+ .withDescription("Rotate solr.log to solr.log.1 etc")
+ .create("rotate_solr_logs"),
+ OptionBuilder
+ .withDescription("Archive old garbage collection logs into archive/")
+ .create("archive_gc_logs"),
+ OptionBuilder
+ .withDescription("Archive old console logs into archive/")
+ .create("archive_console_logs")
+ };
+ }
+
+ @Override
+ public int runTool(CommandLine cli) throws Exception {
+ if (cli.getOptions().length == 0 || cli.getArgs().length > 0 || cli.hasOption("h")) {
+ new HelpFormatter().printHelp("bin/solr utils [OPTIONS]", getToolOptions(this));
+ return 1;
+ }
+ if (cli.hasOption("s")) {
+ serverPath = Paths.get(cli.getOptionValue("s"));
+ }
+ if (cli.hasOption("l")) {
+ logsPath = Paths.get(cli.getOptionValue("l"));
+ }
+ if (cli.hasOption("q")) {
+ beQuiet = cli.hasOption("q");
+ }
+ if (cli.hasOption("remove_old_solr_logs")) {
+ if (removeOldSolrLogs(Integer.parseInt(cli.getOptionValue("remove_old_solr_logs"))) > 0) return 1;
+ }
+ if (cli.hasOption("rotate_solr_logs")) {
+ if (rotateSolrLogs(Integer.parseInt(cli.getOptionValue("rotate_solr_logs"))) > 0) return 1;
+ }
+ if (cli.hasOption("archive_gc_logs")) {
+ if (archiveGcLogs() > 0) return 1;
+ }
+ if (cli.hasOption("archive_console_logs")) {
+ if (archiveConsoleLogs() > 0) return 1;
+ }
+ return 0;
+ }
+
+ /**
+ * Moves gc logs into archived/
+ * @return 0 on success
+ * @throws Exception on failure
+ */
+ public int archiveGcLogs() throws Exception {
+ prepareLogsPath();
+ Path archivePath = logsPath.resolve("archived");
+ if (!archivePath.toFile().exists()) {
+ Files.createDirectories(archivePath);
+ }
+ List<Path> archived = Files.find(archivePath, 1, (f, a)
+ -> a.isRegularFile() && String.valueOf(f.getFileName()).startsWith("solr_gc_"))
+ .collect(Collectors.toList());
+ for (Path p : archived) {
+ Files.delete(p);
+ }
+ List<Path> files = Files.find(logsPath, 1, (f, a)
+ -> a.isRegularFile() && String.valueOf(f.getFileName()).startsWith("solr_gc_"))
+ .collect(Collectors.toList());
+ if (files.size() > 0) {
+ out("Archiving " + files.size() + " old GC log files to " + archivePath);
+ for (Path p : files) {
+ Files.move(p, archivePath.resolve(p.getFileName()), StandardCopyOption.REPLACE_EXISTING);
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Moves console log(s) into archiced/
+ * @return 0 on success
+ * @throws Exception on failure
+ */
+ public int archiveConsoleLogs() throws Exception {
+ prepareLogsPath();
+ Path archivePath = logsPath.resolve("archived");
+ if (!archivePath.toFile().exists()) {
+ Files.createDirectories(archivePath);
+ }
+ List<Path> archived = Files.find(archivePath, 1, (f, a)
+ -> a.isRegularFile() && String.valueOf(f.getFileName()).endsWith("-console.log"))
+ .collect(Collectors.toList());
+ for (Path p : archived) {
+ Files.delete(p);
+ }
+ List<Path> files = Files.find(logsPath, 1, (f, a)
+ -> a.isRegularFile() && String.valueOf(f.getFileName()).endsWith("-console.log"))
+ .collect(Collectors.toList());
+ if (files.size() > 0) {
+ out("Archiving " + files.size() + " console log files");
+ for (Path p : files) {
+ Files.move(p, archivePath.resolve(p.getFileName()), StandardCopyOption.REPLACE_EXISTING);
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Rotates solr.log before starting Solr. Mimics log4j2 behavior, i.e. with generations=9:
+ * <pre>
+ * solr.log.9 (and higher) are deleted
+ * solr.log.8 -> solr.log.9
+ * solr.log.7 -> solr.log.8
+ * ...
+ * solr.log -> solr.log.1
+ * </pre>
+ * @param generations number of generations to keep. Should agree with setting in log4j.properties
+ * @return 0 if success
+ * @throws Exception if problems
+ */
+ public int rotateSolrLogs(int generations) throws Exception {
+ prepareLogsPath();
+ if (logsPath.toFile().exists() && logsPath.resolve("solr.log").toFile().exists()) {
+ out("Rotating solr logs, keeping a max of "+generations+" generations");
+ try (Stream<Path> files = Files.find(logsPath, 1,
+ (f, a) -> a.isRegularFile() && String.valueOf(f.getFileName()).startsWith("solr.log."))
+ .sorted((b,a) -> new Integer(a.getFileName().toString().substring(9))
+ .compareTo(new Integer(b.getFileName().toString().substring(9))))) {
+ files.forEach(p -> {
+ try {
+ int number = Integer.parseInt(p.getFileName().toString().substring(9));
+ if (number >= generations) {
+ Files.delete(p);
+ } else {
+ Path renamed = p.getParent().resolve("solr.log." + (number + 1));
+ Files.move(p, renamed);
+ }
+ } catch (IOException e) {
+ out("Problem during rotation of log files: " + e.getMessage());
+ }
+ });
+ } catch (NumberFormatException nfe) {
+ throw new Exception("Do not know how to rotate solr.log.<ext> with non-numeric extension. Rotate aborted.", nfe);
+ }
+ Files.move(logsPath.resolve("solr.log"), logsPath.resolve("solr.log.1"));
+ }
+
+ return 0;
+ }
+
+ /**
+ * Deletes time-stamped old solr logs, if older than n days
+ * @param daysToKeep number of days logs to keep before deleting
+ * @return 0 on success
+ * @throws Exception on failure
+ */
+ public int removeOldSolrLogs(int daysToKeep) throws Exception {
+ prepareLogsPath();
+ if (logsPath.toFile().exists()) {
+ try (Stream<Path> stream = Files.find(logsPath, 2, (f, a) -> a.isRegularFile()
+ && Instant.now().minus(Period.ofDays(daysToKeep)).isAfter(a.lastModifiedTime().toInstant())
+ && String.valueOf(f.getFileName()).startsWith("solr_log_"))) {
+ List<Path> files = stream.collect(Collectors.toList());
+ if (files.size() > 0) {
+ out("Deleting "+files.size() + " solr_log_* files older than " + daysToKeep + " days.");
+ for (Path p : files) {
+ Files.delete(p);
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ // Private methods to follow
+
+ private void out(String message) {
+ if (!beQuiet) {
+ stdout.print(message + "\n");
+ }
+ }
+
+ private void prepareLogsPath() throws Exception {
+ if (logsPath == null) {
+ throw new Exception("Command requires the -l <log-directory> option");
+ }
+ if (!logsPath.isAbsolute()) {
+ if (serverPath != null && serverPath.isAbsolute() && serverPath.toFile().exists()) {
+ logsPath = serverPath.resolve(logsPath);
+ } else {
+ throw new Exception("Logs directory must be an absolute path, or -s must be supplied");
+ }
+ }
+ }
+
+ @Override
+ protected void runImpl(CommandLine cli) throws Exception {
+ }
+
+ public void setLogPath(Path logsPath) {
+ this.logsPath = logsPath;
+ }
+
+ public void setServerPath(Path serverPath) {
+ this.serverPath = serverPath;
+ }
+
+ public void setQuiet(boolean shouldPrintStdout) {
+ this.beQuiet = shouldPrintStdout;
+ }
+ } // end UtilsTool class
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ed3b268d/solr/core/src/test/org/apache/solr/util/UtilsToolTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/UtilsToolTest.java b/solr/core/src/test/org/apache/solr/util/UtilsToolTest.java
new file mode 100644
index 0000000..fa39620
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/util/UtilsToolTest.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.solr.util;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileTime;
+import java.time.Instant;
+import java.time.Period;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.cli.CommandLine;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.solr.util.SolrCLI.findTool;
+import static org.apache.solr.util.SolrCLI.parseCmdLine;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit test for SolrCLI's UtilsTool
+ */
+public class UtilsToolTest {
+
+ private Path dir;
+ private SolrCLI.UtilsTool tool;
+ private List<String> files = Arrays.asList(
+ "solr.log",
+ "solr.log.1",
+ "solr.log.2",
+ "solr.log.3",
+ "solr.log.9",
+ "solr.log.10",
+ "solr.log.11",
+ "solr_log_20160102",
+ "solr_log_20160304",
+ "solr-8983-console.log",
+ "solr_gc_log_20160102",
+ "solr_gc_log_2");
+
+ @Before
+ public void setUp() throws IOException {
+ dir = Files.createTempDirectory("Utils Tool Test");
+ files.stream().forEach(f -> {
+ try {
+ dir.resolve(f).toFile().createNewFile();
+ } catch (IOException e) {
+ assertTrue(false);
+ }
+ });
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ org.apache.commons.io.FileUtils.deleteDirectory(dir.toFile());
+ }
+
+ @Test
+ public void testEmptyAndQuiet() throws Exception {
+ String[] args = {"utils", "-remove_old_solr_logs", "7",
+ "-rotate_solr_logs", "9",
+ "-archive_gc_logs",
+ "-archive_console_logs",
+ "-q",
+ "-l", dir.toString()};
+ assertEquals(0, runTool(args));
+ }
+
+ @Test
+ public void testNonexisting() throws Exception {
+ String nonexisting = dir.resolve("non-existing").toString();
+ String[] args = {"utils", "-remove_old_solr_logs", "7",
+ "-rotate_solr_logs", "9",
+ "-archive_gc_logs",
+ "-archive_console_logs",
+ "-l", nonexisting};
+ assertEquals(0, runTool(args));
+ }
+
+ @Test
+ public void testRemoveOldSolrLogs() throws Exception {
+ String[] args = {"utils", "-remove_old_solr_logs", "1", "-l", dir.toString()};
+ assertEquals(files.size(), fileCount());
+ assertEquals(0, runTool(args));
+ assertEquals(files.size(), fileCount()); // No logs older than 1 day
+ Files.setLastModifiedTime(dir.resolve("solr_log_20160102"), FileTime.from(Instant.now().minus(Period.ofDays(2))));
+ assertEquals(0, runTool(args));
+ assertEquals(files.size()-1, fileCount()); // One logs older than 1 day
+ Files.setLastModifiedTime(dir.resolve("solr_log_20160304"), FileTime.from(Instant.now().minus(Period.ofDays(3))));
+ assertEquals(0, runTool(args));
+ assertEquals(files.size()-2, fileCount()); // Two logs older than 1 day
+ }
+
+ @Test
+ public void testRelativePath() throws Exception {
+ String[] args = {"utils", "-remove_old_solr_logs", "0", "-l", dir.getFileName().toString(), "-s", dir.getParent().toString()};
+ assertEquals(files.size(), fileCount());
+ assertEquals(0, runTool(args));
+ assertEquals(files.size()-2, fileCount());
+ }
+
+ @Test
+ public void testRelativePathError() throws Exception {
+ String[] args = {"utils", "-remove_old_solr_logs", "0", "-l", dir.getFileName().toString()};
+ try {
+ runTool(args);
+ } catch (Exception e) {
+ return;
+ }
+ assertTrue(false);
+ }
+
+ @Test
+ public void testRemoveOldGcLogs() throws Exception {
+ String[] args = {"utils", "-archive_gc_logs", "-l", dir.toString()};
+ assertEquals(files.size(), fileCount());
+ assertEquals(0, runTool(args));
+ assertEquals(files.size()-2, fileCount());
+ assertFalse(listFiles().contains("solr_gc_log_2"));
+ assertTrue(Files.exists(dir.resolve("archived").resolve("solr_gc_log_2")));
+ assertEquals(0, runTool(args));
+ assertFalse(Files.exists(dir.resolve("archived").resolve("solr_gc_log_2")));
+ }
+
+ @Test
+ public void testArchiveConsoleLogs() throws Exception {
+ String[] args = {"utils", "-archive_console_logs", "-l", dir.toString()};
+ assertEquals(files.size(), fileCount());
+ assertEquals(0, runTool(args));
+ assertEquals(files.size()-1, fileCount());
+ assertFalse(listFiles().contains("solr-8983-console.log"));
+ assertTrue(Files.exists(dir.resolve("archived").resolve("solr-8983-console.log")));
+ assertEquals(0, runTool(args));
+ assertFalse(Files.exists(dir.resolve("archived").resolve("solr-8983-console.log")));
+ }
+
+ @Test
+ public void testRotateSolrLogs() throws Exception {
+ String[] args = {"utils", "-rotate_solr_logs", "9", "-l", dir.toString()};
+ assertEquals(files.size(), fileCount());
+ assertTrue(listFiles().contains("solr.log"));
+ assertEquals(0, runTool(args));
+ assertEquals(files.size()-3, fileCount());
+ assertTrue(listFiles().contains("solr.log.4"));
+ assertFalse(listFiles().contains("solr.log"));
+ assertFalse(listFiles().contains("solr.log.9"));
+ assertFalse(listFiles().contains("solr.log.10"));
+ assertFalse(listFiles().contains("solr.log.11"));
+ }
+
+ private List<String> listFiles() throws IOException {
+ return Files.find(dir, 1, (p, a) -> a.isRegularFile()).map(p -> p.getFileName().toString()).collect(Collectors.toList());
+ }
+
+ private long fileCount() throws IOException {
+ return listFiles().size();
+ }
+
+ private int runTool(String[] args) throws Exception {
+ SolrCLI.Tool tool = findTool(args);
+ CommandLine cli = parseCmdLine(args, tool.getOptions());
+ return tool.runTool(cli);
+ }
+}
\ No newline at end of file