Repository: hive
Updated Branches:
  refs/heads/master 6a6522a09 -> 1b4baf474


HIVE-17870: Update NoDeleteRollingFileAppender to use Log4j2 api (Andrew 
Sheman, reviewed by Aihua Xu)


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/1b4baf47
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/1b4baf47
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/1b4baf47

Branch: refs/heads/master
Commit: 1b4baf474c15377cc9f0bacdda317feabeefacaf
Parents: 6a6522a
Author: Aihua Xu <aihu...@apache.org>
Authored: Fri Dec 1 11:38:34 2017 -0800
Committer: Aihua Xu <aihu...@apache.org>
Committed: Fri Dec 1 13:09:34 2017 -0800

----------------------------------------------------------------------
 pom.xml                                         |   2 +-
 .../log/HushableRandomAccessFileAppender.java   |   3 +-
 .../ql/log/NoDeleteRollingFileAppender.java     | 176 -------------------
 .../ql/log/SlidingFilenameRolloverStrategy.java |  82 +++++++++
 .../TestSlidingFilenameRolloverStrategy.java    | 145 +++++++++++++++
 .../log4j2_test_sliding_rollover.properties     |  69 ++++++++
 testutils/ptest2/pom.xml                        |   2 +-
 7 files changed, 299 insertions(+), 180 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/1b4baf47/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1682f47..6d8ab5e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -180,7 +180,7 @@
     <kryo.version>3.0.3</kryo.version>
     <libfb303.version>0.9.3</libfb303.version>
     <libthrift.version>0.9.3</libthrift.version>
-    <log4j2.version>2.6.2</log4j2.version>
+    <log4j2.version>2.8.2</log4j2.version>
     <opencsv.version>2.3</opencsv.version>
     <orc.version>1.4.1</orc.version>
     <mockito-all.version>1.10.19</mockito-all.version>

http://git-wip-us.apache.org/repos/asf/hive/blob/1b4baf47/ql/src/java/org/apache/hadoop/hive/ql/log/HushableRandomAccessFileAppender.java
----------------------------------------------------------------------
diff --git 
a/ql/src/java/org/apache/hadoop/hive/ql/log/HushableRandomAccessFileAppender.java
 
b/ql/src/java/org/apache/hadoop/hive/ql/log/HushableRandomAccessFileAppender.java
index 639d1d8..0ff66df 100644
--- 
a/ql/src/java/org/apache/hadoop/hive/ql/log/HushableRandomAccessFileAppender.java
+++ 
b/ql/src/java/org/apache/hadoop/hive/ql/log/HushableRandomAccessFileAppender.java
@@ -176,8 +176,7 @@ public final class HushableRandomAccessFileAppender extends
       layout = PatternLayout.createDefaultLayout();
     }
     final RandomAccessFileManager manager = 
