Convert logs code to use Path

Tested:
-Ran server with file-based logs.
-Changed log compression frequency to every 10s and observed logs
 being compressed.

Change-Id: I813002d483cac4be376001da8cfec6bbb3f04e99
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java b/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java
index ef24201..2335b8d1 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/FileUtil.java
@@ -86,6 +86,15 @@
     }
   }
 
+  public static Path mkdirsOrDie(Path p, String errMsg) {
+    try {
+      Files.createDirectories(p);
+      return p;
+    } catch (IOException e) {
+      throw new Die(errMsg + ": " + p, e);
+    }
+  }
+
   private FileUtil() {
   }
 }
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/ErrorLogFile.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/ErrorLogFile.java
index c947ac3..3b1714e 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/ErrorLogFile.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/ErrorLogFile.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.pgm.util;
 
-import com.google.gerrit.common.Die;
+import com.google.gerrit.common.FileUtil;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.util.SystemLog;
@@ -25,7 +25,6 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.PatternLayout;
 
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.nio.file.Path;
 
@@ -50,10 +49,8 @@
 
   public static LifecycleListener start(final Path sitePath)
       throws FileNotFoundException {
-    final File logdir = new SitePaths(sitePath).logs_dir;
-    if (!logdir.exists() && !logdir.mkdirs()) {
-      throw new Die("Cannot create log directory: " + logdir);
-    }
+    Path logdir = FileUtil.mkdirsOrDie(new SitePaths(sitePath).logs_dir,
+        "Cannot create log directory");
     if (SystemLog.shouldConfigure()) {
       initLogSystem(logdir);
     }
@@ -70,7 +67,7 @@
     };
   }
 
