You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Matt Sicker <bo...@gmail.com> on 2016/08/20 00:43:04 UTC

Fwd: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.

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: <gg...@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 <gg...@apache.org>
Authored: Fri Aug 19 17:27:26 2016 -0700
Committer: Gary Gregory <gg...@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 <bo...@gmail.com>

Re: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.

Posted by Matt Sicker <bo...@gmail.com>.
That's actually what I based the simplified validation API on.

On 21 August 2016 at 19:33, Gary Gregory <ga...@gmail.com> wrote:

> We are entering bean validation territory here...
>
> On Aug 20, 2016 5:19 PM, "Matt Sicker" <bo...@gmail.com> wrote:
>
>> Ah, ok. Then it seems like it could be valuable to make the validation
>> API work more easily for situations like this. From what I remember, the
>> validations API is optimized for its usage in PluginBuilder, not
>> necessarily in arbitrary code.
>>
>> On 20 August 2016 at 12:00, Gary Gregory <ga...@gmail.com> wrote:
>>
>>> To avoid duplicating code, the method
>>>
>>> RollingFileAppender.createAppender(String, String, String, String,
>>> String, String, String, TriggeringPolicy, RolloverStrategy, Layout<?
>>> extends Serializable>, Filter, String, String, String, Configuration)
>>>
>>> uses the new builder.
>>>
>>> Gary
>>>
>>> On Fri, Aug 19, 2016 at 6:11 PM, Matt Sicker <bo...@gmail.com> wrote:
>>>
>>>> Do you mean from the @PluginFactory methods, or from Builder.build()?
>>>>
>>>> On 19 August 2016 at 20:06, Gary Gregory <ga...@gmail.com>
>>>> wrote:
>>>>
>>>>> On Fri, Aug 19, 2016 at 5:43 PM, Matt Sicker <bo...@gmail.com> wrote:
>>>>>
>>>>>> 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).
>>>>>>
>>>>>
>>>>> Indeed, I had to keep the null checks for the programmatic
>>>>> configuration to work.
>>>>>
>>>>> Gary
>>>>>
>>>>>
>>>>>>
>>>>>> ---------- Forwarded message ----------
>>>>>> From: <gg...@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/a
>>>>>> 82794f0
>>>>>> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a
>>>>>> 82794f0
>>>>>>
>>>>>> Branch: refs/heads/master
>>>>>> Commit: a82794f06e3bc095ef0bca41b98c5d1ea915de76
>>>>>> Parents: 60649ef
>>>>>> Author: Gary Gregory <gg...@apache.org>
>>>>>> Authored: Fri Aug 19 17:27:26 2016 -0700
>>>>>> Committer: Gary Gregory <gg...@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/a
>>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>>> re/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/app
>>>>>> ender/FileManager.java
>>>>>> index c71bd95..b8a559a 100644
>>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/FileManager.java
>>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/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/a
>>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>>> re/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/app
>>>>>> ender/OutputStreamManager.java
>>>>>> index e707bea..d895dd5 100644
>>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/OutputStreamManager.java
>>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/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/a
>>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>>> re/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/app
>>>>>> ender/RollingFileAppender.java
>>>>>> index 01ef50d..dc830e3 100644
>>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/RollingFileAppender.java
>>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/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.PluginBuilderAt
>>>>>> tribute;
>>>>>> +import org.apache.logging.log4j.core.config.plugins.PluginBuilderFa
>>>>>> ctory;
>>>>>>  import org.apache.logging.log4j.core.config.plugins.PluginConfigura
>>>>>> tion;
>>>>>>  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.cons
>>>>>> traints.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/a
>>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>>> re/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/app
>>>>>> ender/rolling/RollingFileManager.java
>>>>>> index 4fdbf30..5f390f1 100644
>>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/rolling/RollingFileManager.java
>>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>>> ender/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.Abstra
>>>>>> ctAction;
>>>>>>  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/a
>>>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>>>> re/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/app
>>>>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>>>>> index eacf7c6..27f8e7e 100644
>>>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>>> ender/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/rollOnSta
>>>>>> rtup");
>>>>>> +    @Rule
>>>>>> +    public CleanFolders rule = new CleanFolders("target/rollOnSta
>>>>>> rtup");
>>>>>>
>>>>>>      @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/a
>>>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>>>> re/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/app
>>>>>> ender/rolling/RollingAppenderSizeTest.java
>>>>>> index 92e89b1..0560301 100644
>>>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>>> ender/rolling/RollingAppenderSizeTest.java
>>>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>>> ender/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.co
>>>>>> mpressors.CompressorInputStream;
>>>>>>  import org.apache.commons.compress.compressors.CompressorStreamFact
>>>>>> ory;
>>>>>>  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/a
>>>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>>>> re/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/app
>>>>>> ender/rolling/RollingFileAppenderAccessTest.java
>>>>>> index d22fc6a..b484567 100644
>>>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>>> ender/rolling/RollingFileAppenderAccessTest.java
>>>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>>> ender/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(OnStartupTriggerin
>>>>>> gPolicy.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/a
>>>>>> 82794f0/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/rolling
>>>>>> 1/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/a
>>>>>> 82794f0/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/rolling
>>>>>> 1/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/a
>>>>>> 82794f0/log4j-core/src/test/resources/log4j-rolling-deflate-lazy.xml
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>> diff --git a/log4j-core/src/test/resource
>>>>>> s/log4j-rolling-deflate-lazy.xml b/log4j-core/src/test/resource
>>>>>> s/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/rolling
>>>>>> 1/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/a
>>>>>> 82794f0/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/rolling
>>>>>> 1/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/a
>>>>>> 82794f0/log4j-core/src/test/resources/log4j-rolling-pack200-lazy.xml
>>>>>> ------------------------------------------------------------
>>>>>> ----------
>>>>>> diff --git a/log4j-core/src/test/resource
>>>>>> s/log4j-rolling-pack200-lazy.xml b/log4j-core/src/test/resource
>>>>>> s/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/rolling
>>>>>> 1/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/a
>>>>>> 82794f0/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/rolling
>>>>>> 1/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/a
>>>>>> 82794f0/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/rolling
>>>>>> 1/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/a
>>>>>> 82794f0/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 <bo...@gmail.com>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>>>>> Java Persistence with Hibernate, Second Edition
>>>>> <http://www.manning.com/bauer3/>
>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>> Blog: http://garygregory.wordpress.com
>>>>> Home: http://garygregory.com/
>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Matt Sicker <bo...@gmail.com>
>>>>
>>>
>>>
>>>
>>> --
>>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>>> Java Persistence with Hibernate, Second Edition
>>> <http://www.manning.com/bauer3/>
>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>> Spring Batch in Action <http://www.manning.com/templier/>
>>> Blog: http://garygregory.wordpress.com
>>> Home: http://garygregory.com/
>>> Tweet! http://twitter.com/GaryGregory
>>>
>>
>>
>>
>> --
>> Matt Sicker <bo...@gmail.com>
>>
>


-- 
Matt Sicker <bo...@gmail.com>

Re: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.

Posted by Gary Gregory <ga...@gmail.com>.
We are entering bean validation territory here...

On Aug 20, 2016 5:19 PM, "Matt Sicker" <bo...@gmail.com> wrote:

> Ah, ok. Then it seems like it could be valuable to make the validation API
> work more easily for situations like this. From what I remember, the
> validations API is optimized for its usage in PluginBuilder, not
> necessarily in arbitrary code.
>
> On 20 August 2016 at 12:00, Gary Gregory <ga...@gmail.com> wrote:
>
>> To avoid duplicating code, the method
>>
>> RollingFileAppender.createAppender(String, String, String, String,
>> String, String, String, TriggeringPolicy, RolloverStrategy, Layout<?
>> extends Serializable>, Filter, String, String, String, Configuration)
>>
>> uses the new builder.
>>
>> Gary
>>
>> On Fri, Aug 19, 2016 at 6:11 PM, Matt Sicker <bo...@gmail.com> wrote:
>>
>>> Do you mean from the @PluginFactory methods, or from Builder.build()?
>>>
>>> On 19 August 2016 at 20:06, Gary Gregory <ga...@gmail.com> wrote:
>>>
>>>> On Fri, Aug 19, 2016 at 5:43 PM, Matt Sicker <bo...@gmail.com> wrote:
>>>>
>>>>> 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).
>>>>>
>>>>
>>>> Indeed, I had to keep the null checks for the programmatic
>>>> configuration to work.
>>>>
>>>> Gary
>>>>
>>>>
>>>>>
>>>>> ---------- Forwarded message ----------
>>>>> From: <gg...@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/a
>>>>> 82794f0
>>>>> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a
>>>>> 82794f0
>>>>>
>>>>> Branch: refs/heads/master
>>>>> Commit: a82794f06e3bc095ef0bca41b98c5d1ea915de76
>>>>> Parents: 60649ef
>>>>> Author: Gary Gregory <gg...@apache.org>
>>>>> Authored: Fri Aug 19 17:27:26 2016 -0700
>>>>> Committer: Gary Gregory <gg...@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/a
>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>> re/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/app
>>>>> ender/FileManager.java
>>>>> index c71bd95..b8a559a 100644
>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/FileManager.java
>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/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/a
>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>> re/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/app
>>>>> ender/OutputStreamManager.java
>>>>> index e707bea..d895dd5 100644
>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/OutputStreamManager.java
>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/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/a
>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>> re/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/app
>>>>> ender/RollingFileAppender.java
>>>>> index 01ef50d..dc830e3 100644
>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/RollingFileAppender.java
>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/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.PluginBuilderAt
>>>>> tribute;
>>>>> +import org.apache.logging.log4j.core.config.plugins.PluginBuilderFa
>>>>> ctory;
>>>>>  import org.apache.logging.log4j.core.config.plugins.PluginConfigura
>>>>> tion;
>>>>>  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.cons
>>>>> traints.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/a
>>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>>> re/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/app
>>>>> ender/rolling/RollingFileManager.java
>>>>> index 4fdbf30..5f390f1 100644
>>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/rolling/RollingFileManager.java
>>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>>> ender/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.Abstra
>>>>> ctAction;
>>>>>  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/a
>>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>>> re/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/app
>>>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>>>> index eacf7c6..27f8e7e 100644
>>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>> ender/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/rollOnSta
>>>>> rtup");
>>>>> +    @Rule
>>>>> +    public CleanFolders rule = new CleanFolders("target/rollOnSta
>>>>> rtup");
>>>>>
>>>>>      @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/a
>>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>>> re/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/app
>>>>> ender/rolling/RollingAppenderSizeTest.java
>>>>> index 92e89b1..0560301 100644
>>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>> ender/rolling/RollingAppenderSizeTest.java
>>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>> ender/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.co
>>>>> mpressors.CompressorInputStream;
>>>>>  import org.apache.commons.compress.compressors.CompressorStreamFact
>>>>> ory;
>>>>>  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/a
>>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>>> re/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/app
>>>>> ender/rolling/RollingFileAppenderAccessTest.java
>>>>> index d22fc6a..b484567 100644
>>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>> ender/rolling/RollingFileAppenderAccessTest.java
>>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>>> ender/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(OnStartupTriggerin
>>>>> gPolicy.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/a
>>>>> 82794f0/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/rolling
>>>>> 1/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/a
>>>>> 82794f0/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/rolling
>>>>> 1/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/a
>>>>> 82794f0/log4j-core/src/test/resources/log4j-rolling-deflate-lazy.xml
>>>>> ----------------------------------------------------------------------
>>>>> diff --git a/log4j-core/src/test/resource
>>>>> s/log4j-rolling-deflate-lazy.xml b/log4j-core/src/test/resource
>>>>> s/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/rolling
>>>>> 1/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/a
>>>>> 82794f0/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/rolling
>>>>> 1/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/a
>>>>> 82794f0/log4j-core/src/test/resources/log4j-rolling-pack200-lazy.xml
>>>>> ----------------------------------------------------------------------
>>>>> diff --git a/log4j-core/src/test/resource
>>>>> s/log4j-rolling-pack200-lazy.xml b/log4j-core/src/test/resource
>>>>> s/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/rolling
>>>>> 1/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/a
>>>>> 82794f0/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/rolling
>>>>> 1/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/a
>>>>> 82794f0/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/rolling
>>>>> 1/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/a
>>>>> 82794f0/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 <bo...@gmail.com>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>>>> Java Persistence with Hibernate, Second Edition
>>>> <http://www.manning.com/bauer3/>
>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>> Blog: http://garygregory.wordpress.com
>>>> Home: http://garygregory.com/
>>>> Tweet! http://twitter.com/GaryGregory
>>>>
>>>
>>>
>>>
>>> --
>>> Matt Sicker <bo...@gmail.com>
>>>
>>
>>
>>
>> --
>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>> Java Persistence with Hibernate, Second Edition
>> <http://www.manning.com/bauer3/>
>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>> Spring Batch in Action <http://www.manning.com/templier/>
>> Blog: http://garygregory.wordpress.com
>> Home: http://garygregory.com/
>> Tweet! http://twitter.com/GaryGregory
>>
>
>
>
> --
> Matt Sicker <bo...@gmail.com>
>

Re: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.

Posted by Matt Sicker <bo...@gmail.com>.
Ah, ok. Then it seems like it could be valuable to make the validation API
work more easily for situations like this. From what I remember, the
validations API is optimized for its usage in PluginBuilder, not
necessarily in arbitrary code.

On 20 August 2016 at 12:00, Gary Gregory <ga...@gmail.com> wrote:

> To avoid duplicating code, the method
>
> RollingFileAppender.createAppender(String, String, String, String,
> String, String, String, TriggeringPolicy, RolloverStrategy, Layout<?
> extends Serializable>, Filter, String, String, String, Configuration)
>
> uses the new builder.
>
> Gary
>
> On Fri, Aug 19, 2016 at 6:11 PM, Matt Sicker <bo...@gmail.com> wrote:
>
>> Do you mean from the @PluginFactory methods, or from Builder.build()?
>>
>> On 19 August 2016 at 20:06, Gary Gregory <ga...@gmail.com> wrote:
>>
>>> On Fri, Aug 19, 2016 at 5:43 PM, Matt Sicker <bo...@gmail.com> wrote:
>>>
>>>> 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).
>>>>
>>>
>>> Indeed, I had to keep the null checks for the programmatic configuration
>>> to work.
>>>
>>> Gary
>>>
>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: <gg...@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/a
>>>> 82794f0
>>>> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a
>>>> 82794f0
>>>>
>>>> Branch: refs/heads/master
>>>> Commit: a82794f06e3bc095ef0bca41b98c5d1ea915de76
>>>> Parents: 60649ef
>>>> Author: Gary Gregory <gg...@apache.org>
>>>> Authored: Fri Aug 19 17:27:26 2016 -0700
>>>> Committer: Gary Gregory <gg...@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/a
>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>> re/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/app
>>>> ender/FileManager.java
>>>> index c71bd95..b8a559a 100644
>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/FileManager.java
>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/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/a
>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>> re/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/app
>>>> ender/OutputStreamManager.java
>>>> index e707bea..d895dd5 100644
>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/OutputStreamManager.java
>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/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/a
>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>> re/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/app
>>>> ender/RollingFileAppender.java
>>>> index 01ef50d..dc830e3 100644
>>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/RollingFileAppender.java
>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/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.PluginBuilderAt
>>>> tribute;
>>>> +import org.apache.logging.log4j.core.config.plugins.PluginBuilderFa
>>>> ctory;
>>>>  import org.apache.logging.log4j.core.config.plugins.PluginConfigura
>>>> tion;
>>>>  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.cons
>>>> traints.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/a
>>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>>> re/appender/rolling/RollingFileManager.java
>>>> ----------------------------------------------------------------------
>>>> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/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/app
>>>> ender/rolling/RollingFileManager.java
>>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>>> ender/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.Abstra
>>>> ctAction;
>>>>  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/a
>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>> re/appender/rolling/OnStartupTriggeringPolicyTest.java
>>>> ----------------------------------------------------------------------
>>>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>>> index eacf7c6..27f8e7e 100644
>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/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/rollOnSta
>>>> rtup");
>>>> +    @Rule
>>>> +    public CleanFolders rule = new CleanFolders("target/rollOnSta
>>>> rtup");
>>>>
>>>>      @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/a
>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>> re/appender/rolling/RollingAppenderSizeTest.java
>>>> ----------------------------------------------------------------------
>>>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/RollingAppenderSizeTest.java
>>>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/RollingAppenderSizeTest.java
>>>> index 92e89b1..0560301 100644
>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/RollingAppenderSizeTest.java
>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/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.co
>>>> mpressors.CompressorInputStream;
>>>>  import org.apache.commons.compress.compressors.CompressorStreamFact
>>>> ory;
>>>>  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/a
>>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>>> re/appender/rolling/RollingFileAppenderAccessTest.java
>>>> ----------------------------------------------------------------------
>>>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/RollingFileAppenderAccessTest.java
>>>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/RollingFileAppenderAccessTest.java
>>>> index d22fc6a..b484567 100644
>>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/rolling/RollingFileAppenderAccessTest.java
>>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>>> ender/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(OnStartupTriggerin
>>>> gPolicy.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/a
>>>> 82794f0/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/rolling
>>>> 1/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/a
>>>> 82794f0/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/rolling
>>>> 1/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/a
>>>> 82794f0/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/rolling
>>>> 1/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/a
>>>> 82794f0/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/rolling
>>>> 1/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/a
>>>> 82794f0/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/rolling
>>>> 1/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/a
>>>> 82794f0/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/rolling
>>>> 1/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/a
>>>> 82794f0/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/rolling
>>>> 1/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/a
>>>> 82794f0/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 <bo...@gmail.com>
>>>>
>>>
>>>
>>>
>>> --
>>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>>> Java Persistence with Hibernate, Second Edition
>>> <http://www.manning.com/bauer3/>
>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>> Spring Batch in Action <http://www.manning.com/templier/>
>>> Blog: http://garygregory.wordpress.com
>>> Home: http://garygregory.com/
>>> Tweet! http://twitter.com/GaryGregory
>>>
>>
>>
>>
>> --
>> Matt Sicker <bo...@gmail.com>
>>
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>



-- 
Matt Sicker <bo...@gmail.com>

Re: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.

Posted by Gary Gregory <ga...@gmail.com>.
To avoid duplicating code, the method

RollingFileAppender.createAppender(String, String, String, String, String,
String, String, TriggeringPolicy, RolloverStrategy, Layout<? extends
Serializable>, Filter, String, String, String, Configuration)

uses the new builder.

Gary

On Fri, Aug 19, 2016 at 6:11 PM, Matt Sicker <bo...@gmail.com> wrote:

> Do you mean from the @PluginFactory methods, or from Builder.build()?
>
> On 19 August 2016 at 20:06, Gary Gregory <ga...@gmail.com> wrote:
>
>> On Fri, Aug 19, 2016 at 5:43 PM, Matt Sicker <bo...@gmail.com> wrote:
>>
>>> 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).
>>>
>>
>> Indeed, I had to keep the null checks for the programmatic configuration
>> to work.
>>
>> Gary
>>
>>
>>>
>>> ---------- Forwarded message ----------
>>> From: <gg...@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/a
>>> 82794f0
>>> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a
>>> 82794f0
>>>
>>> Branch: refs/heads/master
>>> Commit: a82794f06e3bc095ef0bca41b98c5d1ea915de76
>>> Parents: 60649ef
>>> Author: Gary Gregory <gg...@apache.org>
>>> Authored: Fri Aug 19 17:27:26 2016 -0700
>>> Committer: Gary Gregory <gg...@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/a
>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>> re/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/app
>>> ender/FileManager.java
>>> index c71bd95..b8a559a 100644
>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/FileManager.java
>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/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/a
>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>> re/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/app
>>> ender/OutputStreamManager.java
>>> index e707bea..d895dd5 100644
>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/OutputStreamManager.java
>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/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/a
>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>> re/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/app
>>> ender/RollingFileAppender.java
>>> index 01ef50d..dc830e3 100644
>>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/RollingFileAppender.java
>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/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.PluginBuilderAt
>>> tribute;
>>> +import org.apache.logging.log4j.core.config.plugins.PluginBuilderFa
>>> ctory;
>>>  import org.apache.logging.log4j.core.config.plugins.PluginConfigura
>>> tion;
>>>  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.cons
>>> traints.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/a
>>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>>> re/appender/rolling/RollingFileManager.java
>>> ----------------------------------------------------------------------
>>> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/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/app
>>> ender/rolling/RollingFileManager.java
>>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/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.Abstra
>>> ctAction;
>>>  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/a
>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>> re/appender/rolling/OnStartupTriggeringPolicyTest.java
>>> ----------------------------------------------------------------------
>>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>> index eacf7c6..27f8e7e 100644
>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/OnStartupTriggeringPolicyTest.java
>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/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/rollOnSta
>>> rtup");
>>> +    @Rule
>>> +    public CleanFolders rule = new CleanFolders("target/rollOnSta
>>> rtup");
>>>
>>>      @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/a
>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>> re/appender/rolling/RollingAppenderSizeTest.java
>>> ----------------------------------------------------------------------
>>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/RollingAppenderSizeTest.java
>>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/RollingAppenderSizeTest.java
>>> index 92e89b1..0560301 100644
>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/RollingAppenderSizeTest.java
>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/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.co
>>> mpressors.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/a
>>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>>> re/appender/rolling/RollingFileAppenderAccessTest.java
>>> ----------------------------------------------------------------------
>>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/RollingFileAppenderAccessTest.java
>>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/RollingFileAppenderAccessTest.java
>>> index d22fc6a..b484567 100644
>>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/rolling/RollingFileAppenderAccessTest.java
>>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/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(OnStartupTriggerin
>>> gPolicy.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/a
>>> 82794f0/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/rolling
>>> 1/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/a
>>> 82794f0/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/rolling
>>> 1/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/a
>>> 82794f0/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/rolling
>>> 1/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/a
>>> 82794f0/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/rolling
>>> 1/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/a
>>> 82794f0/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/rolling
>>> 1/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/a
>>> 82794f0/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/rolling
>>> 1/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/a
>>> 82794f0/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/rolling
>>> 1/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/a
>>> 82794f0/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 <bo...@gmail.com>
>>>
>>
>>
>>
>> --
>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>> Java Persistence with Hibernate, Second Edition
>> <http://www.manning.com/bauer3/>
>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>> Spring Batch in Action <http://www.manning.com/templier/>
>> Blog: http://garygregory.wordpress.com
>> Home: http://garygregory.com/
>> Tweet! http://twitter.com/GaryGregory
>>
>
>
>
> --
> Matt Sicker <bo...@gmail.com>
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Re: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.

Posted by Matt Sicker <bo...@gmail.com>.
Do you mean from the @PluginFactory methods, or from Builder.build()?

On 19 August 2016 at 20:06, Gary Gregory <ga...@gmail.com> wrote:

> On Fri, Aug 19, 2016 at 5:43 PM, Matt Sicker <bo...@gmail.com> wrote:
>
>> 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).
>>
>
> Indeed, I had to keep the null checks for the programmatic configuration
> to work.
>
> Gary
>
>
>>
>> ---------- Forwarded message ----------
>> From: <gg...@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 <gg...@apache.org>
>> Authored: Fri Aug 19 17:27:26 2016 -0700
>> Committer: Gary Gregory <gg...@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/a
>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>> re/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/app
>> ender/FileManager.java
>> index c71bd95..b8a559a 100644
>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/FileManager.java
>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/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/a
>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>> re/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/app
>> ender/OutputStreamManager.java
>> index e707bea..d895dd5 100644
>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/OutputStreamManager.java
>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/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/a
>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>> re/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/app
>> ender/RollingFileAppender.java
>> index 01ef50d..dc830e3 100644
>> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/RollingFileAppender.java
>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/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.PluginBuilderAt
>> tribute;
>> +import org.apache.logging.log4j.core.config.plugins.PluginBuilderFa
>> ctory;
>>  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.cons
>> traints.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/a
>> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
>> re/appender/rolling/RollingFileManager.java
>> ----------------------------------------------------------------------
>> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/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/app
>> ender/rolling/RollingFileManager.java
>> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>> ender/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.Abstra
>> ctAction;
>>  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/a
>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>> re/appender/rolling/OnStartupTriggeringPolicyTest.java
>> ----------------------------------------------------------------------
>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/rolling/OnStartupTriggeringPolicyTest.java
>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/rolling/OnStartupTriggeringPolicyTest.java
>> index eacf7c6..27f8e7e 100644
>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/rolling/OnStartupTriggeringPolicyTest.java
>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/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/rollOnSta
>> rtup");
>> +    @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/a
>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>> re/appender/rolling/RollingAppenderSizeTest.java
>> ----------------------------------------------------------------------
>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/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/app
>> ender/rolling/RollingAppenderSizeTest.java
>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/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.co
>> mpressors.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/a
>> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
>> re/appender/rolling/RollingFileAppenderAccessTest.java
>> ----------------------------------------------------------------------
>> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/rolling/RollingFileAppenderAccessTest.java
>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/rolling/RollingFileAppenderAccessTest.java
>> index d22fc6a..b484567 100644
>> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/rolling/RollingFileAppenderAccessTest.java
>> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>> ender/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(OnStartupTriggerin
>> gPolicy.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/a
>> 82794f0/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/a
>> 82794f0/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/a
>> 82794f0/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/a
>> 82794f0/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/a
>> 82794f0/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/a
>> 82794f0/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/a
>> 82794f0/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/a
>> 82794f0/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 <bo...@gmail.com>
>>
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>



-- 
Matt Sicker <bo...@gmail.com>

Re: [1/2] logging-log4j2 git commit: [LOG4J2-1504] RollingFileAppender should be able to create files on-demand.

Posted by Gary Gregory <ga...@gmail.com>.
On Fri, Aug 19, 2016 at 5:43 PM, Matt Sicker <bo...@gmail.com> wrote:

> 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).
>

Indeed, I had to keep the null checks for the programmatic configuration to
work.

Gary


>
> ---------- Forwarded message ----------
> From: <gg...@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 <gg...@apache.org>
> Authored: Fri Aug 19 17:27:26 2016 -0700
> Committer: Gary Gregory <gg...@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/a
> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/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/app
> ender/FileManager.java
> index c71bd95..b8a559a 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/FileManager.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/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/a
> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/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/app
> ender/OutputStreamManager.java
> index e707bea..d895dd5 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/OutputStreamManager.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/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/a
> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/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/app
> ender/RollingFileAppender.java
> index 01ef50d..dc830e3 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/RollingFileAppender.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/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.PluginBuilderAt
> tribute;
> +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.cons
> traints.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/a
> 82794f0/log4j-core/src/main/java/org/apache/logging/log4j/co
> re/appender/rolling/RollingFileManager.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/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/app
> ender/rolling/RollingFileManager.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
> ender/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.Abstra
> ctAction;
>  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/a
> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
> re/appender/rolling/OnStartupTriggeringPolicyTest.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/rolling/OnStartupTriggeringPolicyTest.java
> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/rolling/OnStartupTriggeringPolicyTest.java
> index eacf7c6..27f8e7e 100644
> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/rolling/OnStartupTriggeringPolicyTest.java
> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/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/rollOnSta
> rtup");
> +    @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/a
> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
> re/appender/rolling/RollingAppenderSizeTest.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/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/app
> ender/rolling/RollingAppenderSizeTest.java
> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/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.co
> mpressors.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/a
> 82794f0/log4j-core/src/test/java/org/apache/logging/log4j/co
> re/appender/rolling/RollingFileAppenderAccessTest.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/rolling/RollingFileAppenderAccessTest.java
> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/rolling/RollingFileAppenderAccessTest.java
> index d22fc6a..b484567 100644
> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/rolling/RollingFileAppenderAccessTest.java
> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
> ender/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(OnStartupTriggerin
> gPolicy.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/a
> 82794f0/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/a
> 82794f0/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/a
> 82794f0/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/a
> 82794f0/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/a
> 82794f0/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/a
> 82794f0/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/a
> 82794f0/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/a
> 82794f0/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 <bo...@gmail.com>
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory