logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Sicker <boa...@gmail.com>
Subject Fwd: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.
Date Sat, 20 Aug 2016 00:43:04 GMT
You have a bunch of null checks in the plugin builder that can be automated
with @Required on the field. However, that only applies in the dynamic
plugin build process, not when you manually make a method call to the
factory method or to the builder; that would require a bit of work to the
validation system (something I've considered doing in the past but never
figured out a good way to refactor it).

---------- Forwarded message ----------
From: <ggregory@apache.org>
Date: 19 August 2016 at 19:27
Subject: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender
should be able to create files on-demand.
To: commits@logging.apache.org


Repository: logging-log4j2
Updated Branches:
  refs/heads/master 6a2330166 -> 93f55f378


[LOG4J2-1504] RollingFileAppender should be able to create files
on-demand.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/
commit/a82794f0
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/a82794f0
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a82794f0

Branch: refs/heads/master
Commit: a82794f06e3bc095ef0bca41b98c5d1ea915de76
Parents: 60649ef
Author: Gary Gregory <ggregory@apache.org>
Authored: Fri Aug 19 17:27:26 2016 -0700
Committer: Gary Gregory <ggregory@apache.org>
Committed: Fri Aug 19 17:27:26 2016 -0700

----------------------------------------------------------------------
 .../log4j/core/appender/FileManager.java        |  12 +-
 .../core/appender/OutputStreamManager.java      |  18 +-
 .../core/appender/RollingFileAppender.java      | 372 ++++++++++++-------
 .../appender/rolling/RollingFileManager.java    |  50 ++-
 .../rolling/OnStartupTriggeringPolicyTest.java  |  10 +-
 .../rolling/RollingAppenderSizeTest.java        |  43 ++-
 .../rolling/RollingFileAppenderAccessTest.java  |  61 +--
 .../test/resources/log4j-rolling-7z-lazy.xml    |  59 +++
 .../test/resources/log4j-rolling-bzip2-lazy.xml |  60 +++
 .../resources/log4j-rolling-deflate-lazy.xml    |  60 +++
 .../test/resources/log4j-rolling-gz-lazy.xml    |  59 +++
 .../resources/log4j-rolling-pack200-lazy.xml    |  60 +++
 .../test/resources/log4j-rolling-xz-lazy.xml    |  60 +++
 .../test/resources/log4j-rolling-zip-lazy.xml   |  60 +++
 src/changes/changes.xml                         |   5 +-
 15 files changed, 791 insertions(+), 198 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/log4j-core/src/main/java/org/apache/logging/log4j/
