[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/LOG4J2-1528 Commit: a82794f06e3bc095ef0bca41b98c5d1ea915de76 Parents: 60649ef Author: Gary Gregory <ggreg...@apache.org> Authored: Fri Aug 19 17:27:26 2016 -0700 Committer: Gary Gregory <ggreg...@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.