-  private static void initLogSystem(final File logdir) {
+  private static void initLogSystem(Path logdir) {
     final Logger root = LogManager.getRootLogger();
     root.removeAllAppenders();
     root.addAppender(SystemLog.createAppender(logdir, LOG_NAME,
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/GarbageCollectionLogFile.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/GarbageCollectionLogFile.java
index 3a8223c..3d2b8e1 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/GarbageCollectionLogFile.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/GarbageCollectionLogFile.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.pgm.util;
 
-import com.google.gerrit.common.Die;
+import com.google.gerrit.common.FileUtil;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.git.GarbageCollection;
@@ -24,18 +24,14 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.PatternLayout;
 
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.nio.file.Path;
 
 public class GarbageCollectionLogFile {
-
   public static LifecycleListener start(Path sitePath)
       throws FileNotFoundException {
-    File logdir = new SitePaths(sitePath).logs_dir;
-    if (!logdir.exists() && !logdir.mkdirs()) {
-      throw new Die("Cannot create log directory: " + logdir);
-    }
+    Path logdir = FileUtil.mkdirsOrDie(new SitePaths(sitePath).logs_dir,
+        "Cannot create log directory");
     if (SystemLog.shouldConfigure()) {
       initLogSystem(logdir);
     }
@@ -52,7 +48,7 @@
     };
   }
 
-  private static void initLogSystem(File logdir) {
+  private static void initLogSystem(Path logdir) {
     Logger gcLogger = LogManager.getLogger(GarbageCollection.LOG_NAME);
     gcLogger.removeAllAppenders();
     gcLogger.addAppender(SystemLog.createAppender(logdir,
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/LogFileCompressor.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/LogFileCompressor.java
index db74ac3..1107208 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/LogFileCompressor.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/LogFileCompressor.java
@@ -16,6 +16,7 @@
 
 import static java.util.concurrent.TimeUnit.HOURS;
 
+import com.google.common.io.ByteStreams;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.lifecycle.LifecycleModule;
 import com.google.gerrit.server.config.SitePaths;
@@ -25,12 +26,12 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.zip.GZIPOutputStream;
 
 /** Compresses the old error logs. */
@@ -65,76 +66,78 @@
     }
   }
 
-  private final File logs_dir;
+  private final Path logs_dir;
 
   @Inject
   LogFileCompressor(final SitePaths site) {
     logs_dir = resolve(site.logs_dir);
   }
 
-  private static File resolve(final File logs_dir) {
+  private static Path resolve(Path p) {
     try {
-      return logs_dir.getCanonicalFile();
+      return p.toRealPath().normalize();
     } catch (IOException e) {
-      return logs_dir.getAbsoluteFile();
+      return p.toAbsolutePath().normalize();
     }
   }
 
   @Override
   public void run() {
-    final File[] list = logs_dir.listFiles();
-    if (list == null) {
+    if (!Files.isDirectory(logs_dir)) {
       return;
     }
-
-    for (final File entry : list) {
-      if (!isLive(entry) && !isCompressed(entry) && isLogFile(entry)) {
-        compress(entry);
+    try (DirectoryStream<Path> list = Files.newDirectoryStream(logs_dir)) {
+      for (Path entry : list) {
+        if (!isLive(entry) && !isCompressed(entry) && isLogFile(entry)) {
+          compress(entry);
+        }
       }
+    } catch (IOException e) {
+      log.error("Error listing logs to compress in " + logs_dir, e);
     }
   }
 
-  private boolean isLive(final File entry) {
-    final String name = entry.getName();
+  private boolean isLive(Path entry) {
+    String name = entry.getFileName().toString();
     return name.endsWith("_log")
         || name.endsWith(".log")
         || name.endsWith(".run")
         || name.endsWith(".pid");
   }
 
-  private boolean isCompressed(final File entry) {
-    final String name = entry.getName();
+  private boolean isCompressed(Path entry) {
+    String name = entry.getFileName().toString();
     return name.endsWith(".gz") //
         || name.endsWith(".zip") //
         || name.endsWith(".bz2");
   }
 
-  private boolean isLogFile(final File entry) {
-    return entry.isFile();
+  private boolean isLogFile(Path entry) {
+    return Files.isRegularFile(entry);
   }
 
-  private void compress(final File src) {
-    final File dir = src.getParentFile();
-    final File dst = new File(dir, src.getName() + ".gz");
-    final File tmp = new File(dir, ".tmp." + src.getName());
+  private void compress(Path src) {
+    Path dst = src.resolveSibling(src.getFileName() + ".gz");
+    Path tmp = src.resolveSibling(".tmp." + src.getFileName());
     try {
-      try (InputStream in = new FileInputStream(src);
-          FileOutputStream fo = new FileOutputStream(tmp);
-          OutputStream out = new GZIPOutputStream(fo)) {
-        final byte[] buf = new byte[2048];
-        int n;
-        while (0 < (n = in.read(buf))) {
-          out.write(buf, 0, n);
-        }
-        tmp.setReadOnly();
+      try (InputStream in = Files.newInputStream(src);
+          OutputStream out = new GZIPOutputStream(Files.newOutputStream(tmp))) {
+        ByteStreams.copy(in, out);
       }
-      if (!tmp.renameTo(dst)) {
-        throw new IOException("Cannot rename " + tmp + " to " + dst);
+      tmp.toFile().setReadOnly();
+      try {
+        Files.move(tmp, dst);
+      } catch (IOException e) {
+        throw new IOException("Cannot rename " + tmp + " to " + dst, e);
       }
-      src.delete();
+      Files.delete(src);
     } catch (IOException e) {
       log.error("Cannot compress " + src, e);
-      tmp.delete();
+      try {
+        Files.deleteIfExists(tmp);
+      } catch (IOException e2) {
+        log.warn("Failed to delete temporary log file " + tmp, e2);
+      }
     }
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
index 5cfcc04..1b8f373 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
@@ -34,7 +34,7 @@
   public final Path etc_dir;
   public final Path lib_dir;
   public final Path tmp_dir;
-  public final File logs_dir;
+  public final Path logs_dir;
   public final Path plugins_dir;
   public final Path data_dir;
   public final File mail_dir;
@@ -76,7 +76,7 @@
     tmp_dir = p.resolve("tmp");
     plugins_dir = p.resolve("plugins");
     data_dir = p.resolve("data");
-    logs_dir = new File(site_path, "logs");
+    logs_dir = p.resolve("logs");
     mail_dir = etc_dir.resolve("mail").toFile();
     hooks_dir = new File(site_path, "hooks");
     static_dir = new File(site_path, "static");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/util/SystemLog.java b/gerrit-server/src/main/java/com/google/gerrit/server/util/SystemLog.java
index ba31f56..d4b8457 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/util/SystemLog.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/util/SystemLog.java
@@ -33,8 +33,8 @@
 import org.eclipse.jgit.lib.Config;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
 
 @Singleton
 public class SystemLog {
@@ -55,12 +55,12 @@
     return Strings.isNullOrEmpty(System.getProperty(LOG4J_CONFIGURATION));
   }
 
-  public static Appender createAppender(File logdir, String name, Layout layout) {
+  public static Appender createAppender(Path logdir, String name, Layout layout) {
     final DailyRollingFileAppender dst = new DailyRollingFileAppender();
     dst.setName(name);
     dst.setLayout(layout);
     dst.setEncoding("UTF-8");
-    dst.setFile(new File(resolve(logdir), name).getPath());
+    dst.setFile(resolve(logdir).resolve(name).toString());
     dst.setImmediateFlush(true);
     dst.setAppend(true);
     dst.setErrorHandler(new DieErrorHandler());
@@ -90,11 +90,11 @@
     return async;
   }
 
-  private static File resolve(final File logs_dir) {
+  private static Path resolve(Path p) {
     try {
-      return logs_dir.getCanonicalFile();
+      return p.toRealPath().normalize();
     } catch (IOException e) {
-      return logs_dir.getAbsoluteFile();
+      return p.toAbsolutePath().normalize();
     }
   }