You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2017/06/27 06:48:41 UTC
logging-log4j2 git commit: [LOG4J2-1766] Temporary compress directory
during rollover (#88).
Repository: logging-log4j2
Updated Branches:
refs/heads/master 3f4536859 -> e7b638929
[LOG4J2-1766] Temporary compress directory during rollover (#88).
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/e7b63892
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/e7b63892
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/e7b63892
Branch: refs/heads/master
Commit: e7b638929cc71ed626b52263ac6a04388b1e7dbd
Parents: 3f45368
Author: Pierrick HYMBERT <pi...@gmail.com>
Authored: Mon Jun 26 23:48:37 2017 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Mon Jun 26 23:48:37 2017 -0700
----------------------------------------------------------------------
.../core/appender/RollingFileAppender.java | 12 +-
.../RollingRandomAccessFileAppender.java | 6 +-
.../rolling/DefaultRolloverStrategy.java | 279 ++++++++++++++++---
.../rolling/DirectWriteRolloverStrategy.java | 210 ++++++++++++--
...irectWriteTempCompressedFilePatternTest.java | 98 +++++++
...ngAppenderTempCompressedFilePatternTest.java | 151 ++++++++++
...log4j-rolling-direct-tmp-compress-folder.xml | 52 ++++
.../resources/log4j-rolling-gz-tmp-compress.xml | 62 +++++
src/changes/changes.xml | 3 +
src/site/xdoc/manual/appenders.xml | 10 +
10 files changed, 827 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
index 1072259..bcba88f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
@@ -125,11 +125,15 @@ public final class RollingFileAppender extends AbstractOutputStreamAppender<Roll
if (strategy == null) {
if (fileName != null) {
- strategy = DefaultRolloverStrategy.createStrategy(null, null, null,
- String.valueOf(Deflater.DEFAULT_COMPRESSION), null, true, getConfiguration());
+ strategy = DefaultRolloverStrategy.newBuilder()
+ .withCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION))
+ .withConfig(getConfiguration())
+ .build();
} else {
- strategy = DirectWriteRolloverStrategy.createStrategy(null,
- String.valueOf(Deflater.DEFAULT_COMPRESSION), null, true, getConfiguration());
+ strategy = DirectWriteRolloverStrategy.newBuilder()
+ .withCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION))
+ .withConfig(getConfiguration())
+ .build();
}
} else if (fileName == null && !(strategy instanceof DirectFileRolloverStrategy)) {
LOGGER.error("RollingFileAppender '{}': When no file name is provided a DirectFilenameRolloverStrategy must be configured");
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
index 89c2008..6148dec 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
@@ -111,8 +111,10 @@ public final class RollingRandomAccessFileAppender extends AbstractOutputStreamA
}
if (strategy == null) {
- strategy = DefaultRolloverStrategy.createStrategy(null, null, null,
- String.valueOf(Deflater.DEFAULT_COMPRESSION), null, true, getConfiguration());
+ strategy = DefaultRolloverStrategy.newBuilder()
+ .withCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION))
+ .withConfig(getConfiguration())
+ .build();
}
final Layout<? extends Serializable> layout = getOrCreateLayout();
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
index 4141195..865eeb4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
@@ -37,6 +37,8 @@ import org.apache.logging.log4j.core.appender.rolling.action.PosixViewAttributeA
import org.apache.logging.log4j.core.config.Configuration;
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.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
@@ -83,6 +85,195 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
private static final int DEFAULT_WINDOW_SIZE = 7;
/**
+ * Builds DefaultRolloverStrategy instances.
+ */
+ public static class Builder implements org.apache.logging.log4j.core.util.Builder<DefaultRolloverStrategy> {
+ @PluginBuilderAttribute("max")
+ private String max;
+
+ @PluginBuilderAttribute("min")
+ private String min;
+
+ @PluginBuilderAttribute("fileIndex")
+ private String fileIndex;
+
+ @PluginBuilderAttribute("compressionLevel")
+ private String compressionLevelStr;
+
+ @PluginElement("Actions")
+ private Action[] customActions;
+
+ @PluginBuilderAttribute(value = "stopCustomActionsOnError")
+ private boolean stopCustomActionsOnError = true;
+
+ @PluginBuilderAttribute(value = "tempCompressedFilePattern")
+ private String tempCompressedFilePattern;
+
+ @PluginConfiguration
+ private Configuration config;
+
+ @Override
+ public DefaultRolloverStrategy build() {
+ int minIndex;
+ int maxIndex;
+ boolean useMax;
+
+ if (fileIndex != null && fileIndex.equalsIgnoreCase("nomax")) {
+ minIndex = Integer.MIN_VALUE;
+ maxIndex = Integer.MAX_VALUE;
+ useMax = false;
+ } else {
+ useMax = fileIndex == null ? true : fileIndex.equalsIgnoreCase("max");
+ minIndex = MIN_WINDOW_SIZE;
+ if (min != null) {
+ minIndex = Integer.parseInt(min);
+ if (minIndex < 1) {
+ LOGGER.error("Minimum window size too small. Limited to " + MIN_WINDOW_SIZE);
+ minIndex = MIN_WINDOW_SIZE;
+ }
+ }
+ maxIndex = DEFAULT_WINDOW_SIZE;
+ if (max != null) {
+ maxIndex = Integer.parseInt(max);
+ if (maxIndex < minIndex) {
+ maxIndex = minIndex < DEFAULT_WINDOW_SIZE ? DEFAULT_WINDOW_SIZE : minIndex;
+ LOGGER.error("Maximum window size must be greater than the minimum windows size. Set to " + maxIndex);
+ }
+ }
+ }
+ final int compressionLevel = Integers.parseInt(compressionLevelStr, Deflater.DEFAULT_COMPRESSION);
+ return new DefaultRolloverStrategy(minIndex, maxIndex, useMax, compressionLevel, config.getStrSubstitutor(),
+ customActions, stopCustomActionsOnError, tempCompressedFilePattern);
+ }
+
+ public String getMax() {
+ return max;
+ }
+
+ /**
+ * Defines the maximum number of files to keep.
+ *
+ * @param max The maximum number of files to keep.
+ * @return This builder for chaining convenience
+ */
+ public Builder withMax(String max) {
+ this.max = max;
+ return this;
+ }
+
+ public String getMin() {
+ return min;
+ }
+
+ /**
+ * Defines the minimum number of files to keep.
+ *
+ * @param min The minimum number of files to keep.
+ * @return This builder for chaining convenience
+ */
+ public Builder withMin(String min) {
+ this.min = min;
+ return this;
+ }
+
+ public String getFileIndex() {
+ return fileIndex;
+ }
+
+ /**
+ * Defines the file index for rolling strategy.
+ *
+ * @param fileIndex If set to "max" (the default), files with a higher index will be newer than files with a smaller
+ * index. If set to "min", file renaming and the counter will follow the Fixed Window strategy.
+ * @return This builder for chaining convenience
+ */
+ public Builder withFileIndex(String fileIndex) {
+ this.fileIndex = fileIndex;
+ return this;
+ }
+
+ public String getCompressionLevelStr() {
+ return compressionLevelStr;
+ }
+
+ /**
+ * Defines compression level.
+ *
+ * @param compressionLevelStr The compression level, 0 (less) through 9 (more); applies only to ZIP files.
+ * @return This builder for chaining convenience
+ */
+ public Builder withCompressionLevelStr(String compressionLevelStr) {
+ this.compressionLevelStr = compressionLevelStr;
+ return this;
+ }
+
+ public Action[] getCustomActions() {
+ return customActions;
+ }
+
+ /**
+ * Defines custom actions.
+ *
+ * @param customActions custom actions to perform asynchronously after rollover
+ * @return This builder for chaining convenience
+ */
+ public Builder withCustomActions(Action[] customActions) {
+ this.customActions = customActions;
+ return this;
+ }
+
+ public boolean isStopCustomActionsOnError() {
+ return stopCustomActionsOnError;
+ }
+
+ /**
+ * Defines whether to stop executing asynchronous actions if an error occurs.
+ *
+ * @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
+ * @return This builder for chaining convenience
+ */
+ public Builder withStopCustomActionsOnError(boolean stopCustomActionsOnError) {
+ this.stopCustomActionsOnError = stopCustomActionsOnError;
+ return this;
+ }
+
+ public String getTempCompressedFilePattern() {
+ return tempCompressedFilePattern;
+ }
+
+ /**
+ * Defines temporary compression file pattern.
+ *
+ * @param tempCompressedFilePattern File pattern of the working file pattern used during compression, if null no temporary file are used
+ * @return This builder for chaining convenience
+ */
+ public Builder withTempCompressedFilePattern(String tempCompressedFilePattern) {
+ this.tempCompressedFilePattern = tempCompressedFilePattern;
+ return this;
+ }
+
+ public Configuration getConfig() {
+ return config;
+ }
+
+ /**
+ * Defines configuration.
+ *
+ * @param config The Configuration.
+ * @return This builder for chaining convenience
+ */
+ public Builder withConfig(Configuration config) {
+ this.config = config;
+ return this;
+ }
+ }
+
+ @PluginBuilderFactory
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ /**
* Creates the DefaultRolloverStrategy.
*
* @param max The maximum number of files to keep.
@@ -94,8 +285,10 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
* @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
* @param config The Configuration.
* @return A DefaultRolloverStrategy.
+ * @deprecated Since 2.9 Usage of Builder API is preferable
*/
@PluginFactory
+ @Deprecated
public static DefaultRolloverStrategy createStrategy(
// @formatter:off
@PluginAttribute("max") final String max,
@@ -106,37 +299,16 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
@PluginAttribute(value = "stopCustomActionsOnError", defaultBoolean = true)
final boolean stopCustomActionsOnError,
@PluginConfiguration final Configuration config) {
+ return DefaultRolloverStrategy.newBuilder()
+ .withMin(min)
+ .withMax(max)
+ .withFileIndex(fileIndex)
+ .withCompressionLevelStr(compressionLevelStr)
+ .withCustomActions(customActions)
+ .withStopCustomActionsOnError(stopCustomActionsOnError)
+ .withConfig(config)
+ .build();
// @formatter:on
- int minIndex;
- int maxIndex;
- boolean useMax;
-
- if (fileIndex != null && fileIndex.equalsIgnoreCase("nomax")) {
- minIndex = Integer.MIN_VALUE;
- maxIndex = Integer.MAX_VALUE;
- useMax = false;
- } else {
- useMax = fileIndex == null ? true : fileIndex.equalsIgnoreCase("max");
- minIndex = MIN_WINDOW_SIZE;
- if (min != null) {
- minIndex = Integer.parseInt(min);
- if (minIndex < 1) {
- LOGGER.error("Minimum window size too small. Limited to " + MIN_WINDOW_SIZE);
- minIndex = MIN_WINDOW_SIZE;
- }
- }
- maxIndex = DEFAULT_WINDOW_SIZE;
- if (max != null) {
- maxIndex = Integer.parseInt(max);
- if (maxIndex < minIndex) {
- maxIndex = minIndex < DEFAULT_WINDOW_SIZE ? DEFAULT_WINDOW_SIZE : minIndex;
- LOGGER.error("Maximum window size must be greater than the minimum windows size. Set to " + maxIndex);
- }
- }
- }
- final int compressionLevel = Integers.parseInt(compressionLevelStr, Deflater.DEFAULT_COMPRESSION);
- return new DefaultRolloverStrategy(minIndex, maxIndex, useMax, compressionLevel, config.getStrSubstitutor(),
- customActions, stopCustomActionsOnError);
}
/**
@@ -152,6 +324,7 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
private final int compressionLevel;
private final List<Action> customActions;
private final boolean stopCustomActionsOnError;
+ private final PatternProcessor tempCompressedFilePattern;
/**
* Constructs a new instance.
@@ -160,10 +333,29 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
* @param maxIndex The maximum index.
* @param customActions custom actions to perform asynchronously after rollover
* @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
+ * @deprecated Since 2.9 Added tempCompressedFilePatternString parameter
*/
+ @Deprecated
protected DefaultRolloverStrategy(final int minIndex, final int maxIndex, final boolean useMax,
final int compressionLevel, final StrSubstitutor strSubstitutor, final Action[] customActions,
final boolean stopCustomActionsOnError) {
+ this(minIndex, maxIndex, useMax, compressionLevel,
+ strSubstitutor, customActions, stopCustomActionsOnError, null);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param minIndex The minimum index.
+ * @param maxIndex The maximum index.
+ * @param customActions custom actions to perform asynchronously after rollover
+ * @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
+ * @param tempCompressedFilePatternString File pattern of the working file
+ * used during compression, if null no temporary file are used
+ */
+ protected DefaultRolloverStrategy(final int minIndex, final int maxIndex, final boolean useMax,
+ final int compressionLevel, final StrSubstitutor strSubstitutor, final Action[] customActions,
+ final boolean stopCustomActionsOnError, final String tempCompressedFilePatternString) {
super(strSubstitutor);
this.minIndex = minIndex;
this.maxIndex = maxIndex;
@@ -171,6 +363,8 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
this.compressionLevel = compressionLevel;
this.stopCustomActionsOnError = stopCustomActionsOnError;
this.customActions = customActions == null ? Collections.<Action> emptyList() : Arrays.asList(customActions);
+ this.tempCompressedFilePattern =
+ tempCompressedFilePatternString != null ? new PatternProcessor(tempCompressedFilePatternString) : null;
}
public int getCompressionLevel() {
@@ -197,6 +391,10 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
return useMax;
}
+ public PatternProcessor getTempCompressedFilePattern() {
+ return tempCompressedFilePattern;
+ }
+
private int purge(final int lowIndex, final int highIndex, final RollingFileManager manager) {
return useMax ? purgeAscending(lowIndex, highIndex, manager) : purgeDescending(lowIndex, highIndex, manager);
}
@@ -344,9 +542,26 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
FileExtension fileExtension = manager.getFileExtension();
if (fileExtension != null) {
+ final File renameToFile = new File(renameTo);
renameTo = renameTo.substring(0, renameTo.length() - fileExtension.length());
- compressAction = fileExtension.createCompressAction(renameTo, compressedName,
- true, compressionLevel);
+ if (tempCompressedFilePattern != null) {
+ buf.delete(0, buf.length());
+ tempCompressedFilePattern.formatFileName(strSubstitutor, buf, fileIndex);
+ String tmpCompressedName = buf.toString();
+ final File tmpCompressedNameFile = new File(tmpCompressedName);
+ if (tmpCompressedNameFile.getParentFile() != null) {
+ tmpCompressedNameFile.getParentFile().mkdirs();
+ }
+ compressAction = new CompositeAction(
+ Arrays.asList(fileExtension.createCompressAction(renameTo, tmpCompressedName,
+ true, compressionLevel),
+ new FileRenameAction(tmpCompressedNameFile,
+ renameToFile, true)),
+ true);
+ } else {
+ compressAction = fileExtension.createCompressAction(renameTo, compressedName,
+ true, compressionLevel);
+ }
}
if (currentFileName.equals(renameTo)) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
index 6ce58d8..06dd5d3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
@@ -16,6 +16,7 @@
*/
package org.apache.logging.log4j.core.appender.rolling;
+import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -29,11 +30,14 @@ import java.util.zip.Deflater;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.appender.rolling.action.Action;
import org.apache.logging.log4j.core.appender.rolling.action.CompositeAction;
+import org.apache.logging.log4j.core.appender.rolling.action.FileRenameAction;
import org.apache.logging.log4j.core.appender.rolling.action.PathCondition;
import org.apache.logging.log4j.core.appender.rolling.action.PosixViewAttributeAction;
import org.apache.logging.log4j.core.config.Configuration;
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.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
@@ -56,6 +60,141 @@ import org.apache.logging.log4j.core.util.Integers;
public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implements DirectFileRolloverStrategy {
private static final int DEFAULT_MAX_FILES = 7;
+
+ /**
+ * Builds DirectWriteRolloverStrategy instances.
+ */
+ public static class Builder implements org.apache.logging.log4j.core.util.Builder<DirectWriteRolloverStrategy> {
+ @PluginBuilderAttribute("maxFiles")
+ private String maxFiles;
+
+ @PluginBuilderAttribute("compressionLevel")
+ private String compressionLevelStr;
+
+ @PluginElement("Actions")
+ private Action[] customActions;
+
+ @PluginBuilderAttribute(value = "stopCustomActionsOnError")
+ private boolean stopCustomActionsOnError = true;
+
+ @PluginBuilderAttribute(value = "tempCompressedFilePattern")
+ private String tempCompressedFilePattern;
+
+ @PluginConfiguration
+ private Configuration config;
+
+ @Override
+ public DirectWriteRolloverStrategy build() {
+ int maxIndex = Integer.MAX_VALUE;
+ if (maxFiles != null) {
+ maxIndex = Integer.parseInt(maxFiles);
+ if (maxIndex < 0) {
+ maxIndex = Integer.MAX_VALUE;
+ } else if (maxIndex < 2) {
+ LOGGER.error("Maximum files too small. Limited to " + DEFAULT_MAX_FILES);
+ maxIndex = DEFAULT_MAX_FILES;
+ }
+ }
+ final int compressionLevel = Integers.parseInt(compressionLevelStr, Deflater.DEFAULT_COMPRESSION);
+ return new DirectWriteRolloverStrategy(maxIndex, compressionLevel, config.getStrSubstitutor(),
+ customActions, stopCustomActionsOnError, tempCompressedFilePattern);
+ }
+
+ public String getMaxFiles() {
+ return maxFiles;
+ }
+
+ /**
+ * Defines the maximum number of files to keep.
+ *
+ * @param maxFiles The maximum number of files that match the date portion of the pattern to keep.
+ * @return This builder for chaining convenience
+ */
+ public Builder withMaxFiles(String maxFiles) {
+ this.maxFiles = maxFiles;
+ return this;
+ }
+
+ public String getCompressionLevelStr() {
+ return compressionLevelStr;
+ }
+
+ /**
+ * Defines compression level.
+ *
+ * @param compressionLevelStr The compression level, 0 (less) through 9 (more); applies only to ZIP files.
+ * @return This builder for chaining convenience
+ */
+ public Builder withCompressionLevelStr(String compressionLevelStr) {
+ this.compressionLevelStr = compressionLevelStr;
+ return this;
+ }
+
+ public Action[] getCustomActions() {
+ return customActions;
+ }
+
+ /**
+ * Defines custom actions.
+ *
+ * @param customActions custom actions to perform asynchronously after rollover
+ * @return This builder for chaining convenience
+ */
+ public Builder withCustomActions(Action[] customActions) {
+ this.customActions = customActions;
+ return this;
+ }
+
+ public boolean isStopCustomActionsOnError() {
+ return stopCustomActionsOnError;
+ }
+
+ /**
+ * Defines whether to stop executing asynchronous actions if an error occurs.
+ *
+ * @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
+ * @return This builder for chaining convenience
+ */
+ public Builder withStopCustomActionsOnError(boolean stopCustomActionsOnError) {
+ this.stopCustomActionsOnError = stopCustomActionsOnError;
+ return this;
+ }
+
+ public String getTempCompressedFilePattern() {
+ return tempCompressedFilePattern;
+ }
+
+ /**
+ * Defines temporary compression file pattern.
+ *
+ * @param tempCompressedFilePattern File pattern of the working file pattern used during compression, if null no temporary file are used
+ * @return This builder for chaining convenience
+ */
+ public Builder withTempCompressedFilePattern(String tempCompressedFilePattern) {
+ this.tempCompressedFilePattern = tempCompressedFilePattern;
+ return this;
+ }
+
+ public Configuration getConfig() {
+ return config;
+ }
+
+ /**
+ * Defines configuration.
+ *
+ * @param config The Configuration.
+ * @return This builder for chaining convenience
+ */
+ public Builder withConfig(Configuration config) {
+ this.config = config;
+ return this;
+ }
+ }
+
+ @PluginBuilderFactory
+ public static Builder newBuilder() {
+ return new Builder();
+ }
/**
* Creates the DirectWriteRolloverStrategy.
@@ -65,8 +204,10 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
* @param customActions custom actions to perform asynchronously after rollover
* @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
* @param config The Configuration.
- * @return A DefaultRolloverStrategy.
+ * @return A DirectWriteRolloverStrategy.
+ * @deprecated Since 2.9 Usage of Builder API is preferable
*/
+ @Deprecated
@PluginFactory
public static DirectWriteRolloverStrategy createStrategy(
// @formatter:off
@@ -76,20 +217,13 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
@PluginAttribute(value = "stopCustomActionsOnError", defaultBoolean = true)
final boolean stopCustomActionsOnError,
@PluginConfiguration final Configuration config) {
+ return newBuilder().withMaxFiles(maxFiles)
+ .withCompressionLevelStr(compressionLevelStr)
+ .withCustomActions(customActions)
+ .withStopCustomActionsOnError(stopCustomActionsOnError)
+ .withConfig(config)
+ .build();
// @formatter:on
- int maxIndex = Integer.MAX_VALUE;
- if (maxFiles != null) {
- maxIndex = Integer.parseInt(maxFiles);
- if (maxIndex < 0) {
- maxIndex = Integer.MAX_VALUE;
- } else if (maxIndex < 2) {
- LOGGER.error("Maximum files too small. Limited to " + DEFAULT_MAX_FILES);
- maxIndex = DEFAULT_MAX_FILES;
- }
- }
- final int compressionLevel = Integers.parseInt(compressionLevelStr, Deflater.DEFAULT_COMPRESSION);
- return new DirectWriteRolloverStrategy(maxIndex, compressionLevel, config.getStrSubstitutor(),
- customActions, stopCustomActionsOnError);
}
/**
@@ -101,22 +235,42 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
private final boolean stopCustomActionsOnError;
private volatile String currentFileName;
private int nextIndex = -1;
+ private final PatternProcessor tempCompressedFilePattern;
/**
* Constructs a new instance.
*
- * @param maxFiles The minimum index.
+ * @param maxFiles The maximum number of files that match the date portion of the pattern to keep.
* @param customActions custom actions to perform asynchronously after rollover
* @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
+ * @deprecated Since 2.9 Added tempCompressedFilePatternString parameter
*/
+ @Deprecated
protected DirectWriteRolloverStrategy(final int maxFiles, final int compressionLevel,
final StrSubstitutor strSubstitutor, final Action[] customActions,
final boolean stopCustomActionsOnError) {
+ this(maxFiles, compressionLevel, strSubstitutor, customActions, stopCustomActionsOnError, null);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param maxFiles The maximum number of files that match the date portion of the pattern to keep.
+ * @param customActions custom actions to perform asynchronously after rollover
+ * @param stopCustomActionsOnError whether to stop executing asynchronous actions if an error occurs
+ * @param tempCompressedFilePatternString File pattern of the working file
+ * used during compression, if null no temporary file are used
+ */
+ protected DirectWriteRolloverStrategy(final int maxFiles, final int compressionLevel,
+ final StrSubstitutor strSubstitutor, final Action[] customActions,
+ final boolean stopCustomActionsOnError, final String tempCompressedFilePatternString) {
super(strSubstitutor);
this.maxFiles = maxFiles;
this.compressionLevel = compressionLevel;
this.stopCustomActionsOnError = stopCustomActionsOnError;
this.customActions = customActions == null ? Collections.<Action> emptyList() : Arrays.asList(customActions);
+ this.tempCompressedFilePattern =
+ tempCompressedFilePatternString != null ? new PatternProcessor(tempCompressedFilePatternString) : null;
}
public int getCompressionLevel() {
@@ -135,6 +289,10 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
return stopCustomActionsOnError;
}
+ public PatternProcessor getTempCompressedFilePattern() {
+ return tempCompressedFilePattern;
+ }
+
private int purge(final RollingFileManager manager) {
SortedMap<Integer, Path> eligibleFiles = getEligibleFiles(manager);
LOGGER.debug("Found {} eligible files, max is {}", eligibleFiles.size(), maxFiles);
@@ -190,9 +348,25 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
nextIndex = fileIndex + 1;
FileExtension fileExtension = manager.getFileExtension();
if (fileExtension != null) {
- compressedName += fileExtension.getExtension();
- compressAction = fileExtension.createCompressAction(sourceName, compressedName,
- true, compressionLevel);
+ compressedName += fileExtension.getExtension();
+ if (tempCompressedFilePattern != null) {
+ StringBuilder buf = new StringBuilder();
+ tempCompressedFilePattern.formatFileName(strSubstitutor, buf, fileIndex);
+ String tmpCompressedName = buf.toString();
+ final File tmpCompressedNameFile = new File(tmpCompressedName);
+ if (tmpCompressedNameFile.getParentFile() != null) {
+ tmpCompressedNameFile.getParentFile().mkdirs();
+ }
+ compressAction = new CompositeAction(
+ Arrays.asList(fileExtension.createCompressAction(sourceName, tmpCompressedName,
+ true, compressionLevel),
+ new FileRenameAction(tmpCompressedNameFile,
+ new File(compressedName), true)),
+ true);
+ } else {
+ compressAction = fileExtension.createCompressAction(sourceName, compressedName,
+ true, compressionLevel);
+ }
}
if (manager.isPosixSupported()) {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java
new file mode 100644
index 0000000..8b6430b
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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 static org.apache.logging.log4j.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.hamcrest.Matchers.endsWith;
+import static org.hamcrest.Matchers.hasItemInArray;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+
+/**
+ * LOG4J2-1766.
+ */
+public class RollingAppenderDirectWriteTempCompressedFilePatternTest {
+
+ private static final String CONFIG = "log4j-rolling-direct-tmp-compress-folder.xml";
+
+ private static final String DIR = "target/rolling-direct";
+
+ public static LoggerContextRule loggerContextRule = LoggerContextRule
+ .createShutdownTimeoutLoggerContextRule(CONFIG);
+
+ @Rule
+ public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR);
+
+ private Logger logger;
+
+ @Before
+ public void setUp() throws Exception {
+ this.logger = loggerContextRule.getLogger(RollingAppenderDirectWriteTest.class.getName());
+ }
+
+ @Test
+ public void testAppender() throws Exception {
+ final File dir = new File(DIR);
+ dir.mkdirs();
+ final WatchService watcher = FileSystems.getDefault().newWatchService();
+ WatchKey key = dir.toPath().register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
+
+ for (int i = 0; i < 100; ++i) {
+ logger.debug("This is test message number " + i);
+ }
+ Thread.sleep(50);
+ assertTrue("Directory not created", dir.exists() && dir.listFiles().length > 0);
+ final File[] files = dir.listFiles();
+ assertNotNull(files);
+ assertThat(files, hasItemInArray(that(hasName(that(endsWith(".gz"))))));
+
+ int temporaryFilesCreated = 0;
+ int compressedFiles = 0;
+ key = watcher.take();
+
+ for (final WatchEvent<?> event : key.pollEvents()) {
+ final WatchEvent.Kind<?> kind = event.kind();
+ final WatchEvent<Path> ev = (WatchEvent<Path>) event;
+ final Path filename = ev.context();
+ if (filename.toString().endsWith(".tmp")) {
+ temporaryFilesCreated++;
+ }
+ if (filename.toString().endsWith(".gz")) {
+ compressedFiles++;
+ }
+ }
+ assertTrue("No temporary file created during compression", temporaryFilesCreated > 0);
+ assertTrue("Temporarys file created not equals to compressed files", compressedFiles == temporaryFilesCreated);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java
new file mode 100644
index 0000000..a62d494
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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 static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.compress.compressors.CompressorException;
+import org.apache.commons.compress.compressors.CompressorStreamFactory;
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+
+/**
+ * LOG4J2-1766.
+ */
+public class RollingAppenderTempCompressedFilePatternTest {
+
+ private static final String CONFIG = "log4j-rolling-gz-tmp-compress.xml";
+
+ private static final String DIR = "target/rolling2";
+ private static final String DIR_TMP = "target/rolling-tmp";
+
+ public static LoggerContextRule loggerContextRule = LoggerContextRule
+ .createShutdownTimeoutLoggerContextRule(CONFIG);
+
+ @Rule
+ public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR, DIR_TMP);
+
+ private Logger logger;
+
+ @Before
+ public void setUp() throws Exception {
+ this.logger = loggerContextRule.getLogger(RollingAppenderTempCompressedFilePatternTest.class.getName());
+ }
+
+ @Test
+ public void testAppender() throws Exception {
+ final File dirTmp = new File(DIR_TMP);
+ dirTmp.mkdirs();
+ final WatchService watcher = FileSystems.getDefault().newWatchService();
+ WatchKey key = dirTmp.toPath().register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
+
+ final List<String> messages = new ArrayList<>();
+ for (int i = 0; i < 500; ++i) {
+ final String message = "This is test message number " + i;
+ messages.add(message);
+ logger.debug(message);
+ if (i % 100 == 0) {
+ Thread.sleep(500);
+ }
+ }
+ if (!loggerContextRule.getLoggerContext().stop(30, TimeUnit.SECONDS)) {
+ System.err.println("Could not stop cleanly " + loggerContextRule + " for " + this);
+ }
+ final File dir = new File(DIR);
+ assertTrue("Directory not created", dir.exists());
+ final File[] files = dir.listFiles();
+ assertNotNull(files);
+ int gzippedFiles = 0;
+ for (final File file : files) {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ InputStream in = null;
+ final FileExtension ext = FileExtension.lookupForFile(file.getName());
+ try {
+ try (FileInputStream fis = new FileInputStream(file)) {
+ if (ext != null) {
+ gzippedFiles++;
+ try {
+ in = new CompressorStreamFactory().createCompressorInputStream(ext.name().toLowerCase(),
+ fis);
+ } catch (final CompressorException ce) {
+ ce.printStackTrace();
+ fail("Error creating intput stream from " + file.toString() + ": " + ce.getMessage());
+ }
+ } else {
+ in = new FileInputStream(file);
+ }
+ assertNotNull("No input stream for " + file.getName(), in);
+ try {
+ IOUtils.copy(in, baos);
+ } catch (final Exception ex) {
+ ex.printStackTrace();
+ fail("Unable to decompress " + file.getAbsolutePath());
+ }
+ }
+ } finally {
+ Closer.close(in);
+ }
+ final String text = new String(baos.toByteArray(), Charset.defaultCharset());
+ final String[] lines = text.split("[\\r\\n]+");
+ for (final String line : lines) {
+ messages.remove(line);
+ }
+ }
+ assertTrue("Log messages lost : " + messages.size(), messages.isEmpty());
+ assertTrue("Files not rolled : " + files.length, files.length > 2);
+ assertTrue("Files gzipped not rolled : " + gzippedFiles, gzippedFiles > 0);
+
+ int temporaryFilesCreated = 0;
+ key = watcher.take();
+
+ for (final WatchEvent<?> event : key.pollEvents()) {
+ final WatchEvent.Kind<?> kind = event.kind();
+ final WatchEvent<Path> ev = (WatchEvent<Path>) event;
+ final Path filename = ev.context();
+ if (filename.toString().endsWith(".tmp")) {
+ temporaryFilesCreated++;
+ }
+ }
+ assertTrue("No temporary file created during compression", temporaryFilesCreated > 0);
+ assertTrue(
+ "Temporarys file created not equals to compressed files " + temporaryFilesCreated + "/" + gzippedFiles,
+ gzippedFiles == temporaryFilesCreated);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/test/resources/log4j-rolling-direct-tmp-compress-folder.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-direct-tmp-compress-folder.xml b/log4j-core/src/test/resources/log4j-rolling-direct-tmp-compress-folder.xml
new file mode 100644
index 0000000..cac266b
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-direct-tmp-compress-folder.xml
@@ -0,0 +1,52 @@
+<?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="WARN" name="XMLConfigTest">
+ <Properties>
+ <Property name="logDir">target/rolling-direct</Property>
+ </Properties>
+ <ThresholdFilter level="debug"/>
+
+ <Appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m%n"/>
+ </Console>
+ <RollingFile name="RollingFile" filePattern="${logDir}/test1-%d{MM-dd-yy-HH-mm}-%i.log.gz">
+ <PatternLayout>
+ <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+ </PatternLayout>
+ <Policies>
+ <TimeBasedTriggeringPolicy />
+ <SizeBasedTriggeringPolicy size="500" />
+ </Policies>
+ <DirectWriteRolloverStrategy
+ tempCompressedFilePattern="${logDir}/test1-%d{MM-dd-yy-HH-mm}-%i.log.gz.tmp"/>
+ </RollingFile>
+ </Appenders>
+
+ <Loggers>
+ <Logger name="org.apache.logging.log4j.core.appender.rolling" level="debug" additivity="false">
+ <AppenderRef ref="RollingFile"/>
+ </Logger>>
+
+ <Root level="error">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+
+</Configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/log4j-core/src/test/resources/log4j-rolling-gz-tmp-compress.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-gz-tmp-compress.xml b/log4j-core/src/test/resources/log4j-rolling-gz-tmp-compress.xml
new file mode 100644
index 0000000..5caf196
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-gz-tmp-compress.xml
@@ -0,0 +1,62 @@
+<?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="WARN" name="XMLConfigTest">
+ <Properties>
+ <Property name="filename">target/rolling2/rollingtest.log</Property>
+ </Properties>
+ <ThresholdFilter level="debug"/>
+
+ <Appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m%n"/>
+ </Console>
+ <RollingFile name="RollingFile" fileName="${filename}"
+ filePattern="target/rolling2/test1-$${date:MM-dd-yyyy}-%i.log.gz"
+ createOnDemand="true">
+ <PatternLayout>
+ <Pattern>%m%n</Pattern>
+ </PatternLayout>
+ <SizeBasedTriggeringPolicy size="500" />
+ <DefaultRolloverStrategy
+ fileIndex="nomax"
+ tempCompressedFilePattern="target/rolling-tmp/test1-$${date:MM-dd-yyyy}-%i.log.gz.tmp"/>
+ </RollingFile>
+ <List name="List">
+ <ThresholdFilter level="error"/>
+ </List>
+ </Appenders>
+
+ <Loggers>
+ <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
+ <ThreadContextMapFilter>
+ <KeyValuePair key="test" value="123"/>
+ </ThreadContextMapFilter>
+ <AppenderRef ref="STDOUT"/>
+ </Logger>>
+
+ <Logger name="org.apache.logging.log4j.core.appender.rolling" level="debug" additivity="false">
+ <AppenderRef ref="RollingFile"/>
+ </Logger>>
+
+ <Root level="error">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+
+</Configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 91b1101..d272730 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,9 @@
- "remove" - Removed
-->
<release version="2.9.0" date="2017-MM-DD" description="GA Release 2.9.0">
+ <action issue="LOG4J2-1766" dev="ggregory" type="add" due-to="Pierrick HYMBERT">
+ Temporary compress directory during rollover (#88).
+ </action>
<action issue="LOG4J2-1950" dev="ggregory" type="update" due-to="Pierrick HYMBERT">
Fix docker build with jdk9 requirements (#84).
</action>
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e7b63892/src/site/xdoc/manual/appenders.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml
index ba1bf7d..339d35c 100644
--- a/src/site/xdoc/manual/appenders.xml
+++ b/src/site/xdoc/manual/appenders.xml
@@ -2930,6 +2930,11 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity {
Only implemented for ZIP files.
</td>
</tr>
+ <tr>
+ <td>tempCompressedFilePattern</td>
+ <td>String</td>
+ <td>The pattern of the file name of the archived log file during compression.</td>
+ </tr>
</table>
<a name="DirectWriteRolloverStrategy"/>
<h5>DirectWrite Rollover Strategy</h5>
@@ -2968,6 +2973,11 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity {
Only implemented for ZIP files.
</td>
</tr>
+ <tr>
+ <td>tempCompressedFilePattern</td>
+ <td>String</td>
+ <td>The pattern of the file name of the archived log file during compression.</td>
+ </tr>
</table>
<p>
Below is a sample configuration that uses a RollingFileAppender with both the time and size based