core/appender/FileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/FileManager.java
index c71bd95..b8a559a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/FileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/FileManager.java
@@ -45,6 +45,9 @@ public class FileManager extends OutputStreamManager {
     private final String advertiseURI;
     private final int bufferSize;

+    /**
+     * @deprecated
+     */
     @Deprecated
     protected FileManager(final String fileName, final OutputStream os,
final boolean append, final boolean locking,
             final String advertiseURI, final Layout<? extends
Serializable> layout, final int bufferSize,
@@ -53,7 +56,7 @@ public class FileManager extends OutputStreamManager {
     }

     /**
-     * @deprecated
+     * @deprecated
      * @since 2.6
      */
     @Deprecated
@@ -72,10 +75,10 @@ public class FileManager extends OutputStreamManager {
      * @throws IOException
      * @since 2.7
      */
-    protected FileManager(final String fileName, final boolean append,
final boolean locking, final boolean lazyCreate,
+    protected FileManager(final String fileName, final OutputStream os,
final boolean append, final boolean locking, final boolean lazyCreate,
             final String advertiseURI, final Layout<? extends
Serializable> layout, final boolean writeHeader,
             final ByteBuffer buffer) throws IOException {
-        super(fileName, lazyCreate, layout, writeHeader, buffer);
+        super(os, fileName, lazyCreate, layout, writeHeader, buffer);
         this.isAppend = append;
         this.isLazyCreate = lazyCreate;
         this.isLocking = locking;
@@ -253,7 +256,8 @@ public class FileManager extends OutputStreamManager {
             try {
                 final int actualSize = data.bufferedIO ? data.bufferSize :
Constants.ENCODER_BYTE_BUFFER_SIZE;
                 final ByteBuffer buffer = ByteBuffer.wrap(new
byte[actualSize]);
-                return new FileManager(name, data.append, data.locking,
data.lazyCreate, data.advertiseURI, data.layout,
+                final FileOutputStream fos = data.lazyCreate ? null : new
FileOutputStream(file, data.append);
+                return new FileManager(name, fos, data.append,
data.locking, data.lazyCreate, data.advertiseURI, data.layout,
                         writeHeader, buffer);
             } catch (final IOException ex) {
                 LOGGER.error("FileManager (" + name + ") " + ex, ex);

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/
OutputStreamManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/OutputStreamManager.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/appender/OutputStreamManager.java
index e707bea..d895dd5 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/OutputStreamManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/OutputStreamManager.java
@@ -43,12 +43,6 @@ public class OutputStreamManager extends AbstractManager
implements ByteBufferDe
     }

     /**
-     *
-     * @param os
-     * @param streamName
-     * @param layout
-     * @param writeHeader
-     * @param byteBuffer
      * @since 2.6
      * @deprecated
      */
@@ -72,17 +66,21 @@ public class OutputStreamManager extends
AbstractManager implements ByteBufferDe
     }

     /**
-     * @param byteBuffer
      * @throws IOException
      * @since 2.7
      */
-    protected OutputStreamManager(final String streamName, final boolean
lazyCreate, final Layout<? extends Serializable> layout,
-            final boolean writeHeader, final ByteBuffer byteBuffer)
+    protected OutputStreamManager(OutputStream os, final String
streamName, final boolean lazyCreate,
+            final Layout<? extends Serializable> layout, final boolean
writeHeader, final ByteBuffer byteBuffer)
             throws IOException {
         super(streamName);
+        if (lazyCreate && os != null) {
+            LOGGER.error(
+                    "Invalid OutputStreamManager configuration for '{}':
You cannot both set the OutputStream and request on-demand.",
+                    streamName);
+        }
         this.layout = layout;
         this.byteBuffer = Objects.requireNonNull(byteBuffer, "byteBuffer");
-        this.os = lazyCreate ? null : createOutputStream();
+        this.os = os;
         if (writeHeader && layout != null) {
             final byte[] header = layout.getHeader();
             if (header != null) {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/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 01ef50d..dc830e3 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
@@ -31,9 +31,12 @@ import org.apache.logging.log4j.core.appender.rolling.
TriggeringPolicy;
 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;
+import org.apache.logging.log4j.core.config.plugins.validation.
constraints.Required;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.net.Advertiser;
 import org.apache.logging.log4j.core.util.Booleans;
@@ -45,6 +48,215 @@ import org.apache.logging.log4j.core.util.Integers;
 @Plugin(name = "RollingFile", category = "Core", elementType = "appender",
printObject = true)
 public final class RollingFileAppender extends
AbstractOutputStreamAppender<RollingFileManager> {

+    /**
+     * Builds FileAppender instances.
+     *
+     * @param <B>
+     *            This builder class
+     */
+    public static class Builder<B extends Builder<B>> extends
AbstractOutputStreamAppender.Builder<B>
+            implements
org.apache.logging.log4j.core.util.Builder<RollingFileAppender>
{
+
+        @PluginBuilderAttribute
+        @Required
+        private String fileName;
+
+        @PluginBuilderAttribute
+        @Required
+        private String filePattern;
+
+        @PluginBuilderAttribute
+        private boolean append = true;
+
+        @PluginBuilderAttribute
+        private boolean locking;
+
+        @PluginElement("Policy")
+        @Required
+        private TriggeringPolicy policy;
+
+        @PluginElement("Strategy")
+        private RolloverStrategy strategy;
+
+        @PluginBuilderAttribute
+        private boolean bufferedIo = true;
+
+        @PluginBuilderAttribute
+        private int bufferSize = DEFAULT_BUFFER_SIZE;
+
+        @PluginBuilderAttribute
+        private boolean advertise;
+
+        @PluginBuilderAttribute
+        private String advertiseUri;
+
+        @PluginBuilderAttribute
+        private boolean lazyCreate;
+
+        @PluginConfiguration
+        private Configuration config;
+
+        @Override
+        public RollingFileAppender build() {
+            // Even though some variables may be annotated with @Required,
we must still perform validation here for
+            // call sites that build builders programmatically.
+            if (getName() == null) {
+                LOGGER.error("RollingFileAppender '{}': No name
provided.", getName());
+                return null;
+            }
+
+            if (!bufferedIo && bufferSize > 0) {
+                LOGGER.warn("RollingFileAppender '{}': The bufferSize is
set to {} but bufferedIO is not true", getName(), bufferSize);
+            }
+
+            if (fileName == null) {
+                LOGGER.error("RollingFileAppender '{}': No file name
provided.", getName());
+                return null;
+            }
+
+            if (filePattern == null) {
+                LOGGER.error("RollingFileAppender '{}': No file name
pattern provided.", getName());
+                return null;
+            }
+
+            if (policy == null) {
+                LOGGER.error("RollingFileAppender '{}': No
TriggeringPolicy provided.", getName());
+                return null;
+            }
+
+            if (strategy == null) {
+                strategy = DefaultRolloverStrategy.createStrategy(null,
null, null,
+                        String.valueOf(Deflater.DEFAULT_COMPRESSION),
null, true, config);
+            }
+
+            if (strategy == null) {
+                strategy = DefaultRolloverStrategy.createStrategy(null,
null, null,
+                        String.valueOf(Deflater.DEFAULT_COMPRESSION),
null, true, config);
+            }
+
+            final RollingFileManager manager =
RollingFileManager.getFileManager(fileName,
filePattern, append,
+                    bufferedIo, policy, strategy, advertiseUri,
getLayout(), bufferSize, isImmediateFlush(),
+                    lazyCreate);
+            if (manager == null) {
+                return null;
+            }
+
+            manager.initialize();
+
+            return new RollingFileAppender(getName(), getLayout(),
getFilter(), manager, fileName, filePattern,
+                    isIgnoreExceptions(), isImmediateFlush(), advertise ?
config.getAdvertiser() : null);
+        }
+
+        public String getAdvertiseUri() {
+            return advertiseUri;
+        }
+
+        public int getBufferSize() {
+            return bufferSize;
+        }
+
+        public Configuration getConfig() {
+            return config;
+        }
+
+        public String getFileName() {
+            return fileName;
+        }
+
+        public boolean isAdvertise() {
+            return advertise;
+        }
+
+        public boolean isAppend() {
+            return append;
+        }
+
+        public boolean isBufferedIo() {
+            return bufferedIo;
+        }
+
+        public boolean isLazyCreate() {
+            return lazyCreate;
+        }
+
+        public boolean isLocking() {
+            return locking;
+        }
+
+        public B withAdvertise(final boolean advertise) {
+            this.advertise = advertise;
+            return asBuilder();
+        }
+
+        public B withAdvertiseUri(final String advertiseUri) {
+            this.advertiseUri = advertiseUri;
+            return asBuilder();
+        }
+
+        public B withAppend(final boolean append) {
+            this.append = append;
+            return asBuilder();
+        }
+
+        public B withBufferedIo(final boolean bufferedIo) {
+            this.bufferedIo = bufferedIo;
+            return asBuilder();
+        }
+
+        public B withBufferSize(final int bufferSize) {
+            this.bufferSize = bufferSize;
+            return asBuilder();
+        }
+
+        public B withConfig(final Configuration config) {
+            this.config = config;
+            return asBuilder();
+        }
+
+        public B withFileName(final String fileName) {
+            this.fileName = fileName;
+            return asBuilder();
+        }
+
+        public B withLazyCreate(final boolean lazyCreate) {
+            this.lazyCreate = lazyCreate;
+            return asBuilder();
+        }
+
+        public B withLocking(final boolean locking) {
+            this.locking = locking;
+            return asBuilder();
+        }
+
+        public String getFilePattern() {
+            return filePattern;
+        }
+
+        public TriggeringPolicy getPolicy() {
+            return policy;
+        }
+
+        public RolloverStrategy getStrategy() {
+            return strategy;
+        }
+
+        public B withFilePattern(String filePattern) {
+            this.filePattern = filePattern;
+            return asBuilder();
+        }
+
+        public B withPolicy(TriggeringPolicy policy) {
+            this.policy = policy;
+            return asBuilder();
+        }
+
+        public B withStrategy(RolloverStrategy strategy) {
+            this.strategy = strategy;
+            return asBuilder();
+        }
+
+    }
+
     private static final int DEFAULT_BUFFER_SIZE = 8192;

     private final String fileName;
@@ -128,9 +340,10 @@ public final class RollingFileAppender extends
AbstractOutputStreamAppender<Roll
      * @param ignore If {@code "true"} (default) exceptions encountered
when appending events are logged; otherwise
      *               they are propagated to the caller.
      * @param advertise "true" if the appender configuration should be
advertised, "false" otherwise.
-     * @param advertiseURI The advertised URI which can be used to
retrieve the file contents.
+     * @param advertiseUri The advertised URI which can be used to
retrieve the file contents.
      * @param config The Configuration.
      * @return A RollingFileAppender.
+     * @deprecated Use {@link #newBuilder()}.
      */
     @Deprecated
     public static RollingFileAppender createAppender(
@@ -148,142 +361,35 @@ public final class RollingFileAppender extends
AbstractOutputStreamAppender<Roll
             final Filter filter,
             final String ignore,
             final String advertise,
-            final String advertiseURI,
+            final String advertiseUri,
             final Configuration config) {
             // @formatter:on
-
-        final boolean isAppend = Booleans.parseBoolean(append, true);
-        final boolean ignoreExceptions = Booleans.parseBoolean(ignore,
true);
-        final boolean isBuffered = Booleans.parseBoolean(bufferedIO, true);
-        final boolean isFlush = Booleans.parseBoolean(immediateFlush,
true);
-        final boolean isAdvertise = Boolean.parseBoolean(advertise);
         final int bufferSize = Integers.parseInt(bufferSizeStr,
DEFAULT_BUFFER_SIZE);
-        if (!isBuffered && bufferSize > 0) {
-            LOGGER.warn("The bufferSize is set to {} but bufferedIO is not
true: {}", bufferSize, bufferedIO);
-        }
-        if (name == null) {
-            LOGGER.error("No name provided for FileAppender");
-            return null;
-        }
-
-        if (fileName == null) {
-            LOGGER.error("No filename was provided for FileAppender with
name "  + name);
-            return null;
-        }
-
-        if (filePattern == null) {
-            LOGGER.error("No filename pattern provided for FileAppender
with name "  + name);
-            return null;
-        }
-
-        if (policy == null) {
-            LOGGER.error("A TriggeringPolicy must be provided");
-            return null;
-        }
-
-        if (strategy == null) {
-            strategy = DefaultRolloverStrategy.createStrategy(null, null,
null,
-                    String.valueOf(Deflater.DEFAULT_COMPRESSION), null,
true, config);
-        }
-
-        if (layout == null) {
-            layout = PatternLayout.createDefaultLayout();
-        }
-
-        final RollingFileManager manager =
RollingFileManager.getFileManager(fileName,
filePattern, isAppend,
-            isBuffered, policy, strategy, advertiseURI, layout,
bufferSize, isFlush);
-        if (manager == null) {
-            return null;
-        }
-
-        manager.initialize();
-
-        return new RollingFileAppender(name, layout, filter, manager,
fileName, filePattern,
-                ignoreExceptions, isFlush, isAdvertise ?
config.getAdvertiser() : null);
+        // @formatter:off
+        return newBuilder()
+                .withAdvertise(Boolean.parseBoolean(advertise))
+                .withAdvertiseUri(advertiseUri)
+                .withAppend(Booleans.parseBoolean(append, true))
+                .withBufferedIo(Booleans.parseBoolean(bufferedIO, true))
+                .withBufferSize(bufferSize)
+                .withConfig(config)
+                .withFileName(fileName)
+                .withFilePattern(filePattern)
+                .withFilter(filter)
+                .withIgnoreExceptions(Booleans.parseBoolean(ignore, true))
+                .withImmediateFlush(Booleans.parseBoolean(immediateFlush,
true))
+                .withLayout(layout)
+                .withLazyCreate(false)
+                .withLocking(false)
+                .withName(name)
+                .withPolicy(policy)
+                .withStrategy(strategy)
+                .build();
+        // @formatter:on
     }

-    /**
-     * Creates a RollingFileAppender.
-     * @param fileName The name of the file that is actively written to.
(required).
-     * @param filePattern The pattern of the file name to use on rollover.
(required).
-     * @param append If true, events are appended to the file. If false,
the file
-     * is overwritten when opened. Defaults to "true"
-     * @param name The name of the Appender (required).
-     * @param bufferedIo When true, I/O will be buffered. Defaults to
"true".
-     * @param bufferSize buffer size for buffered IO (default is 8192).
-     * @param immediateFlush When true, events are immediately flushed.
Defaults to "true".
-     * @param policy The triggering policy. (required).
-     * @param strategy The rollover strategy. Defaults to
DefaultRolloverStrategy.
-     * @param layout The layout to use (defaults to the default
PatternLayout).
-     * @param filter The Filter or null.
-     * @param ignoreExceptions If {@code "true"} (default) exceptions
encountered when appending events are logged; otherwise
-     *               they are propagated to the caller.
-     * @param advertise "true" if the appender configuration should be
advertised, "false" otherwise.
-     * @param advertiseURI The advertised URI which can be used to
retrieve the file contents.
-     * @param config The Configuration.
-     * @return A RollingFileAppender.
-     * @since 2.7
-     */
-    @PluginFactory
-    public static RollingFileAppender createAppender(
-            // @formatter:off
-            @PluginAttribute("fileName") final String fileName,
-            @PluginAttribute("filePattern") final String filePattern,
-            @PluginAttribute(value = "append", defaultBoolean = true)
final boolean append,
-            @PluginAttribute("name") final String name,
-            @PluginAttribute(value = "bufferedIO", defaultBoolean = true)
final boolean bufferedIo,
-            @PluginAttribute(value = "bufferSize", defaultInt =
DEFAULT_BUFFER_SIZE) final int bufferSize,
-            @PluginAttribute(value = "immediateFlush" , defaultBoolean =
true) final boolean immediateFlush,
-            @PluginElement("Policy") final TriggeringPolicy policy,
-            @PluginElement("Strategy") RolloverStrategy strategy,
-            @PluginElement("Layout") Layout<? extends Serializable> layout,
-            @PluginElement("Filter") final Filter filter,
-            @PluginAttribute(value = "ignoreExceptions", defaultBoolean =
true) final boolean ignoreExceptions,
-            @PluginAttribute("advertise") final boolean advertise,
-            @PluginAttribute("advertiseURI") final String advertiseURI,
-            @PluginConfiguration final Configuration config) {
-            // @formatter:on
-        if (!bufferedIo && bufferSize > 0) {
-            LOGGER.warn("The bufferSize is set to {} but bufferedIO is not
true: {}", bufferSize, bufferedIo);
-        }
-        if (name == null) {
-            LOGGER.error("No name provided for FileAppender");
-            return null;
-        }
-
-        if (fileName == null) {
-            LOGGER.error("No filename was provided for FileAppender with
name "  + name);
-            return null;
-        }
-
-        if (filePattern == null) {
-            LOGGER.error("No filename pattern provided for FileAppender
with name "  + name);
-            return null;
-        }
-
-        if (policy == null) {
-            LOGGER.error("A TriggeringPolicy must be provided");
-            return null;
-        }
-
-        if (strategy == null) {
-            strategy = DefaultRolloverStrategy.createStrategy(null, null,
null,
-                    String.valueOf(Deflater.DEFAULT_COMPRESSION), null,
true, config);
-        }
-
-        if (layout == null) {
-            layout = PatternLayout.createDefaultLayout();
-        }
-
-        final RollingFileManager manager =
RollingFileManager.getFileManager(fileName,
filePattern, append,
-            bufferedIo, policy, strategy, advertiseURI, layout,
bufferSize, immediateFlush);
-        if (manager == null) {
-            return null;
-        }
-
-        manager.initialize();
-
-        return new RollingFileAppender(name, layout, filter, manager,
fileName, filePattern,
-                ignoreExceptions, immediateFlush, advertise ?
config.getAdvertiser() : null);
+    @PluginBuilderFactory
+    public static <B extends Builder<B>> B newBuilder() {
+        return new Builder<B>().asBuilder();
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/log4j-core/src/main/java/org/apache/logging/log4j/
core/appender/rolling/RollingFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/
org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
index 4fdbf30..5f390f1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/rolling/RollingFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
appender/rolling/RollingFileManager.java
@@ -32,6 +32,7 @@ import org.apache.logging.log4j.core.appender.FileManager;
 import org.apache.logging.log4j.core.appender.ManagerFactory;
 import org.apache.logging.log4j.core.appender.rolling.action.
AbstractAction;
 import org.apache.logging.log4j.core.appender.rolling.action.Action;
+import org.apache.logging.log4j.core.util.Clock;
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.core.util.Log4jThread;

@@ -65,6 +66,7 @@ public class RollingFileManager extends FileManager {
                 writeHeader, ByteBuffer.wrap(new
byte[Constants.ENCODER_BYTE_BUFFER_SIZE]));
     }

+    @Deprecated
     protected RollingFileManager(final String fileName, final String
pattern, final OutputStream os,
             final boolean append, final long size, final long time, final
TriggeringPolicy triggeringPolicy,
             final RolloverStrategy rolloverStrategy, final String
advertiseURI,
@@ -78,6 +80,24 @@ public class RollingFileManager extends FileManager {
         this.patternProcessor.setPrevFileTime(time);
     }

+    /**
+     * @throws IOException
+     * @since 2.7
+     */
+    protected RollingFileManager(final String fileName, final String
pattern, final OutputStream os, final boolean append,
+            final boolean lazyCreate, final long size, final long time,
final TriggeringPolicy triggeringPolicy,
+            final RolloverStrategy rolloverStrategy, final String
advertiseURI,
+            final Layout<? extends Serializable> layout, final boolean
writeHeader, final ByteBuffer buffer)
+            throws IOException {
+        super(fileName, os, append, false, lazyCreate, advertiseURI,
layout, writeHeader, buffer);
+        this.size = size;
+        this.initialTime = time;
+        this.triggeringPolicy = triggeringPolicy;
+        this.rolloverStrategy = rolloverStrategy;
+        this.patternProcessor = new PatternProcessor(pattern);
+        this.patternProcessor.setPrevFileTime(time);
+    }
+
     public void initialize() {
         triggeringPolicy.initialize(this);
     }
@@ -93,15 +113,17 @@ public class RollingFileManager extends FileManager {
      * @param advertiseURI the URI to use when advertising the file
      * @param layout The Layout.
      * @param bufferSize buffer size to use if bufferedIO is true
+     * @param immediateFlush flush on every write or not
+     * @param lazyCreate true if you want to lazy-create the file (a.k.a.
on-demand.)
      * @return A RollingFileManager.
      */
     public static RollingFileManager getFileManager(final String fileName,
final String pattern, final boolean append,
             final boolean bufferedIO, final TriggeringPolicy policy, final
RolloverStrategy strategy,
             final String advertiseURI, final Layout<? extends
Serializable> layout, final int bufferSize,
-            final boolean immediateFlush) {
+            final boolean immediateFlush, final boolean lazyCreate) {

         return (RollingFileManager) getManager(fileName, new
FactoryData(pattern, append,
-            bufferedIO, policy, strategy, advertiseURI, layout,
bufferSize, immediateFlush), factory);
+            bufferedIO, policy, strategy, advertiseURI, layout,
bufferSize, immediateFlush, lazyCreate), factory);
     }

     // override to make visible for unit tests
@@ -325,6 +347,7 @@ public class RollingFileManager extends FileManager {
         private final boolean bufferedIO;
         private final int bufferSize;
         private final boolean immediateFlush;
+        private final boolean lazyCreate;
         private final TriggeringPolicy policy;
         private final RolloverStrategy strategy;
         private final String advertiseURI;
@@ -339,10 +362,12 @@ public class RollingFileManager extends FileManager {
          * @param layout The Layout.
          * @param bufferSize the buffer size
          * @param immediateFlush flush on every write or not
+         * @param lazyCreate true if you want to lazy-create the file
(a.k.a. on-demand.)
          */
         public FactoryData(final String pattern, final boolean append,
final boolean bufferedIO,
                 final TriggeringPolicy policy, final RolloverStrategy
strategy, final String advertiseURI,
-                final Layout<? extends Serializable> layout, final int
bufferSize, final boolean immediateFlush) {
+                final Layout<? extends Serializable> layout, final int
bufferSize, final boolean immediateFlush,
+                final boolean lazyCreate) {
             this.pattern = pattern;
             this.append = append;
             this.bufferedIO = bufferedIO;
@@ -352,6 +377,7 @@ public class RollingFileManager extends FileManager {
             this.advertiseURI = advertiseURI;
             this.layout = layout;
             this.immediateFlush = immediateFlush;
+            this.lazyCreate = lazyCreate;
         }

         public TriggeringPolicy getTriggeringPolicy()
@@ -418,24 +444,24 @@ public class RollingFileManager extends FileManager {
             // LOG4J2-1140: check writeHeader before creating the file
             final boolean writeHeader = !data.append || !file.exists();
             try {
-                file.createNewFile();
+                final boolean created = data.lazyCreate ? false :
file.createNewFile();
+                LOGGER.trace("New file '{}' created = {}", name, created);
             } catch (final IOException ioe) {
                 LOGGER.error("Unable to create file " + name, ioe);
                 return null;
             }
             final long size = data.append ? file.length() : 0;

-            OutputStream os;
             try {
-                os = new FileOutputStream(name, data.append);
                 final int actualSize = data.bufferedIO ? data.bufferSize :
Constants.ENCODER_BYTE_BUFFER_SIZE;
                 final ByteBuffer buffer = ByteBuffer.wrap(new
byte[actualSize]);
-
-                final long time = file.lastModified(); // LOG4J2-531
create file first so time has valid value
-                return new RollingFileManager(name, data.pattern, os,
data.append, size, time, data.policy,
-                    data.strategy, data.advertiseURI, data.layout,
writeHeader, buffer);
-            } catch (final FileNotFoundException ex) {
-                LOGGER.error("FileManager (" + name + ") " + ex, ex);
+                final OutputStream os = data.lazyCreate ? null : new
FileOutputStream(name, data.append);
+                final long time = data.lazyCreate?
System.currentTimeMillis() : file.lastModified(); // LOG4J2-531 create file
first so time has valid value
+
+                return new RollingFileManager(name, data.pattern, os,
data.append, data.lazyCreate, size, time, data.policy,
+                        data.strategy, data.advertiseURI, data.layout,
writeHeader, buffer);
+            } catch (final IOException ex) {
+                LOGGER.error("RollingFileManager (" + name + ") " + ex,
ex);
             }
             return null;
         }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/log4j-core/src/test/java/org/apache/logging/log4j/
core/appender/rolling/OnStartupTriggeringPolicyTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/OnStartupTriggeringPolicyTest.java
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/
OnStartupTriggeringPolicyTest.java
index eacf7c6..27f8e7e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/OnStartupTriggeringPolicyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/OnStartupTriggeringPolicyTest.java
@@ -32,7 +32,9 @@ import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.datetime.FastDateFormat;
+import org.apache.logging.log4j.junit.CleanFolders;
 import org.junit.Assert;
+import org.junit.Rule;
 import org.junit.Test;

 /**
@@ -49,8 +51,8 @@ public class OnStartupTriggeringPolicyTest {
     private static final String TEST_DATA = "Hello world!";
     private static final FastDateFormat formatter =
FastDateFormat.getInstance("MM-dd-yyyy");

-    // @Rule
-    // public CleanFolders rule = new CleanFolders("target/rollOnStartup");
+    @Rule
+    public CleanFolders rule = new CleanFolders("target/rollOnStartup");

     @Test
     public void testPolicy() throws Exception {
@@ -76,13 +78,13 @@ public class OnStartupTriggeringPolicyTest {
                 configuration);
         final OnStartupTriggeringPolicy policy = OnStartupTriggeringPolicy.
createPolicy(1);
         final RollingFileManager manager =
RollingFileManager.getFileManager(TARGET_FILE,
TARGET_PATTERN, true, false,
-                policy, strategy, null, layout, 8192, true);
+                policy, strategy, null, layout, 8192, true, false);
         try {
             manager.initialize();
             String files = Arrays.toString(new
File(TARGET_FOLDER).listFiles());
             assertTrue(target.toString() + ", files = " + files,
Files.exists(target));
             assertEquals(target.toString(), 0, Files.size(target));
-            assertTrue(rolled.toString() + ", files = " + files,
Files.exists(rolled));
+            assertTrue("Missing: " + rolled.toString() + ", files on disk
= " + files, Files.exists(rolled));
             assertEquals(rolled.toString(), size, Files.size(rolled));
         } finally {
             manager.release();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/log4j-core/src/test/java/org/apache/logging/log4j/
core/appender/rolling/RollingAppenderSizeTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/RollingAppenderSizeTest.java b/log4j-core/src/test/java/
org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java
index 92e89b1..0560301 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/RollingAppenderSizeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/RollingAppenderSizeTest.java
@@ -29,6 +29,9 @@ import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Collection;

@@ -37,8 +40,10 @@ import org.apache.commons.compress.compressors.
CompressorInputStream;
 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.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.util.Closer;
 import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -61,25 +66,34 @@ public class RollingAppenderSizeTest {

     private Logger logger;

-    @Parameterized.Parameters(name = "{0} \u2192 {1}")
+    private final boolean lazyCreate;
+
+    @Parameterized.Parameters(name = "{0} \u2192 {1} (lazyCreate = {2})")
     public static Collection<Object[]> data() {
         return Arrays.asList(new Object[][] { //
                 // @formatter:off
-                {"log4j-rolling-gz.xml", ".gz"}, //
-                {"log4j-rolling-zip.xml", ".zip"}, //
+               {"log4j-rolling-gz-lazy.xml", ".gz", true}, //
+               {"log4j-rolling-gz.xml", ".gz", false}, //
+               {"log4j-rolling-zip-lazy.xml", ".zip", true}, //
+               {"log4j-rolling-zip.xml", ".zip", false}, //
                 // Apache Commons Compress
-                {"log4j-rolling-bzip2.xml", ".bz2"}, //
-                {"log4j-rolling-deflate.xml", ".deflate"}, //
-                {"log4j-rolling-pack200.xml", ".pack200"}, //
-                {"log4j-rolling-xz.xml", ".xz"}, //
+               {"log4j-rolling-bzip2-lazy.xml", ".bz2", true}, //
+               {"log4j-rolling-bzip2.xml", ".bz2", false}, //
+               {"log4j-rolling-deflate-lazy.xml", ".deflate", true}, //
+               {"log4j-rolling-deflate.xml", ".deflate", false}, //
+               {"log4j-rolling-pack200-lazy.xml", ".pack200", true}, //
+               {"log4j-rolling-pack200.xml", ".pack200", false}, //
+               {"log4j-rolling-xz-lazy.xml", ".xz", true}, //
+               {"log4j-rolling-xz.xml", ".xz", false}, //
                 });
                 // @formatter:on
     }

     private LoggerContextRule loggerContextRule;

-    public RollingAppenderSizeTest(final String configFile, final String
fileExtension) {
+    public RollingAppenderSizeTest(final String configFile, final String
fileExtension, final boolean lazyCreate) {
         this.fileExtension = fileExtension;
+        this.lazyCreate = lazyCreate;
         this.loggerContextRule = new LoggerContextRule(configFile);
         this.chain = loggerContextRule.withCleanFoldersRule(DIR);
     }
@@ -90,7 +104,20 @@ public class RollingAppenderSizeTest {
     }

     @Test
+    public void testIsLazyCreate() {
+        final RollingFileAppender rfAppender = loggerContextRule.
getRequiredAppender("RollingFile",
+                RollingFileAppender.class);
+        final RollingFileManager manager = rfAppender.getManager();
+        Assert.assertNotNull(manager);
+        Assert.assertEquals(lazyCreate, manager.isLazyCreate());
+    }
+
+    @Test
     public void testAppender() throws Exception {
+        final Path path = Paths.get(DIR, "rollingtest.log");
+        if (Files.exists(path) && lazyCreate) {
+            Assert.fail(String.format("Unexpected file: %s (%s bytes)",
path, Files.getAttribute(path, "size")));
+        }
         for (int i = 0; i < 100; ++i) {
             logger.debug("This is test message number " + i);
         }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/log4j-core/src/test/java/org/apache/logging/log4j/
core/appender/rolling/RollingFileAppenderAccessTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/RollingFileAppenderAccessTest.java
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/
RollingFileAppenderAccessTest.java
index d22fc6a..b484567 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/RollingFileAppenderAccessTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/
appender/rolling/RollingFileAppenderAccessTest.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.config.Configuration;
+import org.junit.Assert;
 import org.junit.Test;

 public class RollingFileAppenderAccessTest {
@@ -32,19 +33,26 @@ public class RollingFileAppenderAccessTest {
      * @throws IOException
      */
     @Test
-    public void testAccessManagerWithStrings() throws IOException {
-        final LoggerContext ctx = LoggerContext.getContext(false);
-        final Configuration config = ctx.getConfiguration();
-        final File file = File.createTempFile("
RollingFileAppenderAccessTest", ".tmp");
-        file.deleteOnExit();
-        final RollingFileAppender appender = RollingFileAppender.
createAppender(file.getCanonicalPath(), "FilePattern",
-                null, "Name", null, null, null,
OnStartupTriggeringPolicy.createPolicy(1),
null, null, null, null, null,
-                null, config);
-        final RollingFileManager manager = appender.getManager();
-        // Since the RolloverStrategy and TriggeringPolicy are immutable,
we could also use generics to type their
-        // access.
-        manager.getRolloverStrategy();
-        manager.getTriggeringPolicy();
+    public void testAccessManagerWithBuilder() throws IOException {
+        try (final LoggerContext ctx = LoggerContext.getContext(false)) {
+            final Configuration config = ctx.getConfiguration();
+            final File file = File.createTempFile("
RollingFileAppenderAccessTest", ".tmp");
+            file.deleteOnExit();
+            // @formatter:off
+            final RollingFileAppender appender = RollingFileAppender.
newBuilder()
+                    .withFileName(file.getCanonicalPath())
+                    .withFilePattern("FilePattern")
+                    .withName("Name")
+                    .withPolicy(OnStartupTriggeringPolicy.createPolicy(1))
+                    .withConfig(config)
+                    .build();
+            // @formatter:on
+            final RollingFileManager manager = appender.getManager();
+            // Since the RolloverStrategy and TriggeringPolicy are
immutable, we could also use generics to type their
+            // access.
+            Assert.assertNotNull(manager.getRolloverStrategy());
+            Assert.assertNotNull(manager.getTriggeringPolicy());
+        }
     }

     /**
@@ -53,18 +61,19 @@ public class RollingFileAppenderAccessTest {
      * @throws IOException
      */
     @Test
-    public void testAccessManagerWithPrimitives() throws IOException {
-        final LoggerContext ctx = LoggerContext.getContext(false);
-        final Configuration config = ctx.getConfiguration();
-        final File file = File.createTempFile("
RollingFileAppenderAccessTest", ".tmp");
-        file.deleteOnExit();
-        final RollingFileAppender appender = RollingFileAppender.
createAppender(file.getCanonicalPath(), "FilePattern",
-                true, "Name", true, 8192, true,
OnStartupTriggeringPolicy.createPolicy(1),
null, null, null, true, false,
-                null, config);
-        final RollingFileManager manager = appender.getManager();
-        // Since the RolloverStrategy and TriggeringPolicy are immutable,
we could also use generics to type their
-        // access.
-        manager.getRolloverStrategy();
-        manager.getTriggeringPolicy();
+    public void testAccessManagerWithStrings() throws IOException {
+        try (final LoggerContext ctx = LoggerContext.getContext(false)) {
+            final Configuration config = ctx.getConfiguration();
+            final File file = File.createTempFile("
RollingFileAppenderAccessTest", ".tmp");
+            file.deleteOnExit();
+            final RollingFileAppender appender = RollingFileAppender.
createAppender(file.getCanonicalPath(),
+                    "FilePattern", null, "Name", null, null, null,
OnStartupTriggeringPolicy.createPolicy(1), null,
+                    null, null, null, null, null, config);
+            final RollingFileManager manager = appender.getManager();
+            // Since the RolloverStrategy and TriggeringPolicy are
immutable, we could also use generics to type their
+            // access.
+            Assert.assertNotNull(manager.getRolloverStrategy());
+            Assert.assertNotNull(manager.getTriggeringPolicy());
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
a82794f0/log4j-core/src/test/resources/log4j-rolling-7z-lazy.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-7z-lazy.xml
b/log4j-core/src/test/resources/log4j-rolling-7z-lazy.xml
new file mode 100644
index 0000000..ce16320
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-7z-lazy.xml
@@ -0,0 +1,59 @@
+<?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="OFF" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}-%i.
log.7z"
+                 lazyCreate="true">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="500" />
+    </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/
a82794f0/log4j-core/src/test/resources/log4j-rolling-bzip2-lazy.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-bzip2-lazy.xml
b/log4j-core/src/test/resources/log4j-rolling-bzip2-lazy.xml
new file mode 100644
index 0000000..6697293
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-bzip2-lazy.xml
@@ -0,0 +1,60 @@
+<?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="OFF" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}-%i.
log.bz2"
+                 lazyCreate="true">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="500" />
+      <DefaultRolloverStrategy compressionLevel="9" />
+    </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/
a82794f0/log4j-core/src/test/resources/log4j-rolling-deflate-lazy.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-deflate-lazy.xml
b/log4j-core/src/test/resources/log4j-rolling-deflate-lazy.xml
new file mode 100644
index 0000000..d4561f7
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-deflate-lazy.xml
@@ -0,0 +1,60 @@
+<?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="OFF" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}-%i.
log.deflate"
+                 lazyCreate="true">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="500" />
+      <DefaultRolloverStrategy compressionLevel="9" />
+    </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/
a82794f0/log4j-core/src/test/resources/log4j-rolling-gz-lazy.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-gz-lazy.xml
b/log4j-core/src/test/resources/log4j-rolling-gz-lazy.xml
new file mode 100644
index 0000000..f9bfd90
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-gz-lazy.xml
@@ -0,0 +1,59 @@
+<?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="OFF" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}-%i.
log.gz"
+                 lazyCreate="true">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="500" />
+    </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/
a82794f0/log4j-core/src/test/resources/log4j-rolling-pack200-lazy.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-pack200-lazy.xml
b/log4j-core/src/test/resources/log4j-rolling-pack200-lazy.xml
new file mode 100644
index 0000000..7355e61
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-pack200-lazy.xml
@@ -0,0 +1,60 @@
+<?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="OFF" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}-%i.
log.pack200"
+                 lazyCreate="true">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="500" />
+      <DefaultRolloverStrategy compressionLevel="9" />
+    </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/
a82794f0/log4j-core/src/test/resources/log4j-rolling-xz-lazy.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-xz-lazy.xml
b/log4j-core/src/test/resources/log4j-rolling-xz-lazy.xml
new file mode 100644
index 0000000..02aa528
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-xz-lazy.xml
@@ -0,0 +1,60 @@
+<?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="OFF" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}-%i.
log.xz"
+                 lazyCreate="true">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="500" />
+      <DefaultRolloverStrategy compressionLevel="9" />
+    </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/
a82794f0/log4j-core/src/test/resources/log4j-rolling-zip-lazy.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-zip-lazy.xml
b/log4j-core/src/test/resources/log4j-rolling-zip-lazy.xml
new file mode 100644
index 0000000..2641d7f
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-zip-lazy.xml
@@ -0,0 +1,60 @@
+<?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="OFF" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}-%i.
log.zip"
+                 lazyCreate="true">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="500" />
+      <DefaultRolloverStrategy compressionLevel="9" />
+    </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/
a82794f0/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 675a24a..36bb642 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -67,7 +67,10 @@
         Properties declared in configuration can now have their value
either in the element body or in an attribute named "value".
       </action>
       <action issue="LOG4J2-1501" dev="ggregory" type="add" due-to="Gary
Gregory">
-        FileAppender should be able to create files lazily.
+        FileAppender should be able to create files on-demand.
+      </action>
+      <action issue="LOG4J2-1504" dev="ggregory" type="add" due-to="Gary
Gregory">
+        RollingFileAppender should be able to create files on-demand.
       </action>
       <action issue="LOG4J2-1471" dev="ggregory" type="add" due-to="Gary
Gregory">
         [PatternLayout] Add an ANSI option to %xThrowable.




-- 
Matt Sicker <boards@gmail.com>

Mime
View raw message