You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2017/08/26 20:53:49 UTC

[31/50] logging-log4j2 git commit: LOG4J2-1928 - Add support for DirectWriteRolloverStrategy to RollingRandomAcessFileAppender

LOG4J2-1928 - Add support for DirectWriteRolloverStrategy to RollingRandomAcessFileAppender


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

Branch: refs/heads/LOG4J2-1431
Commit: 0b37ee7466284d6a012a092f7284d15c53b75803
Parents: 4aa719a
Author: Ralph Goers <rg...@nextiva.com>
Authored: Thu Aug 24 09:20:17 2017 -0700
Committer: Ralph Goers <rg...@nextiva.com>
Committed: Thu Aug 24 09:20:29 2017 -0700

----------------------------------------------------------------------
 .../RollingRandomAccessFileAppender.java        | 25 ++++--
 .../rolling/RollingRandomAccessFileManager.java | 93 ++++++++++++--------
 .../RollingRandomAppenderDirectWriteTest.java   | 66 ++++++++++++++
 .../resources/log4j-rolling-random-direct.xml   | 50 +++++++++++
 src/changes/changes.xml                         |  3 +
 5 files changed, 192 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0b37ee74/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
index 6148dec..f43ccd0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
@@ -28,6 +28,8 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
+import org.apache.logging.log4j.core.appender.rolling.DirectFileRolloverStrategy;
+import org.apache.logging.log4j.core.appender.rolling.DirectWriteRolloverStrategy;
 import org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager;
 import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
 import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
@@ -95,8 +97,20 @@ public final class RollingRandomAccessFileAppender extends AbstractOutputStreamA
                 return null;
             }
 
-            if (fileName == null) {
-                LOGGER.error("No filename was provided for FileAppender with name " + name);
+            if (strategy == null) {
+                if (fileName != null) {
+                    strategy = DefaultRolloverStrategy.newBuilder()
+                            .withCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION))
+                            .withConfig(getConfiguration())
+                            .build();
+                } else {
+                    strategy = DirectWriteRolloverStrategy.newBuilder()
+                            .withCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION))
+                            .withConfig(getConfiguration())
+                            .build();
+                }
+            } else if (fileName == null && !(strategy instanceof DirectFileRolloverStrategy)) {
+                LOGGER.error("RollingFileAppender '{}': When no file name is provided a DirectFilenameRolloverStrategy must be configured");
                 return null;
             }
 
@@ -110,13 +124,6 @@ public final class RollingRandomAccessFileAppender extends AbstractOutputStreamA
                 return null;
             }
 
-            if (strategy == null) {
-                strategy = DefaultRolloverStrategy.newBuilder()
-                                .withCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION))
-                                .withConfig(getConfiguration())
-                                .build();
-            }
-
             final Layout<? extends Serializable> layout = getOrCreateLayout();
 
             final boolean immediateFlush = isImmediateFlush();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0b37ee74/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
index 6d69bd9..0d60483 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
@@ -105,7 +105,8 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
             LOGGER.error("The fileName attribute must not be specified with the DirectWriteRolloverStrategy");
             return null;
         }
