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 15:24:11 UTC
[2/2] logging-log4j2 git commit: LOG4J2-435 added support for nested
conditions, and JUnit tests
LOG4J2-435 added support for nested conditions, and JUnit tests
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/e9875dc6
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/e9875dc6
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/e9875dc6
Branch: refs/heads/LOG4J2-435-delete-on-rollover
Commit: e9875dc684e478331af75f665e4fc8351a9893ce
Parents: 4f0868c
Author: rpopma <rp...@apache.org>
Authored: Sat Nov 28 23:24:24 2015 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sat Nov 28 23:24:24 2015 +0900
----------------------------------------------------------------------
.../rolling/action/IfAccumulatedFileCount.java | 30 ++++-
.../rolling/action/IfAccumulatedFileSize.java | 30 ++++-
.../core/appender/rolling/action/IfAll.java | 33 ++++-
.../appender/rolling/action/IfFileName.java | 42 +++++--
.../appender/rolling/action/IfLastModified.java | 30 ++++-
...lingAppenderDeleteAccumulatedCount1Test.java | 3 +-
...lingAppenderDeleteAccumulatedCount2Test.java | 3 +-
.../RollingAppenderDeleteNestedTest.java | 120 +++++++++++++++++++
.../action/IfAccumulatedFileCountTest.java | 25 ++++
.../action/IfAccumulatedFileSizeTest.java | 36 ++++++
.../appender/rolling/action/IfFileNameTest.java | 52 ++++++++
.../rolling/action/IfLastModifiedTest.java | 36 +++++-
.../log4j-rolling-with-custom-delete-nested.xml | 51 ++++++++
13 files changed, 460 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCount.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCount.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCount.java
index b411d50..6cdcc84 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCount.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCount.java
@@ -18,10 +18,14 @@ package org.apache.logging.log4j.core.appender.rolling.action;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.status.StatusLogger;
@@ -33,17 +37,24 @@ public final class IfAccumulatedFileCount implements PathCondition {
private static final Logger LOGGER = StatusLogger.getLogger();
private final int threshold;
private int count;
+ private final PathCondition[] nestedConditions;
- private IfAccumulatedFileCount(final int thresholdParam) {
+ private IfAccumulatedFileCount(final int thresholdParam, final PathCondition[] nestedConditions) {
if (thresholdParam <= 0) {
throw new IllegalArgumentException("Count must be a positive integer but was " + thresholdParam);
}
this.threshold = thresholdParam;
+ this.nestedConditions = nestedConditions == null ? new PathCondition[0] : Arrays.copyOf(nestedConditions,
+ nestedConditions.length);
}
public int getThresholdCount() {
return threshold;
}
+
+ public List<PathCondition> getNestedConditions() {
+ return Collections.unmodifiableList(Arrays.asList(nestedConditions));
+ }
/*
* (non-Javadoc)
@@ -52,10 +63,13 @@ public final class IfAccumulatedFileCount implements PathCondition {
* java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes)
*/
@Override
- public boolean accept(final Path baseDir, final Path relativePath, final BasicFileAttributes attrs) {
+ public boolean accept(final Path basePath, final Path relativePath, final BasicFileAttributes attrs) {
final boolean result = ++count > threshold;
final String match = result ? ">" : "<=";
LOGGER.trace("IfAccumulatedFileCount: {} count '{}' {} threshold '{}'", relativePath, count, match, threshold);
+ if (result) {
+ return IfAll.accept(nestedConditions, basePath, relativePath, attrs);
+ }
return result;
}
@@ -67,6 +81,7 @@ public final class IfAccumulatedFileCount implements PathCondition {
@Override
public void beforeFileTreeWalk() {
count = 0;
+ IfAll.beforeFileTreeWalk(nestedConditions);
}
/**
@@ -77,15 +92,20 @@ public final class IfAccumulatedFileCount implements PathCondition {
*/
@PluginFactory
public static IfAccumulatedFileCount createFileCountCondition( //
- @PluginAttribute(value = "exceeds", defaultInt = Integer.MAX_VALUE) final int threshold) {
+ // @formatter:off
+ @PluginAttribute(value = "exceeds", defaultInt = Integer.MAX_VALUE) final int threshold,
+ @PluginElement("PathConditions") final PathCondition... nestedConditions) {
+ // @formatter:on
+
if (threshold == Integer.MAX_VALUE) {
LOGGER.error("IfAccumulatedFileCount invalid or missing threshold value.");
}
- return new IfAccumulatedFileCount(threshold);
+ return new IfAccumulatedFileCount(threshold, nestedConditions);
}
@Override
public String toString() {
- return "IfAccumulatedFileCount(exceeds=" + threshold + ")";
+ final String nested = nestedConditions.length == 0 ? "" : " AND " + Arrays.toString(nestedConditions);
+ return "IfAccumulatedFileCount(exceeds=" + threshold + nested + ")";
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSize.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSize.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSize.java
index c1378e6..e7a6bd0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSize.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSize.java
@@ -18,11 +18,15 @@ package org.apache.logging.log4j.core.appender.rolling.action;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.appender.rolling.FileSize;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.status.StatusLogger;
@@ -34,17 +38,24 @@ public final class IfAccumulatedFileSize implements PathCondition {
private static final Logger LOGGER = StatusLogger.getLogger();
private final long thresholdBytes;
private long accumulatedSize;
+ private final PathCondition[] nestedConditions;
- private IfAccumulatedFileSize(final long thresholdSize) {
+ private IfAccumulatedFileSize(final long thresholdSize, final PathCondition[] nestedConditions) {
if (thresholdSize <= 0) {
throw new IllegalArgumentException("Count must be a positive integer but was " + thresholdSize);
}
this.thresholdBytes = thresholdSize;
+ this.nestedConditions = nestedConditions == null ? new PathCondition[0] : Arrays.copyOf(nestedConditions,
+ nestedConditions.length);
}
public long getThresholdBytes() {
return thresholdBytes;
}
+
+ public List<PathCondition> getNestedConditions() {
+ return Collections.unmodifiableList(Arrays.asList(nestedConditions));
+ }
/*
* (non-Javadoc)
@@ -53,12 +64,15 @@ public final class IfAccumulatedFileSize implements PathCondition {
* java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes)
*/
@Override
- public boolean accept(final Path baseDir, final Path relativePath, final BasicFileAttributes attrs) {
+ public boolean accept(final Path basePath, final Path relativePath, final BasicFileAttributes attrs) {
accumulatedSize += attrs.size();
final boolean result = accumulatedSize > thresholdBytes;
final String match = result ? ">" : "<=";
LOGGER.trace("IfAccumulatedFileSize: {} accumulated size '{}' {} thresholdBytes '{}'", relativePath,
accumulatedSize, match, thresholdBytes);
+ if (result) {
+ return IfAll.accept(nestedConditions, basePath, relativePath, attrs);
+ }
return result;
}
@@ -70,6 +84,7 @@ public final class IfAccumulatedFileSize implements PathCondition {
@Override
public void beforeFileTreeWalk() {
accumulatedSize = 0;
+ IfAll.beforeFileTreeWalk(nestedConditions);
}
/**
@@ -80,16 +95,21 @@ public final class IfAccumulatedFileSize implements PathCondition {
*/
@PluginFactory
public static IfAccumulatedFileSize createFileSizeCondition( //
- @PluginAttribute("exceeds") final String size) {
+ // @formatter:off
+ @PluginAttribute("exceeds") final String size,
+ @PluginElement("PathConditions") final PathCondition... nestedConditions) {
+ // @formatter:on
+
if (size == null) {
LOGGER.error("IfAccumulatedFileSize missing mandatory size threshold.");
}
final long threshold = size == null ? Long.MAX_VALUE : FileSize.parse(size, Long.MAX_VALUE);
- return new IfAccumulatedFileSize(threshold);
+ return new IfAccumulatedFileSize(threshold, nestedConditions);
}
@Override
public String toString() {
- return "IfAccumulatedFileSize(exceeds=" + thresholdBytes + ")";
+ final String nested = nestedConditions.length == 0 ? "" : " AND " + Arrays.toString(nestedConditions);
+ return "IfAccumulatedFileSize(exceeds=" + thresholdBytes + nested + ")";
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAll.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAll.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAll.java
index 84a9388..627a082 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAll.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfAll.java
@@ -44,14 +44,31 @@ public final class IfAll implements PathCondition {
/*
* (non-Javadoc)
- * @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#accept(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes)
+ *
+ * @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#accept(java.nio.file.Path,
+ * java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes)
*/
@Override
public boolean accept(final Path baseDir, final Path relativePath, final BasicFileAttributes attrs) {
if (components == null || components.length == 0) {
return false; // unconditional delete not supported
}
- for (final PathCondition component : components) {
+ return accept(components, baseDir, relativePath, attrs);
+ }
+
+ /**
+ * Returns {@code true} if all the specified conditions accept the specified path, {@code false} otherwise.
+ *
+ * @param list the array of conditions to evaluate
+ * @param baseDir the directory from where to start scanning for deletion candidate files
+ * @param relativePath the candidate for deletion. This path is relative to the baseDir.
+ * @param attrs attributes of the candidate path
+ * @return {@code true} if all the specified conditions accept the specified path, {@code false} otherwise
+ * @throws NullPointerException if any of the parameters is {@code null}
+ */
+ public static boolean accept(final PathCondition[] list, final Path baseDir, final Path relativePath,
+ final BasicFileAttributes attrs) {
+ for (final PathCondition component : list) {
if (!component.accept(baseDir, relativePath, attrs)) {
return false;
}
@@ -61,11 +78,21 @@ public final class IfAll implements PathCondition {
/*
* (non-Javadoc)
+ *
* @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#beforeFileTreeWalk()
*/
@Override
public void beforeFileTreeWalk() {
- for (PathCondition condition : components) {
+ beforeFileTreeWalk(components);
+ }
+
+ /**
+ * Calls {@link #beforeFileTreeWalk()} on all of the specified nested conditions.
+ *
+ * @param nestedConditions the conditions to call {@link #beforeFileTreeWalk()} on
+ */
+ public static void beforeFileTreeWalk(PathCondition[] nestedConditions) {
+ for (PathCondition condition : nestedConditions) {
condition.beforeFileTreeWalk();
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileName.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileName.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileName.java
index a746a20..9bed9f7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileName.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileName.java
@@ -21,11 +21,15 @@ import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.regex.Pattern;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.status.StatusLogger;
@@ -34,14 +38,15 @@ import org.apache.logging.log4j.status.StatusLogger;
* expression. If both a regular expression and a glob pattern are specified the glob pattern is used and the regular
* expression is ignored.
* <p>
- * The regular expression is a pattern as defined by the {@link Pattern} class. A glob is a simplified pattern expression
- * described in {@link FileSystem#getPathMatcher(String)}.
+ * The regular expression is a pattern as defined by the {@link Pattern} class. A glob is a simplified pattern
+ * expression described in {@link FileSystem#getPathMatcher(String)}.
*/
@Plugin(name = "IfFileName", category = "Core", printObject = true)
public final class IfFileName implements PathCondition {
private static final Logger LOGGER = StatusLogger.getLogger();
private final PathMatcher pathMatcher;
private final String syntaxAndPattern;
+ private final PathCondition[] nestedConditions;
/**
* Constructs a FileNameFilter filter. If both a regular expression and a glob pattern are specified the glob
@@ -49,14 +54,17 @@ public final class IfFileName implements PathCondition {
*
* @param glob the baseDir-relative path pattern of the files to delete (may contain '*' and '?' wildcarts)
* @param regex the regular expression that matches the baseDir-relative path of the file(s) to delete
+ * @param nestedConditions nested conditions to evaluate if this condition accepts a path
*/
- private IfFileName(final String glob, final String regex) {
+ private IfFileName(final String glob, final String regex, final PathCondition[] nestedConditions) {
if (regex == null && glob == null) {
throw new IllegalArgumentException("Specify either a path glob or a regular expression. "
+ "Both cannot be null.");
}
- syntaxAndPattern = createSyntaxAndPatternString(glob, regex);
- pathMatcher = FileSystems.getDefault().getPathMatcher(syntaxAndPattern);
+ this.syntaxAndPattern = createSyntaxAndPatternString(glob, regex);
+ this.pathMatcher = FileSystems.getDefault().getPathMatcher(syntaxAndPattern);
+ this.nestedConditions = nestedConditions == null ? new PathCondition[0] : Arrays.copyOf(nestedConditions,
+ nestedConditions.length);
}
static String createSyntaxAndPatternString(final String glob, final String regex) {
@@ -77,10 +85,16 @@ public final class IfFileName implements PathCondition {
public String getSyntaxAndPattern() {
return syntaxAndPattern;
}
+
+ public List<PathCondition> getNestedConditions() {
+ return Collections.unmodifiableList(Arrays.asList(nestedConditions));
+ }
/*
* (non-Javadoc)
- * @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#accept(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes)
+ *
+ * @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#accept(java.nio.file.Path,
+ * java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes)
*/
@Override
public boolean accept(final Path basePath, final Path relativePath, final BasicFileAttributes attrs) {
@@ -88,15 +102,20 @@ public final class IfFileName implements PathCondition {
final String match = result ? " " : " not ";
LOGGER.trace("IfFileName: '{}' does{}match relative path '{}'", syntaxAndPattern, match, relativePath);
+ if (result) {
+ return IfAll.accept(nestedConditions, basePath, relativePath, attrs);
+ }
return result;
}
/*
* (non-Javadoc)
+ *
* @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#beforeFileTreeWalk()
*/
@Override
public void beforeFileTreeWalk() {
+ IfAll.beforeFileTreeWalk(nestedConditions);
}
/**
@@ -107,18 +126,23 @@ public final class IfFileName implements PathCondition {
*
* @param glob the baseDir-relative path pattern of the files to delete (may contain '*' and '?' wildcarts)
* @param regex the regular expression that matches the baseDir-relative path of the file(s) to delete
+ * @param nestedConditions nested conditions to evaluate if this condition accepts a path
* @return A IfFileName condition.
* @see FileSystem#getPathMatcher(String)
*/
@PluginFactory
public static IfFileName createNameCondition( //
+ // @formatter:off
@PluginAttribute("glob") final String glob, //
- @PluginAttribute("regex") final String regex) {
- return new IfFileName(glob, regex);
+ @PluginAttribute("regex") final String regex, //
+ @PluginElement("PathConditions") final PathCondition... nestedConditions) {
+ // @formatter:on
+ return new IfFileName(glob, regex, nestedConditions);
}
@Override
public String toString() {
- return "IfFileName(" + syntaxAndPattern + ")";
+ final String nested = nestedConditions.length == 0 ? "" : " AND " + Arrays.toString(nestedConditions);
+ return "IfFileName(" + syntaxAndPattern + nested + ")";
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java
index 064f702..a67dba9 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java
@@ -19,11 +19,15 @@ package org.apache.logging.log4j.core.appender.rolling.action;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Objects;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.util.Clock;
import org.apache.logging.log4j.core.util.ClockFactory;
@@ -38,27 +42,37 @@ public final class IfLastModified implements PathCondition {
private static final Clock CLOCK = ClockFactory.getClock();
private final Duration age;
+ private final PathCondition[] nestedConditions;
- private IfLastModified(final Duration age) {
+ private IfLastModified(final Duration age, final PathCondition[] nestedConditions) {
this.age = Objects.requireNonNull(age, "age");
+ this.nestedConditions = nestedConditions == null ? new PathCondition[0] : Arrays.copyOf(nestedConditions,
+ nestedConditions.length);
}
public Duration getAge() {
return age;
}
+
+ public List<PathCondition> getNestedConditions() {
+ return Collections.unmodifiableList(Arrays.asList(nestedConditions));
+ }
/*
* (non-Javadoc)
* @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#accept(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes)
*/
@Override
- public boolean accept(final Path baseDir, final Path relativePath, final BasicFileAttributes attrs) {
+ public boolean accept(final Path basePath, final Path relativePath, final BasicFileAttributes attrs) {
final FileTime fileTime = attrs.lastModifiedTime();
final long millis = fileTime.toMillis();
final long ageMillis = CLOCK.currentTimeMillis() - millis;
final boolean result = ageMillis >= age.toMillis();
final String match = result ? ">=" : "<";
LOGGER.trace("IfLastModified: {} ageMillis '{}' {} '{}'", relativePath, ageMillis, match, age);
+ if (result) {
+ return IfAll.accept(nestedConditions, basePath, relativePath, attrs);
+ }
return result;
}
@@ -68,22 +82,28 @@ public final class IfLastModified implements PathCondition {
*/
@Override
public void beforeFileTreeWalk() {
+ IfAll.beforeFileTreeWalk(nestedConditions);
}
/**
* Create an IfLastModified condition.
*
* @param age The path age that is accepted by this condition. Must be a valid Duration.
+ * @param nestedConditions nested conditions to evaluate if this condition accepts a path
* @return An IfLastModified condition.
*/
@PluginFactory
public static IfLastModified createAgeCondition( //
- @PluginAttribute("age") final Duration age) {
- return new IfLastModified(age);
+ // @formatter:off
+ @PluginAttribute("age") final Duration age, //
+ @PluginElement("PathConditions") final PathCondition... nestedConditions) {
+ // @formatter:on
+ return new IfLastModified(age, nestedConditions);
}
@Override
public String toString() {
- return "IfLastModified(age=" + age + ")";
+ final String nested = nestedConditions.length == 0 ? "" : " AND " + Arrays.toString(nestedConditions);
+ return "IfLastModified(age=" + age + nested + ")";
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java
index 2206b63..b2d6fa7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java
@@ -39,7 +39,8 @@ import org.junit.rules.RuleChain;
import static org.junit.Assert.*;
/**
- *
+ * Tests that sibling conditions are invoked in configured order.
+ * This does not work for properties configurations. Use nested conditions instead.
*/
public class RollingAppenderDeleteAccumulatedCount1Test {
private static final String CONFIG = "log4j-rolling-with-custom-delete-accum-count1.xml";
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java
index 9f85eba..d63491e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java
@@ -39,7 +39,8 @@ import org.junit.rules.RuleChain;
import static org.junit.Assert.*;
/**
- *
+ * Tests that sibling conditions are invoked in configured order.
+ * This does not work for properties configurations. Use nested conditions instead.
*/
public class RollingAppenderDeleteAccumulatedCount2Test {
private static final String CONFIG = "log4j-rolling-with-custom-delete-accum-count2.xml";
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java
new file mode 100644
index 0000000..59fc3c9
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.logging.log4j.core.appender.rolling;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.util.datetime.FixedDateFormat;
+import org.apache.logging.log4j.core.util.datetime.FixedDateFormat.FixedFormat;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+import org.junit.rules.RuleChain;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class RollingAppenderDeleteNestedTest {
+ private static final String CONFIG = "log4j-rolling-with-custom-delete-nested.xml";
+ private static final String DIR = "target/rolling-with-delete-nested/test";
+
+ private final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
+
+ @Rule
+ public RuleChain chain = RuleChain.outerRule(new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ deleteDir();
+ }
+ }).around(ctx);
+
+ @Test
+ public void testAppender() throws Exception {
+ Path p1 = writeTextTo(DIR + "/my-1.log"); // glob="test-*.log"
+ Path p2 = writeTextTo(DIR + "/my-2.log");
+ Path p3 = writeTextTo(DIR + "/my-3.log");
+ Path p4 = writeTextTo(DIR + "/my-4.log");
+ Path p5 = writeTextTo(DIR + "/my-5.log");
+
+ final Logger logger = ctx.getLogger();
+ for (int i = 0; i < 10; ++i) {
+ updateLastModified(p1, p2, p3, p4, p5); // make my-*.log files most recent
+
+ // 30 chars per message: each message triggers a rollover
+ logger.debug("This is a test message number " + i); // 30 chars:
+ }
+ Thread.sleep(100); // Allow time for rollover to complete
+
+ final File dir = new File(DIR);
+ assertTrue("Dir " + DIR + " should exist", dir.exists());
+ assertTrue("Dir " + DIR + " should contain files", dir.listFiles().length > 0);
+
+ final File[] files = dir.listFiles();
+ for (File file : files) {
+ System.out.println(file + " (" + file.length() + "B) "
+ + FixedDateFormat.create(FixedFormat.ABSOLUTE).format(file.lastModified()));
+ }
+
+ List<String> expected = Arrays.asList("test-7.log", "test-8.log", "test-9.log", "test-10.log",
+ "my-1.log", "my-2.log", "my-3.log", "my-4.log", "my-5.log");
+ assertEquals(Arrays.toString(files), expected.size() - 1, files.length);
+ for (File file : files) {
+ assertTrue("unexpected file " + file, expected.contains(file.getName()));
+ }
+ }
+
+ private void updateLastModified(Path... paths) throws IOException {
+ for (Path path : paths) {
+ Files.setLastModifiedTime(path, FileTime.fromMillis(System.currentTimeMillis() + 100));
+ }
+ }
+
+ private Path writeTextTo(String location) throws IOException {
+ Path path = Paths.get(location);
+ Files.createDirectories(path.getParent());
+ try (BufferedWriter buffy = Files.newBufferedWriter(path, Charset.defaultCharset())) {
+ buffy.write("some text");
+ buffy.newLine();
+ buffy.flush();
+ }
+ return path;
+ }
+
+ private static void deleteDir() {
+ final File dir = new File(DIR);
+ if (dir.exists()) {
+ final File[] files = dir.listFiles();
+ for (final File file : files) {
+ file.delete();
+ }
+ dir.delete();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCountTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCountTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCountTest.java
index 343aa09..bb2a0d0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCountTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileCountTest.java
@@ -47,4 +47,29 @@ public class IfAccumulatedFileCountTest {
}
}
+ @Test
+ public void testAcceptCallsNestedConditionsOnlyIfPathAccepted() {
+ final CountingCondition counter = new CountingCondition(true);
+ IfAccumulatedFileCount condition = IfAccumulatedFileCount.createFileCountCondition(3, counter);
+
+ for (int i = 1; i < 10; i++) {
+ if (i <= 3) {
+ assertFalse("i=" + i, condition.accept(null, null, null));
+ assertEquals(0, counter.getAcceptCount());
+ } else {
+ assertTrue(condition.accept(null, null, null));
+ assertEquals(i - 3, counter.getAcceptCount());
+ }
+ }
+ }
+
+ @Test
+ public void testBeforeTreeWalk() {
+ final CountingCondition counter = new CountingCondition(true);
+ final IfAccumulatedFileCount filter = IfAccumulatedFileCount.createFileCountCondition(30, counter, counter,
+ counter);
+ filter.beforeFileTreeWalk();
+ assertEquals(3, counter.getBeforeFileTreeWalkCount());
+ }
+
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
index d756a95..d22df55 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAccumulatedFileSizeTest.java
@@ -91,4 +91,40 @@ public class IfAccumulatedFileSizeTest {
}
}
+ @Test
+ public void testAcceptCallsNestedConditionsOnlyIfPathAccepted() {
+ final CountingCondition counter = new CountingCondition(true);
+ IfAccumulatedFileSize condition = IfAccumulatedFileSize.createFileSizeCondition("2KB", counter);
+ DummyFileAttributes attribs = new DummyFileAttributes();
+
+ long quarter = condition.getThresholdBytes() / 4;
+ attribs.size = quarter;
+ assertFalse(condition.accept(null, null, attribs));
+ assertEquals(0, counter.getAcceptCount());
+
+ assertFalse(condition.accept(null, null, attribs));
+ assertEquals(0, counter.getAcceptCount());
+
+ assertFalse(condition.accept(null, null, attribs));
+ assertEquals(0, counter.getAcceptCount());
+
+ assertFalse(condition.accept(null, null, attribs));
+ assertEquals(0, counter.getAcceptCount());
+
+ assertTrue(condition.accept(null, null, attribs));
+ assertEquals(1, counter.getAcceptCount());
+
+ assertTrue(condition.accept(null, null, attribs));
+ assertEquals(2, counter.getAcceptCount());
+ }
+
+ @Test
+ public void testBeforeTreeWalk() {
+ final CountingCondition counter = new CountingCondition(true);
+ final IfAccumulatedFileSize filter = IfAccumulatedFileSize.createFileSizeCondition("2GB", counter, counter,
+ counter);
+ filter.beforeFileTreeWalk();
+ assertEquals(3, counter.getBeforeFileTreeWalkCount());
+ }
+
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java
index 5b81cfb..2e84aa9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java
@@ -76,4 +76,56 @@ public class IfFileNameTest {
final Path pathMatchingRegex = Paths.get("regex");
assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
}
+
+ @Test
+ public void testAcceptCallsNestedConditionsOnlyIfPathAccepted1() {
+ final CountingCondition counter = new CountingCondition(true);
+ final IfFileName regexFilter = IfFileName.createNameCondition(null, "regex", counter);
+ final Path pathMatchingRegex = Paths.get("regex");
+
+ assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+ assertEquals(1, counter.getAcceptCount());
+ assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+ assertEquals(2, counter.getAcceptCount());
+ assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+ assertEquals(3, counter.getAcceptCount());
+
+ final Path noMatch = Paths.get("nomatch");
+ assertFalse(regexFilter.accept(null, noMatch, null));
+ assertEquals(3, counter.getAcceptCount()); // no increase
+ assertFalse(regexFilter.accept(null, noMatch, null));
+ assertEquals(3, counter.getAcceptCount());
+ assertFalse(regexFilter.accept(null, noMatch, null));
+ assertEquals(3, counter.getAcceptCount());
+ }
+
+ @Test
+ public void testAcceptCallsNestedConditionsOnlyIfPathAccepted2() {
+ final CountingCondition counter = new CountingCondition(true);
+ final IfFileName globFilter = IfFileName.createNameCondition("glob", null, counter);
+ final Path pathMatchingGlob = Paths.get("glob");
+
+ assertTrue(globFilter.accept(null, pathMatchingGlob, null));
+ assertEquals(1, counter.getAcceptCount());
+ assertTrue(globFilter.accept(null, pathMatchingGlob, null));
+ assertEquals(2, counter.getAcceptCount());
+ assertTrue(globFilter.accept(null, pathMatchingGlob, null));
+ assertEquals(3, counter.getAcceptCount());
+
+ final Path noMatch = Paths.get("nomatch");
+ assertFalse(globFilter.accept(null, noMatch, null));
+ assertEquals(3, counter.getAcceptCount()); // no increase
+ assertFalse(globFilter.accept(null, noMatch, null));
+ assertEquals(3, counter.getAcceptCount());
+ assertFalse(globFilter.accept(null, noMatch, null));
+ assertEquals(3, counter.getAcceptCount());
+ }
+
+ @Test
+ public void testBeforeTreeWalk() {
+ final CountingCondition counter = new CountingCondition(true);
+ final IfFileName pathFilter = IfFileName.createNameCondition("path", null, counter, counter, counter);
+ pathFilter.beforeFileTreeWalk();
+ assertEquals(3, counter.getBeforeFileTreeWalkCount());
+ }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
index b23ca68..d279660 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java
@@ -19,8 +19,6 @@ package org.apache.logging.log4j.core.appender.rolling.action;
import java.nio.file.attribute.FileTime;
-import org.apache.logging.log4j.core.appender.rolling.action.Duration;
-import org.apache.logging.log4j.core.appender.rolling.action.IfLastModified;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -62,4 +60,38 @@ public class IfLastModifiedTest {
attrs.lastModified = FileTime.fromMillis(System.currentTimeMillis() - age);
assertFalse(filter.accept(null, null, attrs));
}
+
+ @Test
+ public void testAcceptCallsNestedConditionsOnlyIfPathAccepted() {
+ final CountingCondition counter = new CountingCondition(true);
+ IfLastModified filter = IfLastModified.createAgeCondition(Duration.parse("PT33S"), counter);
+ DummyFileAttributes attrs = new DummyFileAttributes();
+ final long oldEnough = 33 * 1000 + 5;
+ attrs.lastModified = FileTime.fromMillis(System.currentTimeMillis() - oldEnough);
+
+ assertTrue(filter.accept(null, null, attrs));
+ assertEquals(1, counter.getAcceptCount());
+ assertTrue(filter.accept(null, null, attrs));
+ assertEquals(2, counter.getAcceptCount());
+ assertTrue(filter.accept(null, null, attrs));
+ assertEquals(3, counter.getAcceptCount());
+
+ final long tooYoung = 33 * 1000 - 5;
+ attrs.lastModified = FileTime.fromMillis(System.currentTimeMillis() - tooYoung);
+ assertFalse(filter.accept(null, null, attrs));
+ assertEquals(3, counter.getAcceptCount()); // no increase
+ assertFalse(filter.accept(null, null, attrs));
+ assertEquals(3, counter.getAcceptCount());
+ assertFalse(filter.accept(null, null, attrs));
+ assertEquals(3, counter.getAcceptCount());
+ }
+
+ @Test
+ public void testBeforeTreeWalk() {
+ final CountingCondition counter = new CountingCondition(true);
+ final IfLastModified filter = IfLastModified.createAgeCondition(Duration.parse("PT33S"), counter, counter,
+ counter);
+ filter.beforeFileTreeWalk();
+ assertEquals(3, counter.getBeforeFileTreeWalkCount());
+ }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e9875dc6/log4j-core/src/test/resources/log4j-rolling-with-custom-delete-nested.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-with-custom-delete-nested.xml b/log4j-core/src/test/resources/log4j-rolling-with-custom-delete-nested.xml
new file mode 100644
index 0000000..cde178d
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-with-custom-delete-nested.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<Configuration status="TRACE" name="RollingWithCustomDeleteAccumulatedSizeTest">
+ <Properties>
+ <Property name="base">target/rolling-with-delete-nested/</Property>
+ </Properties>
+
+ <Appenders>
+ <RollingFile name="RollingFile" fileName="${base}/rollingtest.log"
+ filePattern="${base}/test/test-%i.log">
+ <PatternLayout>
+ <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
+ </PatternLayout>
+ <Policies>
+ <SizeBasedTriggeringPolicy size="30" />
+ </Policies>
+ <DefaultRolloverStrategy max="100" stopCustomActionsOnError="true">
+ <Delete basePath="${base}/test">
+ <!-- delete only test-*.logs, keep the 3 most recent ones -->
+ <IfFileName glob="test-*.log">
+ <!-- nesting guarantees that count not incremented if name does not match -->
+ <IfAccumulatedFileCount exceeds="3" />
+ </IfFileName>
+ </Delete>
+ </DefaultRolloverStrategy>
+ </RollingFile>
+ </Appenders>
+
+ <Loggers>
+ <Root level="trace">
+ <AppenderRef ref="RollingFile" />
+ </Root>
+ </Loggers>
+
+</Configuration>
\ No newline at end of file