RandomAccessFileManager.getFileManager(
-        fileName, isAppend, isFlush, bufferSize, advertiseURI, layout
-        // , config  -- needed in later log4j versions
+        fileName, isAppend, isFlush, bufferSize, advertiseURI, layout, config
     );
     if (manager == null) {
       return null;

http://git-wip-us.apache.org/repos/asf/hive/blob/1b4baf47/ql/src/java/org/apache/hadoop/hive/ql/log/NoDeleteRollingFileAppender.java
----------------------------------------------------------------------
diff --git 
a/ql/src/java/org/apache/hadoop/hive/ql/log/NoDeleteRollingFileAppender.java 
b/ql/src/java/org/apache/hadoop/hive/ql/log/NoDeleteRollingFileAppender.java
deleted file mode 100644
index be32f06..0000000
--- a/ql/src/java/org/apache/hadoop/hive/ql/log/NoDeleteRollingFileAppender.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * 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.hadoop.hive.ql.log;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.io.Writer;
-
-import org.apache.log4j.FileAppender;
-import org.apache.log4j.Layout;
-import org.apache.log4j.helpers.CountingQuietWriter;
-import org.apache.log4j.helpers.LogLog;
-import org.apache.log4j.helpers.OptionConverter;
-import org.apache.log4j.spi.LoggingEvent;
-
-public class NoDeleteRollingFileAppender extends FileAppender {
-  /**
-   * The default maximum file size is 10MB.
-   */
-  protected long maxFileSize = 10 * 1024 * 1024;
-
-  private long nextRollover = 0;
-
-  /**
-   * The default constructor simply calls its {@link FileAppender#FileAppender
-   * parents constructor}.
-   */
-  public NoDeleteRollingFileAppender() {
-  }
-
-  /**
-   * Instantiate a RollingFileAppender and open the file designated by
-   * <code>filename</code>. The opened filename will become the output
-   * destination for this appender.
-   * <p>
-   * If the <code>append</code> parameter is true, the file will be appended 
to.
-   * Otherwise, the file designated by <code>filename</code> will be truncated
-   * before being opened.
-   */
-  public NoDeleteRollingFileAppender(Layout layout, String filename,
-      boolean append) throws IOException {
-    super(layout, filename, append);
-  }
-
-  /**
-   * Instantiate a FileAppender and open the file designated by
-   * <code>filename</code>. The opened filename will become the output
-   * destination for this appender.
-   * <p>
-   * The file will be appended to.
-   */
-  public NoDeleteRollingFileAppender(Layout layout, String filename)
-      throws IOException {
-    super(layout, filename);
-  }
-
-  /**
-   * Get the maximum size that the output file is allowed to reach before being
-   * rolled over to backup files.
-   */
-  public long getMaximumFileSize() {
-    return maxFileSize;
-  }
-
-  /**
-   * Implements the usual roll over behavior.
-   * <p>
-   * <code>File</code> is renamed <code>File.yyyyMMddHHmmss</code> and closed. 
A
-   * new <code>File</code> is created to receive further log output.
-   */
-  // synchronization not necessary since doAppend is already synced
-  public void rollOver() {
-    if (qw != null) {
-      long size = ((CountingQuietWriter) qw).getCount();
-      LogLog.debug("rolling over count=" + size);
-      // if operation fails, do not roll again until
-      // maxFileSize more bytes are written
-      nextRollover = size + maxFileSize;
-    }
-
-    this.closeFile(); // keep windows happy.
-
-    int p = fileName.lastIndexOf(".");
-    String file = p > 0 ? fileName.substring(0, p) : fileName;
-    try {
-      // This will also close the file. This is OK since multiple
-      // close operations are safe.
-      this.setFile(file, false, bufferedIO, bufferSize);
-      nextRollover = 0;
-    } catch (IOException e) {
-      if (e instanceof InterruptedIOException) {
-        Thread.currentThread().interrupt();
-      }
-      LogLog.error("setFile(" + file + ", false) call failed.", e);
-    }
-  }
-
-  public synchronized void setFile(String fileName, boolean append,
-      boolean bufferedIO, int bufferSize) throws IOException {
-    String newFileName = getLogFileName(fileName);
-    super.setFile(newFileName, append, this.bufferedIO, this.bufferSize);
-    if (append) {
-      File f = new File(newFileName);
-      ((CountingQuietWriter) qw).setCount(f.length());
-    }
-  }
-
-  /**
-   * Set the maximum size that the output file is allowed to reach before being
-   * rolled over to backup files.
-   * <p>
-   * This method is equivalent to {@link #setMaxFileSize} except that it is
-   * required for differentiating the setter taking a <code>long</code> 
argument
-   * from the setter taking a <code>String</code> argument by the JavaBeans
-   * {@link java.beans.Introspector Introspector}.
-   *
-   * @see #setMaxFileSize(String)
-   */
-  public void setMaximumFileSize(long maxFileSize) {
-    this.maxFileSize = maxFileSize;
-  }
-
-  /**
-   * Set the maximum size that the output file is allowed to reach before being
-   * rolled over to backup files.
-   * <p>
-   * In configuration files, the <b>MaxFileSize</b> option takes an long 
integer
-   * in the range 0 - 2^63. You can specify the value with the suffixes "KB",
-   * "MB" or "GB" so that the integer is interpreted being expressed
-   * respectively in kilobytes, megabytes or gigabytes. For example, the value
-   * "10KB" will be interpreted as 10240.
-   */
-  public void setMaxFileSize(String value) {
-    maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1);
-  }
-
-  protected void setQWForFiles(Writer writer) {
-    this.qw = new CountingQuietWriter(writer, errorHandler);
-  }
-
-  /**
-   * This method differentiates RollingFileAppender from its super class.
-   */
-  protected void subAppend(LoggingEvent event) {
-    super.subAppend(event);
-
-    if (fileName != null && qw != null) {
-      long size = ((CountingQuietWriter) qw).getCount();
-      if (size >= maxFileSize && size >= nextRollover) {
-        rollOver();
-      }
-    }
-  }
-
-  // Mangled file name. Append the current timestamp
-  private static String getLogFileName(String oldFileName) {
-    return oldFileName + "." + Long.toString(System.currentTimeMillis());
-  }
-}