-        return narrow(RollingRandomAccessFileManager.class, getManager(fileName, new FactoryData(filePattern, isAppend,
+        final String name = fileName == null ? filePattern : fileName;
+        return narrow(RollingRandomAccessFileManager.class, getManager(name, new FactoryData(fileName, filePattern, isAppend,
                 immediateFlush, bufferSize, policy, strategy, advertiseURI, layout,
                 filePermissions, fileOwner, fileGroup, configuration), FACTORY));
     }
@@ -128,6 +129,12 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
     @Override
     protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) {
         try {
+            if (randomAccessFile == null) {
+                String fileName = getFileName();
+                File file = new File(fileName);
+                FileUtils.makeParentDirs(file);
+                createFileAfterRollover(fileName);
+            }
             randomAccessFile.write(bytes, offset, length);
             size += length;
         } catch (final IOException ex) {
@@ -138,7 +145,11 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
 
     @Override
     protected void createFileAfterRollover() throws IOException {
-        this.randomAccessFile = new RandomAccessFile(getFileName(), "rw");
+        createFileAfterRollover(getFileName());
+    }
+
+    private void createFileAfterRollover(String fileName) throws IOException {
+        this.randomAccessFile = new RandomAccessFile(fileName, "rw");
         if (isAppend()) {
             randomAccessFile.seek(randomAccessFile.length());
         }
@@ -187,45 +198,52 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
          */
         @Override
         public RollingRandomAccessFileManager createManager(final String name, final FactoryData data) {
-            final File file = new File(name);
-
-            if (!data.append) {
-                file.delete();
-            }
-            final long size = data.append ? file.length() : 0;
-            final long time = file.exists() ? file.lastModified() : System.currentTimeMillis();
-
-            final boolean writeHeader = !data.append || !file.exists();
+            File file = null;
+            long size = 0;
+            long time = System.currentTimeMillis();
             RandomAccessFile raf = null;
-            try {
-                FileUtils.makeParentDirs(file);
-                raf = new RandomAccessFile(name, "rw");
-                if (data.append) {
-                    final long length = raf.length();
-                    LOGGER.trace("RandomAccessFile {} seek to {}", name, length);
-                    raf.seek(length);
-                } else {
-                    LOGGER.trace("RandomAccessFile {} set length to 0", name);
-                    raf.setLength(0);
+            if (data.fileName != null) {
+                file = new File(name);
+
+                if (!data.append) {
+                    file.delete();
                 }
-                final RollingRandomAccessFileManager rrm = new RollingRandomAccessFileManager(data.getLoggerContext(), raf, name, data.pattern,
-                        NullOutputStream.getInstance(), data.append, data.immediateFlush, data.bufferSize, size, time, data.policy,
-                        data.strategy, data.advertiseURI, data.layout, data.filePermissions, data.fileOwner, data.fileGroup, writeHeader);
-                if (rrm.isAttributeViewEnabled()) {
-                    rrm.defineAttributeView(file.toPath());
+                size = data.append ? file.length() : 0;
+                if (file.exists()) {
+                    time = file.lastModified();
                 }
-                return rrm;
-            } catch (final IOException ex) {
-                LOGGER.error("Cannot access RandomAccessFile " + ex, ex);
-                if (raf != null) {
-                    try {
-                        raf.close();
-                    } catch (final IOException e) {
-                        LOGGER.error("Cannot close RandomAccessFile {}", name, e);
+                try {
+                    FileUtils.makeParentDirs(file);
+                    raf = new RandomAccessFile(name, "rw");
+                    if (data.append) {
+                        final long length = raf.length();
+                        LOGGER.trace("RandomAccessFile {} seek to {}", name, length);
+                        raf.seek(length);
+                    } else {
+                        LOGGER.trace("RandomAccessFile {} set length to 0", name);
+                        raf.setLength(0);
+                    }
+                } catch (final IOException ex) {
+                    LOGGER.error("Cannot access RandomAccessFile " + ex, ex);
+                    if (raf != null) {
+                        try {
+                            raf.close();
+                        } catch (final IOException e) {
+                            LOGGER.error("Cannot close RandomAccessFile {}", name, e);
+                        }
                     }
+                    return null;
                 }
             }
-            return null;
+            final boolean writeHeader = !data.append || file == null || !file.exists();
+
+            final RollingRandomAccessFileManager rrm = new RollingRandomAccessFileManager(data.getLoggerContext(), raf, name, data.pattern,
+                    NullOutputStream.getInstance(), data.append, data.immediateFlush, data.bufferSize, size, time, data.policy,
+                    data.strategy, data.advertiseURI, data.layout, data.filePermissions, data.fileOwner, data.fileGroup, writeHeader);
+            if (rrm.isAttributeViewEnabled()) {
+                rrm.defineAttributeView(file.toPath());
+            }
+            return rrm;
         }
     }
 
@@ -233,6 +251,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
      * Factory data.
      */
     private static class FactoryData extends ConfigurationFactoryData {
+        private final String fileName;
         private final String pattern;
         private final boolean append;
         private final boolean immediateFlush;
@@ -248,6 +267,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
         /**
          * Create the data for the factory.
          *
+         * @param fileName The file name.
          * @param pattern The pattern.
          * @param append The append flag.
          * @param immediateFlush
@@ -261,12 +281,13 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
          * @param fileGroup File group
          * @param configuration
          */
-        public FactoryData(final String pattern, final boolean append, final boolean immediateFlush,
+        public FactoryData(final String fileName, final String pattern, final boolean append, final boolean immediateFlush,
                 final int bufferSize, final TriggeringPolicy policy, final RolloverStrategy strategy,
                 final String advertiseURI, final Layout<? extends Serializable> layout,
                 final String filePermissions, final String fileOwner, final String fileGroup,
                 final Configuration configuration) {
             super(configuration);
+            this.fileName = fileName;
             this.pattern = pattern;
             this.append = append;
             this.immediateFlush = immediateFlush;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0b37ee74/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java
new file mode 100644
index 0000000..3aba52e
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender.rolling;
+
+import java.io.File;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import static org.apache.logging.log4j.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.hamcrest.Matchers.endsWith;
+import static org.hamcrest.Matchers.hasItemInArray;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class RollingRandomAppenderDirectWriteTest {
+
+    private static final String CONFIG = "log4j-rolling-random-direct.xml";
+
+    private static final String DIR = "target/rolling-random-direct";
+
+    public static LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG);
+
+    @Rule
+    public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR);
+
+    private Logger logger;
+
+    @Before
+    public void setUp() throws Exception {
+        this.logger = loggerContextRule.getLogger(RollingRandomAppenderDirectWriteTest.class.getName());
+    }
+
+    @Test
+    public void testAppender() throws Exception {
+        for (int i=0; i < 100; ++i) {
+            logger.debug("This is test message number " + i);
+        }
+        Thread.sleep(50);
+        final File dir = new File(DIR);
+        assertTrue("Directory not created", dir.exists() && dir.listFiles().length > 0);
+        final File[] files = dir.listFiles();
+        assertNotNull(files);
+        assertThat(files, hasItemInArray(that(hasName(that(endsWith(".gz"))))));
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0b37ee74/log4j-core/src/test/resources/log4j-rolling-random-direct.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-random-direct.xml b/log4j-core/src/test/resources/log4j-rolling-random-direct.xml
new file mode 100644
index 0000000..4be5b62
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-random-direct.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<Configuration status="WARN" name="XMLConfigTest">
+  <Properties>
+    <Property name="logDir">target/rolling-random-direct</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingRandomAccessFile name="RollingFile" filePattern="${logDir}/test1-%d{MM-dd-yy-HH-mm}-%i.log.gz">
+      <PatternLayout>
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </PatternLayout>
+      <Policies>
+        <TimeBasedTriggeringPolicy />
+        <SizeBasedTriggeringPolicy size="500" />
+      </Policies>
+    </RollingRandomAccessFile>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="org.apache.logging.log4j.core.appender.rolling" level="debug" additivity="false">
+      <AppenderRef ref="RollingFile"/>
+    </Logger>>
+
+    <Root level="error">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0b37ee74/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 79e9177..12f4938 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,9 @@
          - "remove" - Removed
     -->
     <release version="2.9.0" date="2017-MM-DD" description="GA Release 2.9.0">
+      <action issue="LOG4J2-1928" dev="rgoers" type="update">
+        Add support for DirectWriteRolloverStrategy to RollingRandomAcessFileAppender.
+      </action>
       <action issue="LOG4J2-1833" dev="rgoers" type="fix">
         Prevent NullPointerException when a file name is specified with the DirectWriteRolloverStrategy.
       </action>