You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sr...@apache.org on 2014/08/07 03:20:15 UTC

git commit: SENTRY-346: Create new FileAppender used in log4j to keep all the logs ( Colin Ma via Sravya Tirukkovalur)

Repository: incubator-sentry
Updated Branches:
  refs/heads/master 7e3f287ca -> 3be10df92


SENTRY-346: Create new FileAppender used in log4j to keep all the logs ( Colin Ma via Sravya Tirukkovalur)


Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/3be10df9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/3be10df9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/3be10df9

Branch: refs/heads/master
Commit: 3be10df92c92e39e4d91ff2114f3f72783926e82
Parents: 7e3f287
Author: Sravya Tirukkovalur <sr...@clouera.com>
Authored: Wed Aug 6 18:19:18 2014 -0700
Committer: Sravya Tirukkovalur <sr...@clouera.com>
Committed: Wed Aug 6 18:19:18 2014 -0700

----------------------------------------------------------------------
 .../RollingFileWithoutDeleteAppender.java       | 195 +++++++++++++++++++
 .../TestRollingFileWithoutDeleteAppender.java   |  83 ++++++++
 2 files changed, 278 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/3be10df9/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/appender/RollingFileWithoutDeleteAppender.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/appender/RollingFileWithoutDeleteAppender.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/appender/RollingFileWithoutDeleteAppender.java
new file mode 100644
index 0000000..edbd160
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/appender/RollingFileWithoutDeleteAppender.java
@@ -0,0 +1,195 @@
+/**
+ * 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.sentry.provider.db.log.appender;
+
+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 RollingFileWithoutDeleteAppender 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 RollingFileWithoutDeleteAppender() {
+    super();
+  }
+
+  /**
+   * Instantiate a RollingFileAppender and open the file designated by
+   * <code>filename</code>. The opened filename will become the ouput
+   * destination for this appender.
+   * <p>
+   * If the <code>append</code> parameter is true, the file will be appended to.
+   * Otherwise, the file desginated by <code>filename</code> will be truncated
+   * before being opened.
+   */
+  public RollingFileWithoutDeleteAppender(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 RollingFileWithoutDeleteAppender(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 behaviour.
+   * <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 alreasy synched
+  public void rollOver() {
+    File target;
+    File file;
+    String suffix = Long.toString(System.currentTimeMillis());
+
+    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;
+    }
+
+    boolean renameSucceeded = true;
+
+    // Rename fileName to fileName.yyyyMMddHHmmss
+    target = new File(fileName + "." + suffix);
+
+    this.closeFile(); // keep windows happy.
+
+    file = new File(fileName);
+    LogLog.debug("Renaming file " + file + " to " + target);
+    renameSucceeded = file.renameTo(target);
+    //
+    // if file rename failed, reopen file with append = true
+    //
+    if (!renameSucceeded) {
+      try {
+        this.setFile(fileName, true, bufferedIO, bufferSize);
+      } catch (IOException e) {
+        if (e instanceof InterruptedIOException) {
+          Thread.currentThread().interrupt();
+        }
+        LogLog.error("setFile(" + fileName + ", true) call failed.", e);
+      }
+    } else {
+      try {
+        // This will also close the file. This is OK since multiple
+        // close operations are safe.
+        this.setFile(fileName, false, bufferedIO, bufferSize);
+        nextRollover = 0;
+      } catch (IOException e) {
+        if (e instanceof InterruptedIOException) {
+          Thread.currentThread().interrupt();
+        }
+        LogLog.error("setFile(" + fileName + ", false) call failed.", e);
+      }
+    }
+  }
+
+  public synchronized void setFile(String fileName, boolean append,
+      boolean bufferedIO, int bufferSize) throws IOException {
+    super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
+    if (append) {
+      File f = new File(fileName);
+      ((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();
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/3be10df9/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/appender/TestRollingFileWithoutDeleteAppender.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/appender/TestRollingFileWithoutDeleteAppender.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/appender/TestRollingFileWithoutDeleteAppender.java
new file mode 100644
index 0000000..15393da
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/appender/TestRollingFileWithoutDeleteAppender.java
@@ -0,0 +1,83 @@
+/**
+ * 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.sentry.provider.db.log.appender;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.fail;
+
+import java.io.File;
+
+import junit.framework.ComparisonFailure;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Files;
+
+public class TestRollingFileWithoutDeleteAppender {
+  private Logger sentryLogger = Logger.getRootLogger();
+  private File dataDir;
+
+  @Before
+  public void init() {
+    dataDir = Files.createTempDir();
+  }
+
+  @Test
+  public void testRollOver() throws Throwable {
+    if (dataDir == null) {
+      fail("Excepted temp folder for audit log is created.");
+    }
+    RollingFileWithoutDeleteAppender appender = new RollingFileWithoutDeleteAppender(
+        new PatternLayout("%m%n"), dataDir.getPath() + "/auditLog.log");
+    appender.setMaximumFileSize(100);
+    sentryLogger.addAppender(appender);
+    // Write exactly 10 bytes with each log
+    for (int i = 0; i < 99; i++) {
+      if (i < 10) {
+        sentryLogger.debug("Hello---" + i);
+      } else if (i < 100) {
+        sentryLogger.debug("Hello--" + i);
+      }
+    }
+
+    if (dataDir != null) {
+      File[] files = dataDir.listFiles();
+      if (files != null) {
+        assertEquals(files.length, 10);
+      } else {
+        fail("Excepted 10 log files.");
+      }
+    } else {
+      fail("Excepted 10 log files.");
+    }
+
+  }
+
+  @After
+  public void destroy() {
+    if (dataDir != null) {
+      FileUtils.deleteQuietly(dataDir);
+    }
+  }
+}