http://git-wip-us.apache.org/repos/asf/hive/blob/1b4baf47/ql/src/java/org/apache/hadoop/hive/ql/log/SlidingFilenameRolloverStrategy.java
----------------------------------------------------------------------
diff --git 
a/ql/src/java/org/apache/hadoop/hive/ql/log/SlidingFilenameRolloverStrategy.java
 
b/ql/src/java/org/apache/hadoop/hive/ql/log/SlidingFilenameRolloverStrategy.java
new file mode 100644
index 0000000..c0d58c4
--- /dev/null
+++ 
b/ql/src/java/org/apache/hadoop/hive/ql/log/SlidingFilenameRolloverStrategy.java
@@ -0,0 +1,82 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.hadoop.hive.ql.log;
+
+import java.io.IOException;
+
+import 
org.apache.logging.log4j.core.appender.rolling.DirectFileRolloverStrategy;
+import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;
+import org.apache.logging.log4j.core.appender.rolling.RolloverDescription;
+import org.apache.logging.log4j.core.appender.rolling.RolloverDescriptionImpl;
+import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
+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.config.Configuration;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+
+/**
+ * A RolloverStrategy that does not rename files and
+ * uses file names that are based on a millisecond timestamp.
+ */
+@Plugin(name = "SlidingFilenameRolloverStrategy",
+    category = "Core",
+    printObject = true)
+public class SlidingFilenameRolloverStrategy
+    implements RolloverStrategy, DirectFileRolloverStrategy {
+
+  @PluginFactory
+  public static SlidingFilenameRolloverStrategy createStrategy(
+      @PluginConfiguration Configuration config) {
+    return new SlidingFilenameRolloverStrategy();
+  }
+
+  /**
+   * Do rollover with no renaming.
+   */
+  @Override
+  public RolloverDescription rollover(RollingFileManager manager)
+      throws SecurityException {
+    Action shiftToNextActiveFile = new AbstractAction() {
+      @Override
+      public boolean execute() throws IOException {
+        return true;
+      }
+    };
+    return new RolloverDescriptionImpl("ignored", false, shiftToNextActiveFile,
+        null);
+  }
+
+  /**
+   * Get the new log file name.
+   */
+  @Override
+  public String getCurrentFileName(RollingFileManager rollingFileManager) {
+    String pattern = rollingFileManager.getPatternProcessor().getPattern();
+    return getLogFileName(pattern);
+  }
+
+  /**
+   * @return Mangled file name formed by appending the current timestamp
+   */
+  private static String getLogFileName(String oldFileName) {
+    return oldFileName + "." + Long.toString(System.currentTimeMillis());
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/1b4baf47/ql/src/test/org/apache/hadoop/hive/ql/log/TestSlidingFilenameRolloverStrategy.java
----------------------------------------------------------------------
diff --git 
a/ql/src/test/org/apache/hadoop/hive/ql/log/TestSlidingFilenameRolloverStrategy.java
 
b/ql/src/test/org/apache/hadoop/hive/ql/log/TestSlidingFilenameRolloverStrategy.java
new file mode 100644
index 0000000..ea5dec0
--- /dev/null
+++ 
b/ql/src/test/org/apache/hadoop/hive/ql/log/TestSlidingFilenameRolloverStrategy.java
@@ -0,0 +1,145 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.hadoop.hive.ql.log;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.hive.ql.hooks.LineageLogger;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Test configuration and use of SlidingFilenameRolloverStrategy
+ * @see SlidingFilenameRolloverStrategy
+ */
+public class TestSlidingFilenameRolloverStrategy {
+  // properties file used to configure log4j2
+  private static final String PROPERTIES_FILE =
+      "log4j2_test_sliding_rollover.properties";
+
+  //  file pattern that is set in PROPERTIES_FILE
+  private static final String FILE_PATTERN = 
"./target/tmp/log/slidingTest.log";
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    System.setProperty("log4j.configurationFile", PROPERTIES_FILE);
+  }
+
+  @AfterClass
+  public static void tearDown() {
+    System.clearProperty("log4j.configurationFile");
+    LogManager.shutdown();
+  }
+
+  @Test
+  public void testSlidingLogFiles() throws Exception {
+    assertEquals("bad props file", PROPERTIES_FILE,
+        System.getProperty("log4j.configurationFile"));
+
+    // Where the log files wll be written
+    Path logTemplate = FileSystems.getDefault().getPath(FILE_PATTERN);
+    String fileName = logTemplate.getFileName().toString();
+    Path parent = logTemplate.getParent();
+    try {
+      Files.createDirectory(parent);
+    } catch (FileAlreadyExistsException e) {
+      // OK, fall through.
+    }
+
+    // Delete any stale log files left around from previous failed tests
+    deleteLogFiles(parent, fileName);
+
+    Logger logger = LogManager.getLogger(LineageLogger.class);
+
+    // Does the logger config look correct?
+    org.apache.logging.log4j.core.Logger coreLogger =
+        (org.apache.logging.log4j.core.Logger) logger;
+    LoggerConfig loggerConfig = coreLogger.get();
+    Map<String, Appender> appenders = loggerConfig.getAppenders();
+
+    assertNotNull("sliding appender is missing", appenders.get("sliding"));
+
+    // Do some logging and force log rollover
+    int NUM_LOGS = 7;
+    logger.debug("Debug Message Logged !!!");
+    logger.info("Info Message Logged !!!");
+
+    String errorString = "Error Message Logged ";
+    for (int i = 0; i < NUM_LOGS; i++) {
+      TimeUnit.MILLISECONDS.sleep(100);
+      // log an exception - this produces enough text to force a new logfile
+      // (as appender.sliding.policies.size.size=1KB)
+      logger.error(errorString + i,
+          new RuntimeException("part of a test"));
+    }
+
+    // Check log files look OK
+    DirectoryStream<Path> stream =
+        Files.newDirectoryStream(parent, fileName + ".*");
+    int count = 0;
+    for (Path path : stream) {
+      count++;
+      String contents = new String(Files.readAllBytes(path), "UTF-8");
+      // There should be one exception message per file
+      assertTrue("File " + path + " did not have expected content",
+          contents.contains(errorString));
+      String suffix = StringUtils.substringAfterLast(path.toString(), ".");
+      // suffix should be a timestamp
+      try {
+        long timestamp = Long.parseLong(suffix);
+      } catch (NumberFormatException e) {
+        fail("Suffix " + suffix + " is not a long");
+      }
+    }
+    assertEquals("bad count of log files", NUM_LOGS, count);
+
+    // Check there is no log file without the suffix
+    assertFalse("file should not exist:" + logTemplate,
+        Files.exists(logTemplate));
+
+    // Clean up
+    deleteLogFiles(parent, fileName);
+  }
+
+  private void deleteLogFiles(Path parent, String fileName) throws IOException 
{
+    DirectoryStream<Path> stream =
+        Files.newDirectoryStream(parent, fileName + ".*");
+    for (Path path : stream) {
+      Files.delete(path);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/1b4baf47/ql/src/test/resources/log4j2_test_sliding_rollover.properties
----------------------------------------------------------------------
diff --git a/ql/src/test/resources/log4j2_test_sliding_rollover.properties 
b/ql/src/test/resources/log4j2_test_sliding_rollover.properties
new file mode 100644
index 0000000..b88b79a
--- /dev/null
+++ b/ql/src/test/resources/log4j2_test_sliding_rollover.properties
@@ -0,0 +1,69 @@
+# 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.
+
+
+# Log4j2 config that is used by TestSlidingFilenameRolloverStrategy
+
+status = INFO
+name = Slider
+packages = org.apache.hadoop.hive.ql.log
+
+# list of properties
+property.hive.log.level = DEBUG
+property.hive.root.logger = console
+property.hive.log.dir = ${sys:test.tmp.dir}/log
+property.hive.log.file = hive.log
+property.hive.test.console.log.level = INFO
+
+# list of all appenders
+appenders = console, sliding
+
+# list of loggers that are not root
+loggers = lineage
+
+# console appender
+appender.console.type = Console
+appender.console.name = console
+appender.console.target = SYSTEM_ERR
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d{ISO8601} %5p [%t] %c{2}: %m%n
+
+# root logger
+rootLogger.level = ${sys:hive.log.level}
+rootLogger.appenderRefs = root, console
+rootLogger.appenderRef.root.ref = ${sys:hive.root.logger}
+rootLogger.appenderRef.console.ref = console
+rootLogger.appenderRef.console.level = ${sys:hive.test.console.log.level}
+
+# sliding appender
+appender.sliding.type = RollingFile
+appender.sliding.name = sliding
+appender.sliding.filePattern = ./target/tmp/log/slidingTest.log
+appender.sliding.layout.type = PatternLayout
+appender.sliding.layout.pattern =  %m%n
+appender.sliding.layout.charset = UTF-8
+appender.sliding.policies.type = Policies
+appender.sliding.policies.size.type = SizeBasedTriggeringPolicy
+appender.sliding.policies.size.size=1KB
+appender.sliding.strategy.type = SlidingFilenameRolloverStrategy
+
+# lineage logger
+logger.lineage.name = org.apache.hadoop.hive.ql.hooks.LineageLogger
+logger.lineage.level = debug
+logger.lineage.appenderRefs = sliding
+logger.lineage.appenderRef.file.ref = sliding
+
+

http://git-wip-us.apache.org/repos/asf/hive/blob/1b4baf47/testutils/ptest2/pom.xml
----------------------------------------------------------------------
diff --git a/testutils/ptest2/pom.xml b/testutils/ptest2/pom.xml
index 8563b54..e364817 100644
--- a/testutils/ptest2/pom.xml
+++ b/testutils/ptest2/pom.xml
@@ -26,7 +26,7 @@ limitations under the License.
   <name>hive-ptest</name>
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <log4j2.version>2.6.2</log4j2.version>
+    <log4j2.version>2.8.2</log4j2.version>
     <spring.framework.version>3.2.16.RELEASE</spring.framework.version>
     <jclouds.version>2.0.0</jclouds.version>
     <checkstyle.conf.dir>${basedir}/../../checkstyle/</checkstyle.conf.dir>

Reply via email to