You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2015/11/28 17:16:26 UTC
[43/46] logging-log4j2 git commit: LOG4J2-435 added support for a
TestMode parameter to allow testing without accidentally deleting the wrong
files
LOG4J2-435 added support for a TestMode parameter to allow testing
without accidentally deleting the wrong files
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/11e9a27e
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/11e9a27e
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/11e9a27e
Branch: refs/heads/master
Commit: 11e9a27eb9ee13c6c9a7b0e3203c88e07a2881ab
Parents: e9875dc
Author: rpopma <rp...@apache.org>
Authored: Sun Nov 29 00:13:29 2015 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sun Nov 29 00:13:29 2015 +0900
----------------------------------------------------------------------
.../appender/rolling/action/DeleteAction.java | 30 ++++++++++---
.../rolling/action/DeletingVisitor.java | 23 +++++++++-
.../rolling/action/DeleteActionTest.java | 46 ++++++++++++++------
.../rolling/action/DeletingVisitorTest.java | 27 +++++++++---
src/site/xdoc/manual/appenders.xml | 10 +++++
5 files changed, 108 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/11e9a27e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
index 4cb6b9f..7010766 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteAction.java
@@ -37,7 +37,8 @@ import org.apache.logging.log4j.core.lookup.StrSubstitutor;
@Plugin(name = "Delete", category = "Core", printObject = true)
public class DeleteAction extends AbstractPathAction {
- private PathSorter pathSorter;
+ private final PathSorter pathSorter;
+ private final boolean testMode;
/**
* Creates a new DeleteAction that starts scanning for files to delete from the specified base path.
@@ -47,13 +48,17 @@ public class DeleteAction extends AbstractPathAction {
* @param maxDepth The maxDepth parameter is the maximum number of levels of directories to visit. A value of 0
* means that only the starting file is visited, unless denied by the security manager. A value of
* MAX_VALUE may be used to indicate that all levels should be visited.
+ * @param testMode if true, files are not deleted but instead a message is printed to the <a
+ * href="http://logging.apache.org/log4j/2.x/manual/configuration.html#StatusMessages">status logger</a>
+ * at INFO level. Users can use this to do a dry run to test if their configuration works as expected.
* @param sorter sorts
* @param pathConditions an array of path filters (if more than one, they all need to accept a path before it is
* deleted).
*/
- DeleteAction(final String basePath, final boolean followSymbolicLinks, final int maxDepth, final PathSorter sorter,
- final PathCondition[] pathConditions, final StrSubstitutor subst) {
+ DeleteAction(final String basePath, final boolean followSymbolicLinks, final int maxDepth, final boolean testMode,
+ final PathSorter sorter, final PathCondition[] pathConditions, final StrSubstitutor subst) {
super(basePath, followSymbolicLinks, maxDepth, pathConditions, subst);
+ this.testMode = testMode;
this.pathSorter = Objects.requireNonNull(sorter, "sorter");
if (pathConditions == null || pathConditions.length == 0) {
LOGGER.error("Missing Delete conditions: unconditional Delete not supported");
@@ -94,9 +99,18 @@ public class DeleteAction extends AbstractPathAction {
return sortedPaths;
}
+ /**
+ * Returns {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise.
+ *
+ * @return {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise
+ */
+ public boolean isTestMode() {
+ return testMode;
+ }
+
@Override
protected FileVisitor<Path> createFileVisitor(final Path visitorBaseDir, final List<PathCondition> conditions) {
- return new DeletingVisitor(visitorBaseDir, conditions);
+ return new DeletingVisitor(visitorBaseDir, conditions, testMode);
}
/**
@@ -107,6 +121,10 @@ public class DeleteAction extends AbstractPathAction {
* @param maxDepth The maxDepth parameter is the maximum number of levels of directories to visit. A value of 0
* means that only the starting file is visited, unless denied by the security manager. A value of
* MAX_VALUE may be used to indicate that all levels should be visited.
+ * @param testMode if true, files are not deleted but instead a message is printed to the <a
+ * href="http://logging.apache.org/log4j/2.x/manual/configuration.html#StatusMessages">status logger</a>
+ * at INFO level. Users can use this to do a dry run to test if their configuration works as expected.
+ * Default is false.
* @param PathSorter a plugin implementing the {@link PathSorter} interface
* @param PathConditions an array of path conditions (if more than one, they all need to accept a path before it is
* deleted).
@@ -119,11 +137,13 @@ public class DeleteAction extends AbstractPathAction {
@PluginAttribute("basePath") final String basePath, //
@PluginAttribute(value = "followLinks", defaultBoolean = false) final boolean followLinks,
@PluginAttribute(value = "maxDepth", defaultInt = 1) final int maxDepth,
+ @PluginAttribute(value = "testMode", defaultBoolean = false) final boolean testMode,
@PluginElement("PathSorter") final PathSorter sorterParameter,
@PluginElement("PathConditions") final PathCondition[] pathConditions,
@PluginConfiguration final Configuration config) {
// @formatter:on
final PathSorter sorter = sorterParameter == null ? new PathSortByModificationTime(true) : sorterParameter;
- return new DeleteAction(basePath, followLinks, maxDepth, sorter, pathConditions, config.getStrSubstitutor());
+ return new DeleteAction(basePath, followLinks, maxDepth, testMode, sorter, pathConditions,
+ config.getStrSubstitutor());
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/11e9a27e/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java
index fc42c05..dd94589 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java
@@ -36,6 +36,7 @@ public class DeletingVisitor extends SimpleFileVisitor<Path> {
private static final Logger LOGGER = StatusLogger.getLogger();
private final Path basePath;
+ private final boolean testMode;
private final List<? extends PathCondition> pathConditions;
/**
@@ -43,8 +44,13 @@ public class DeletingVisitor extends SimpleFileVisitor<Path> {
*
* @param basePath used to relativize paths
* @param pathConditions objects that need to confirm whether a file can be deleted
+ * @param testMode if true, files are not deleted but instead a message is printed to the <a
+ * href="http://logging.apache.org/log4j/2.x/manual/configuration.html#StatusMessages">status logger</a>
+ * at INFO level. Users can use this to do a dry run to test if their configuration works as expected.
*/
- public DeletingVisitor(final Path basePath, final List<? extends PathCondition> pathConditions) {
+ public DeletingVisitor(final Path basePath, final List<? extends PathCondition> pathConditions,
+ final boolean testMode) {
+ this.testMode = testMode;
this.basePath = Objects.requireNonNull(basePath, "basePath");
this.pathConditions = Objects.requireNonNull(pathConditions, "pathConditions");
for (final PathCondition condition : pathConditions) {
@@ -61,7 +67,11 @@ public class DeletingVisitor extends SimpleFileVisitor<Path> {
return FileVisitResult.CONTINUE;
}
}
- delete(file);
+ if (isTestMode()) {
+ LOGGER.info("Deleting {} (TEST MODE: file not actually deleted)", file);
+ } else {
+ delete(file);
+ }
return FileVisitResult.CONTINUE;
}
@@ -75,4 +85,13 @@ public class DeletingVisitor extends SimpleFileVisitor<Path> {
LOGGER.trace("Deleting {}", file);
Files.delete(file);
}
+
+ /**
+ * Returns {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise.
+ *
+ * @return {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise
+ */
+ public boolean isTestMode() {
+ return testMode;
+ }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/11e9a27e/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteActionTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteActionTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteActionTest.java
index 8793732..4f0b36e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteActionTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeleteActionTest.java
@@ -39,22 +39,24 @@ import static org.junit.Assert.*;
*/
public class DeleteActionTest {
- private static DeleteAction createAnyFilter(String path, boolean followLinks, int maxDepth) {
+ private static DeleteAction createAnyFilter(String path, boolean followLinks, int maxDepth, boolean testMode) {
PathCondition[] pathFilters = {new FixedCondition(true)};
- return create(path, followLinks, maxDepth, pathFilters);
+ return create(path, followLinks, maxDepth, testMode, pathFilters);
}
- private static DeleteAction create(String path, boolean followLinks, int maxDepth, PathCondition[] filters) {
+ private static DeleteAction create(String path, boolean followLinks, int maxDepth, boolean testMode,
+ PathCondition[] filters) {
Configuration config = new BasicConfigurationFactory().new BasicConfiguration();
- DeleteAction delete = DeleteAction.createDeleteAction(path, followLinks, maxDepth, null, filters, config);
+ DeleteAction delete = DeleteAction.createDeleteAction(path, followLinks, maxDepth, testMode, null, filters,
+ config);
return delete;
}
@Test
public void testGetBasePathResolvesLookups() {
- DeleteAction delete = createAnyFilter("${sys:user.home}/a/b/c", false, 1);
-
- Path actual = delete.getBasePath();
+ DeleteAction delete = createAnyFilter("${sys:user.home}/a/b/c", false, 1, false);
+
+ Path actual = delete.getBasePath();
String expected = System.getProperty("user.home") + "/a/b/c";
assertEquals(FileSystems.getDefault().getPath(expected), actual);
@@ -62,40 +64,56 @@ public class DeleteActionTest {
@Test
public void testGetBasePathStringReturnsOriginalParam() {
- DeleteAction delete = createAnyFilter("${sys:user.home}/a/b/c", false, 1);
+ DeleteAction delete = createAnyFilter("${sys:user.home}/a/b/c", false, 1, false);
assertEquals("${sys:user.home}/a/b/c", delete.getBasePathString());
}
@Test
public void testGetMaxDepthReturnsConstructorValue() {
- DeleteAction delete = createAnyFilter("any", false, 23);
+ DeleteAction delete = createAnyFilter("any", false, 23, false);
assertEquals(23, delete.getMaxDepth());
}
@Test
public void testGetOptionsReturnsEmptySetIfNotFollowingLinks() {
- DeleteAction delete = createAnyFilter("any", false, 0);
+ DeleteAction delete = createAnyFilter("any", false, 0, false);
assertEquals(Collections.emptySet(), delete.getOptions());
}
@Test
public void testGetOptionsReturnsSetWithFollowLinksIfFollowingLinks() {
- DeleteAction delete = createAnyFilter("any", true, 0);
+ DeleteAction delete = createAnyFilter("any", true, 0, false);
assertEquals(EnumSet.of(FileVisitOption.FOLLOW_LINKS), delete.getOptions());
}
@Test
public void testGetFiltersReturnsConstructorValue() {
PathCondition[] filters = {new FixedCondition(true), new FixedCondition(false)};
-
- DeleteAction delete = create("any", true, 0, filters);
+
+ DeleteAction delete = create("any", true, 0, false, filters);
assertEquals(Arrays.asList(filters), delete.getPathConditions());
}
@Test
public void testCreateFileVisitorReturnsDeletingVisitor() {
- DeleteAction delete = createAnyFilter("any", true, 0);
+ DeleteAction delete = createAnyFilter("any", true, 0, false);
+ FileVisitor<Path> visitor = delete.createFileVisitor(delete.getBasePath(), delete.getPathConditions());
+ assertTrue(visitor instanceof DeletingVisitor);
+ }
+
+ @Test
+ public void testCreateFileVisitorTestModeIsActionTestMode() {
+ DeleteAction delete = createAnyFilter("any", true, 0, false);
+ assertFalse(delete.isTestMode());
FileVisitor<Path> visitor = delete.createFileVisitor(delete.getBasePath(), delete.getPathConditions());
assertTrue(visitor instanceof DeletingVisitor);
+ assertFalse(((DeletingVisitor) visitor).isTestMode());
+
+ DeleteAction deleteTestMode = createAnyFilter("any", true, 0, true);
+ assertTrue(deleteTestMode.isTestMode());
+ FileVisitor<Path> testVisitor = deleteTestMode.createFileVisitor(delete.getBasePath(),
+ delete.getPathConditions());
+ assertTrue(testVisitor instanceof DeletingVisitor);
+ assertTrue(((DeletingVisitor) testVisitor).isTestMode());
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/11e9a27e/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitorTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitorTest.java
index d4053d1..2b3eb0c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitorTest.java
@@ -40,8 +40,9 @@ public class DeletingVisitorTest {
static class DeletingVisitorHelper extends DeletingVisitor {
List<Path> deleted = new ArrayList<Path>();
- public DeletingVisitorHelper(final Path basePath, final List<? extends PathCondition> pathFilters) {
- super(basePath, pathFilters);
+ public DeletingVisitorHelper(final Path basePath, final List<? extends PathCondition> pathFilters,
+ final boolean testMode) {
+ super(basePath, pathFilters, testMode);
}
@Override
@@ -54,7 +55,7 @@ public class DeletingVisitorTest {
public void testAcceptedFilesAreDeleted() throws IOException {
Path base = Paths.get("/a/b/c");
final FixedCondition ACCEPT_ALL = new FixedCondition(true);
- DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, Arrays.asList(ACCEPT_ALL));
+ DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, Arrays.asList(ACCEPT_ALL), false);
Path any = Paths.get("/a/b/c/any");
visitor.visitFile(any, null);
@@ -65,7 +66,7 @@ public class DeletingVisitorTest {
public void testRejectedFilesAreNotDeleted() throws IOException {
Path base = Paths.get("/a/b/c");
final FixedCondition REJECT_ALL = new FixedCondition(false);
- DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, Arrays.asList(REJECT_ALL));
+ DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, Arrays.asList(REJECT_ALL), false);
Path any = Paths.get("/a/b/c/any");
visitor.visitFile(any, null);
@@ -78,7 +79,7 @@ public class DeletingVisitorTest {
final FixedCondition ACCEPT_ALL = new FixedCondition(true);
final FixedCondition REJECT_ALL = new FixedCondition(false);
List<? extends PathCondition> filters = Arrays.asList(ACCEPT_ALL, ACCEPT_ALL, REJECT_ALL);
- DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, filters);
+ DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, filters, false);
Path any = Paths.get("/a/b/c/any");
visitor.visitFile(any, null);
@@ -90,7 +91,7 @@ public class DeletingVisitorTest {
Path base = Paths.get("/a/b/c");
final FixedCondition ACCEPT_ALL = new FixedCondition(true);
List<? extends PathCondition> filters = Arrays.asList(ACCEPT_ALL, ACCEPT_ALL, ACCEPT_ALL);
- DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, filters);
+ DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, filters, false);
Path any = Paths.get("/a/b/c/any");
visitor.visitFile(any, null);
@@ -98,6 +99,18 @@ public class DeletingVisitorTest {
}
@Test
+ public void testInTestModeFileIsNotDeletedEvenIfAllFiltersAccept() throws IOException {
+ Path base = Paths.get("/a/b/c");
+ final FixedCondition ACCEPT_ALL = new FixedCondition(true);
+ List<? extends PathCondition> filters = Arrays.asList(ACCEPT_ALL, ACCEPT_ALL, ACCEPT_ALL);
+ DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, filters, true);
+
+ Path any = Paths.get("/a/b/c/any");
+ visitor.visitFile(any, null);
+ assertFalse(visitor.deleted.contains(any));
+ }
+
+ @Test
public void testVisitFileRelativizesAgainstBase() throws IOException {
PathCondition filter = new PathCondition() {
@@ -114,7 +127,7 @@ public class DeletingVisitorTest {
}
};
Path base = Paths.get("/a/b/c");
- DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, Arrays.asList(filter));
+ DeletingVisitorHelper visitor = new DeletingVisitorHelper(base, Arrays.asList(filter), false);
Path child = Paths.get("/a/b/c/relative");
visitor.visitFile(child, null);
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/11e9a27e/src/site/xdoc/manual/appenders.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml
index 97ef344..b376cbd 100644
--- a/src/site/xdoc/manual/appenders.xml
+++ b/src/site/xdoc/manual/appenders.xml
@@ -2478,7 +2478,10 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity {
<tt>max</tt> attribute.
The Delete action lets users configure one or more conditions that select the files to delete
relative to a base directory.
+ </p>
+ <p>
Note that it is possible to delete any file, not just rolled over log files, so use this action with care!
+ With the <tt>testMode</tt> parameter you can test your configuration without accidentally deleting the wrong files.
</p>
<table>
<caption align="top">Delete Parameters</caption>
@@ -2507,6 +2510,13 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity {
<td>Whether to follow symbolic links. Default is false.</td>
</tr>
<tr>
+ <td>testMode</td>
+ <td>boolean</td>
+ <td>If true, files are not deleted but instead a message is printed to the <a
+ href="configuration.html#StatusMessages">status logger</a> at INFO level.
+ Use this to do a dry run to test if the configuration works as expected. Default is false.</td>
+ </tr>
+ <tr>
<td>pathSorter</td>
<td>PathSorter</td>
<td>A plugin implementing the