You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by br...@apache.org on 2016/11/30 18:04:59 UTC

nifi-minifi git commit: MINIFI-126 Migrating improvements made in NiFi bootstrap

Repository: nifi-minifi
Updated Branches:
  refs/heads/master 66595772e -> 5ac121fae


MINIFI-126 Migrating improvements made in NiFi bootstrap

This closes #59

Signed-off-by: Bryan Rosander <br...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/nifi-minifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi-minifi/commit/5ac121fa
Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi/tree/5ac121fa
Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi/diff/5ac121fa

Branch: refs/heads/master
Commit: 5ac121faea8efcc6c16a7e1e836549d339a478d8
Parents: 6659577
Author: Joseph Percivall <JP...@apache.org>
Authored: Mon Nov 28 18:13:34 2016 -0500
Committer: Bryan Rosander <br...@apache.org>
Committed: Wed Nov 30 13:02:24 2016 -0500

----------------------------------------------------------------------
 .../nifi/minifi/bootstrap/BootstrapCodec.java   |   2 +-
 .../apache/nifi/minifi/bootstrap/RunMiNiFi.java | 193 +++++++++++++------
 .../nifi/minifi/bootstrap/ShutdownHook.java     |  10 +-
 .../bootstrap/util/ConfigTransformer.java       |   1 +
 .../src/main/resources/bin/dump-minifi.bat      |   6 +-
 .../src/main/resources/bin/minifi-env.bat       |  29 +++
 .../src/main/resources/bin/minifi-env.sh        |  28 +++
 .../src/main/resources/bin/minifi.sh            | 132 ++++++++++---
 .../src/main/resources/bin/run-minifi.bat       |   6 +-
 .../src/main/resources/bin/status-minifi.bat    |   4 +-
 .../src/main/resources/conf/logback.xml         |  10 +-
 11 files changed, 325 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/BootstrapCodec.java
----------------------------------------------------------------------
diff --git a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/BootstrapCodec.java b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/BootstrapCodec.java
index 2e8a537..6e8ae91 100644
--- a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/BootstrapCodec.java
+++ b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/BootstrapCodec.java
@@ -85,7 +85,7 @@ public class BootstrapCodec {
 
                 final String secretKey = args[1];
 
-                runner.setNiFiCommandControlPort(port, secretKey);
+                runner.setMiNiFiCommandControlPort(port, secretKey);
                 writer.write("OK");
                 writer.newLine();
                 writer.flush();

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
----------------------------------------------------------------------
diff --git a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
index 52a803c..9ac7e23 100644
--- a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
+++ b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
@@ -64,6 +64,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.commons.io.input.TeeInputStream;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.minifi.bootstrap.configuration.ConfigurationChangeException;
 import org.apache.nifi.minifi.bootstrap.configuration.ConfigurationChangeListener;
 import org.apache.nifi.minifi.bootstrap.status.PeriodicStatusReporter;
@@ -73,6 +74,7 @@ import org.apache.nifi.minifi.commons.status.FlowStatusReport;
 import org.apache.nifi.stream.io.ByteArrayInputStream;
 import org.apache.nifi.stream.io.ByteArrayOutputStream;
 import org.apache.nifi.util.Tuple;
+import org.apache.nifi.util.file.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -98,6 +100,8 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
     public static final String DEFAULT_CONFIG_FILE = "./conf/bootstrap.conf";
     public static final String DEFAULT_NIFI_PROPS_FILE = "./conf/nifi.properties";
     public static final String DEFAULT_JAVA_CMD = "java";
+    public static final String DEFAULT_PID_DIR = "bin";
+    public static final String DEFAULT_LOG_DIR = "./logs";
 
 
     public static final String CONF_DIR_KEY = "conf.dir";
@@ -107,9 +111,14 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
     public static final String GRACEFUL_SHUTDOWN_PROP = "graceful.shutdown.seconds";
     public static final String DEFAULT_GRACEFUL_SHUTDOWN_VALUE = "20";
 
-    public static final String RUN_AS_PROP = "run.as";
+    public static final String MINIFI_PID_DIR_PROP = "org.apache.nifi.minifi.bootstrap.config.pid.dir";
+
+    public static final String MINIFI_PID_FILE_NAME = "minifi.pid";
+    public static final String MINIFI_STATUS_FILE_NAME = "minifi.status";
+    public static final String MINIFI_LOCK_FILE_NAME = "minifi.lock";
+
+    public static final String PID_KEY = "pid";
 
-    public static final int MAX_RESTART_ATTEMPTS = 5;
     public static final int STARTUP_WAIT_SECONDS = 60;
 
     public static final String SHUTDOWN_CMD = "SHUTDOWN";
@@ -126,7 +135,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
 
     private volatile boolean autoRestartNiFi = true;
     private volatile int ccPort = -1;
-    private volatile long nifiPid = -1L;
+    private volatile long minifiPid = -1L;
     private volatile String secretKey;
     private volatile ShutdownHook shutdownHook;
     private volatile boolean nifiStarted;
@@ -229,6 +238,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         final File configFile = getBootstrapConfFile();
         final RunMiNiFi runMiNiFi = new RunMiNiFi(configFile);
 
+        Integer exitStatus = null;
         switch (cmd.toLowerCase()) {
             case "start":
                 runMiNiFi.start();
@@ -240,7 +250,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
                 runMiNiFi.stop();
                 break;
             case "status":
-                runMiNiFi.status();
+                exitStatus = runMiNiFi.status();
                 break;
             case "restart":
                 runMiNiFi.stop();
@@ -260,6 +270,9 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
                 }
                 break;
         }
+        if (exitStatus != null) {
+            System.exit(exitStatus);
+        }
     }
 
     private static File getBootstrapConfFile() {
@@ -282,29 +295,41 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         return configFile;
     }
 
-    File getStatusFile() {
-        return getStatusFile(defaultLogger);
-    }
+    private File getBootstrapFile(final Logger logger, String directory, String defaultDirectory, String fileName) throws IOException {
 
-    public File getStatusFile(final Logger logger) {
         final File confDir = bootstrapConfigFile.getParentFile();
         final File nifiHome = confDir.getParentFile();
-        final File bin = new File(nifiHome, "bin");
-        final File statusFile = new File(bin, "minifi.pid");
 
-        logger.debug("Status File: {}", statusFile);
+        String confFileDir = System.getProperty(directory);
 
+        final File fileDir;
+
+        if (confFileDir != null) {
+            fileDir = new File(confFileDir.trim());
+        } else {
+            fileDir = new File(nifiHome, defaultDirectory);
+        }
+
+        FileUtils.ensureDirectoryExistAndCanAccess(fileDir);
+        final File statusFile = new File(fileDir, fileName);
+        logger.debug("Status File: {}", statusFile);
         return statusFile;
     }
 
-    public File getLockFile(final Logger logger) {
-        final File confDir = bootstrapConfigFile.getParentFile();
-        final File nifiHome = confDir.getParentFile();
-        final File bin = new File(nifiHome, "bin");
-        final File lockFile = new File(bin, "minifi.lock");
+    File getPidFile(final Logger logger) throws IOException {
+        return getBootstrapFile(logger, MINIFI_PID_DIR_PROP, DEFAULT_PID_DIR, MINIFI_PID_FILE_NAME);
+    }
+
+    File getStatusFile(final Logger logger) throws IOException {
+        return getBootstrapFile(logger, MINIFI_PID_DIR_PROP, DEFAULT_PID_DIR, MINIFI_STATUS_FILE_NAME);
+    }
+
+    File getLockFile(final Logger logger) throws IOException {
+        return getBootstrapFile(logger, MINIFI_PID_DIR_PROP, DEFAULT_PID_DIR, MINIFI_LOCK_FILE_NAME);
+    }
 
-        logger.debug("Lock File: {}", lockFile);
-        return lockFile;
+    File getStatusFile() throws IOException{
+        return getStatusFile(defaultLogger);
     }
 
     public File getReloadFile(final Logger logger) {
@@ -345,7 +370,12 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         return props;
     }
 
-    private synchronized void saveProperties(final Properties nifiProps, final Logger logger) throws IOException {
+    private synchronized void saveProperties(final Properties minifiProps, final Logger logger) throws IOException {
+        final String pid = minifiProps.getProperty(PID_KEY);
+        if (!StringUtils.isBlank(pid)) {
+            writePidFile(pid, logger);
+        }
+
         final File statusFile = getStatusFile(logger);
         if (statusFile.exists() && !statusFile.delete()) {
             logger.warn("Failed to delete {}", statusFile);
@@ -357,8 +387,10 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
 
         try {
             final Set<PosixFilePermission> perms = new HashSet<>();
-            perms.add(PosixFilePermission.OWNER_READ);
             perms.add(PosixFilePermission.OWNER_WRITE);
+            perms.add(PosixFilePermission.OWNER_READ);
+            perms.add(PosixFilePermission.GROUP_READ);
+            perms.add(PosixFilePermission.OTHERS_READ);
             Files.setPosixFilePermissions(statusFile.toPath(), perms);
         } catch (final Exception e) {
             logger.warn("Failed to set permissions so that only the owner can read status file {}; "
@@ -367,11 +399,40 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         }
 
         try (final FileOutputStream fos = new FileOutputStream(statusFile)) {
-            nifiProps.store(fos, null);
+            minifiProps.store(fos, null);
             fos.getFD().sync();
         }
 
-        logger.debug("Saved Properties {} to {}", new Object[]{nifiProps, statusFile});
+        logger.debug("Saved Properties {} to {}", new Object[]{minifiProps, statusFile});
+    }
+
+    private synchronized void writePidFile(final String pid, final Logger logger) throws IOException {
+        final File pidFile = getPidFile(logger);
+        if (pidFile.exists() && !pidFile.delete()) {
+           logger.warn("Failed to delete {}", pidFile);
+        }
+
+        if (!pidFile.createNewFile()) {
+            throw new IOException("Failed to create file " + pidFile);
+        }
+
+        try {
+            final Set<PosixFilePermission> perms = new HashSet<>();
+            perms.add(PosixFilePermission.OWNER_READ);
+            perms.add(PosixFilePermission.OWNER_WRITE);
+            Files.setPosixFilePermissions(pidFile.toPath(), perms);
+        } catch (final Exception e) {
+            logger.warn("Failed to set permissions so that only the owner can read pid file {}; "
+                    + "this may allows others to have access to the key needed to communicate with MiNiFi. "
+                    + "Permissions should be changed so that only the owner can read this file", pidFile);
+        }
+
+        try (final FileOutputStream fos = new FileOutputStream(pidFile)) {
+            fos.write(pid.getBytes(StandardCharsets.UTF_8));
+            fos.getFD().sync();
+        }
+
+        logger.debug("Saved Pid {} to {}", new Object[]{pid, pidFile});
     }
 
     private boolean isPingSuccessful(final int port, final String secretKey, final Logger logger) {
@@ -414,7 +475,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
             return port;
         }
 
-        final String pid = props.getProperty("pid");
+        final String pid = props.getProperty(PID_KEY);
         logger.debug("PID in status file is {}", pid);
         if (pid != null) {
             final boolean procRunning = isProcessRunning(pid, logger);
@@ -477,7 +538,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         }
 
         final String portValue = props.getProperty("port");
-        final String pid = props.getProperty("pid");
+        final String pid = props.getProperty(PID_KEY);
         final String secretKey = props.getProperty("secret.key");
 
         if (portValue == null && pid == null) {
@@ -499,27 +560,27 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
             return new Status(port, pid, true, true);
         }
 
-        final boolean alive = (pid == null) ? false : isProcessRunning(pid, logger);
+        final boolean alive = (pid != null) && isProcessRunning(pid, logger);
         return new Status(port, pid, pingSuccess, alive);
     }
 
-    public void status() throws IOException {
+    public int status() throws IOException {
         final Logger logger = cmdLogger;
         final Status status = getStatus(logger);
         if (status.isRespondingToPing()) {
             logger.info("Apache MiNiFi is currently running, listening to Bootstrap on port {}, PID={}",
                 new Object[]{status.getPort(), status.getPid() == null ? "unknown" : status.getPid()});
-            return;
+            return 0;
         }
 
         if (status.isProcessRunning()) {
             logger.info("Apache MiNiFi is running at PID {} but is not responding to ping requests", status.getPid());
-            return;
+            return 4;
         }
 
         if (status.getPort() == null) {
             logger.info("Apache MiNiFi is not running");
-            return;
+            return 3;
         }
 
         if (status.getPid() == null) {
@@ -527,6 +588,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         } else {
             logger.info("Apache MiNiFi is not running");
         }
+        return 3;
     }
 
     public FlowStatusReport statusReport(String statusRequest) throws IOException {
@@ -618,8 +680,8 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
             return;
         }
 
-        final Properties nifiProps = loadProperties(logger);
-        final String secretKey = nifiProps.getProperty("secret.key");
+        final Properties minifiProps = loadProperties(logger);
+        final String secretKey = minifiProps.getProperty("secret.key");
 
         final StringBuilder sb = new StringBuilder();
         try (final Socket socket = new Socket()) {
@@ -669,9 +731,9 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
             reloadLockFile.createNewFile();
         }
 
-        final Properties nifiProps = loadProperties(logger);
-        final String secretKey = nifiProps.getProperty("secret.key");
-        final String pid = nifiProps.getProperty("pid");
+        final Properties minifiProps = loadProperties(logger);
+        final String secretKey = minifiProps.getProperty("secret.key");
+        final String pid = minifiProps.getProperty(PID_KEY);
 
         try (final Socket socket = new Socket()) {
             logger.debug("Connecting to MiNiFi instance");
@@ -744,7 +806,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
                 logger.error("Failed to send shutdown command to port {} due to {}. No PID found for the MiNiFi process, so unable to kill process; "
                     + "the process should be killed manually.", new Object[]{port, ioe.toString()});
             } else {
-                logger.error("Failed to send shutdown command to port {} due to {}. Will kill the MiNiFi Process with PID {}.", new Object[]{port, ioe.toString(), pid});
+                logger.error("Failed to send shutdown command to port {} due to {}. Will kill the MiNiFi Process with PID {}.", port, ioe.toString(), pid);
                 killProcessTree(pid, logger);
             }
         } finally {
@@ -768,10 +830,11 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
             lockFile.createNewFile();
         }
 
-        final Properties nifiProps = loadProperties(logger);
-        final String secretKey = nifiProps.getProperty("secret.key");
-        final String pid = nifiProps.getProperty("pid");
+        final Properties minifiProps = loadProperties(logger);
+        final String secretKey = minifiProps.getProperty("secret.key");
+        final String pid = minifiProps.getProperty(PID_KEY);
         final File statusFile = getStatusFile(logger);
+        final File pidFile = getPidFile(logger);
 
         try (final Socket socket = new Socket()) {
             logger.debug("Connecting to MiNiFi instance");
@@ -836,6 +899,11 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
                     if (statusFile.exists() && !statusFile.delete()) {
                         logger.error("Failed to delete status file {}; this file should be cleaned up manually", statusFile);
                     }
+
+                    if (pidFile.exists() && !pidFile.delete()) {
+                        logger.error("Failed to delete pid file {}; this file should be cleaned up manually", pidFile);
+                    }
+
                     logger.info("MiNiFi has finished shutting down.");
                 }
             } else {
@@ -868,7 +936,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
     }
 
     private static List<String> getChildProcesses(final String ppid) throws IOException {
-        final Process proc = Runtime.getRuntime().exec(new String[]{"ps", "-o", "pid", "--no-headers", "--ppid", ppid});
+        final Process proc = Runtime.getRuntime().exec(new String[]{"ps", "-o", PID_KEY, "--no-headers", "--ppid", ppid});
         final List<String> childPids = new ArrayList<>();
         try (final InputStream in = proc.getInputStream();
              final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
@@ -984,22 +1052,24 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
             builder.directory(workingDir);
         }
 
+        final String minifiLogDir = replaceNull(System.getProperty("org.apache.nifi.minifi.bootstrap.config.log.dir"), DEFAULT_LOG_DIR).trim();
+
         final String libFilename = replaceNull(props.get("lib.dir"), "./lib").trim();
         File libDir = getFile(libFilename, workingDir);
 
         final String confFilename = replaceNull(props.get(CONF_DIR_KEY), "./conf").trim();
         File confDir = getFile(confFilename, workingDir);
 
-        String nifiPropsFilename = props.get("props.file");
-        if (nifiPropsFilename == null) {
+        String minifiPropsFilename = props.get("props.file");
+        if (minifiPropsFilename == null) {
             if (confDir.exists()) {
-                nifiPropsFilename = new File(confDir, "nifi.properties").getAbsolutePath();
+                minifiPropsFilename = new File(confDir, "nifi.properties").getAbsolutePath();
             } else {
-                nifiPropsFilename = DEFAULT_CONFIG_FILE;
+                minifiPropsFilename = DEFAULT_CONFIG_FILE;
             }
         }
 
-        nifiPropsFilename = nifiPropsFilename.trim();
+        minifiPropsFilename = minifiPropsFilename.trim();
 
         final List<String> javaAdditionalArgs = new ArrayList<>();
         for (final Entry<String, String> entry : props.entrySet()) {
@@ -1068,9 +1138,10 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         cmd.add("-classpath");
         cmd.add(classPath);
         cmd.addAll(javaAdditionalArgs);
-        cmd.add("-Dnifi.properties.file.path=" + nifiPropsFilename);
+        cmd.add("-Dnifi.properties.file.path=" + minifiPropsFilename);
         cmd.add("-Dnifi.bootstrap.listen.port=" + listenPort);
         cmd.add("-Dapp=MiNiFi");
+        cmd.add("-Dorg.apache.nifi.minifi.bootstrap.config.log.dir="+minifiLogDir);
         cmd.add("org.apache.nifi.minifi.MiNiFi");
 
         builder.command(cmd);
@@ -1089,10 +1160,10 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         handleLogging(process);
         Long pid = getPid(process, cmdLogger);
         if (pid != null) {
-            nifiPid = pid;
-            final Properties nifiProps = new Properties();
-            nifiProps.setProperty("pid", String.valueOf(nifiPid));
-            saveProperties(nifiProps, cmdLogger);
+            minifiPid = pid;
+            final Properties minifiProps = new Properties();
+            minifiProps.setProperty(PID_KEY, String.valueOf(minifiPid));
+            saveProperties(minifiProps, cmdLogger);
         }
 
         gracefulShutdownSeconds = getGracefulShutdownSeconds(props, bootstrapConfigAbsoluteFile);
@@ -1218,10 +1289,10 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
 
                         Long pid = getPid(process, defaultLogger);
                         if (pid != null) {
-                            nifiPid = pid;
-                            final Properties nifiProps = new Properties();
-                            nifiProps.setProperty("pid", String.valueOf(nifiPid));
-                            saveProperties(nifiProps, defaultLogger);
+                            minifiPid = pid;
+                            final Properties minifiProps = new Properties();
+                            minifiProps.setProperty(PID_KEY, String.valueOf(minifiPid));
+                            saveProperties(minifiProps, defaultLogger);
                         }
 
                         shutdownHook = new ShutdownHook(process, this, secretKey, gracefulShutdownSeconds, loggingExecutor);
@@ -1326,7 +1397,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
     private Long getPid(final Process process, final Logger logger) {
         try {
             final Class<?> procClass = process.getClass();
-            final Field pidField = procClass.getDeclaredField("pid");
+            final Field pidField = procClass.getDeclaredField(PID_KEY);
             pidField.setAccessible(true);
             final Object pidObject = pidField.get(process);
 
@@ -1388,7 +1459,7 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
         this.autoRestartNiFi = restart;
     }
 
-    void setNiFiCommandControlPort(final int port, final String secretKey) {
+    void setMiNiFiCommandControlPort(final int port, final String secretKey) throws IOException {
         this.ccPort = port;
         this.secretKey = secretKey;
 
@@ -1398,15 +1469,15 @@ public class RunMiNiFi implements QueryableStatusAggregator, ConfigurationFileHo
 
         final File statusFile = getStatusFile(defaultLogger);
 
-        final Properties nifiProps = new Properties();
-        if (nifiPid != -1) {
-            nifiProps.setProperty("pid", String.valueOf(nifiPid));
+        final Properties minifiProps = new Properties();
+        if (minifiPid != -1) {
+            minifiProps.setProperty(PID_KEY, String.valueOf(minifiPid));
         }
-        nifiProps.setProperty("port", String.valueOf(ccPort));
-        nifiProps.setProperty("secret.key", secretKey);
+        minifiProps.setProperty("port", String.valueOf(ccPort));
+        minifiProps.setProperty("secret.key", secretKey);
 
         try {
-            saveProperties(nifiProps, defaultLogger);
+            saveProperties(minifiProps, defaultLogger);
         } catch (final IOException ioe) {
             defaultLogger.warn("Apache MiNiFi has started but failed to persist MiNiFi Port information to {} due to {}", new Object[]{statusFile.getAbsolutePath(), ioe});
         }

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/ShutdownHook.java
----------------------------------------------------------------------
diff --git a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/ShutdownHook.java b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/ShutdownHook.java
index 236a52d..c0060f5 100644
--- a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/ShutdownHook.java
+++ b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/ShutdownHook.java
@@ -107,9 +107,13 @@ public class ShutdownHook extends Thread {
             }
         }
 
-        final File statusFile = runner.getStatusFile();
-        if (!statusFile.delete()) {
-            System.err.println("Failed to delete status file " + statusFile.getAbsolutePath() + "; this file should be cleaned up manually");
+        try {
+            final File statusFile = runner.getStatusFile();
+            if (!statusFile.delete()) {
+                System.err.println("Failed to delete status file " + statusFile.getAbsolutePath() + "; this file should be cleaned up manually");
+            }
+        }catch (IOException ex){
+            System.err.println("Failed to retrieve status file " + ex);
         }
 
         System.out.println("MiNiFi is done shutting down");

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
----------------------------------------------------------------------
diff --git a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
index 3000fc8..def5980 100644
--- a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
+++ b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
@@ -167,6 +167,7 @@ public final class ConfigTransformer {
             writer.println();
             writer.println("nifi.version=" + NIFI_VERSION);
             writer.println("nifi.flow.configuration.file=./conf/flow.xml.gz");
+            writer.println("nifi.flow.configuration.archive.enabled=false");
             writer.println("nifi.flow.configuration.archive.dir=./conf/archive/");
             writer.println("nifi.flowcontroller.autoResumeState=true");
             writer.println("nifi.flowcontroller.graceful.shutdown.period=" + coreProperties.getFlowControllerGracefulShutdownPeriod());

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/dump-minifi.bat
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/dump-minifi.bat b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/dump-minifi.bat
index ecf831f..6e7897b 100644
--- a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/dump-minifi.bat
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/dump-minifi.bat
@@ -16,6 +16,10 @@ rem    See the License for the specific language governing permissions and
 rem    limitations under the License.
 rem
 
+rem Set environment variables
+
+call minifi-env.bat
+
 rem Use JAVA_HOME if it's set; otherwise, just use java
 
 if "%JAVA_HOME%" == "" goto noJavaHome
@@ -38,7 +42,7 @@ set LIB_DIR=lib
 set CONF_DIR=conf
 
 set BOOTSTRAP_CONF_FILE=%CONF_DIR%\bootstrap.conf
-set JAVA_ARGS=-Dorg.apache.nifi.minifi.bootstrap.config.file=%BOOTSTRAP_CONF_FILE%
+set JAVA_ARGS=-Dorg.apache.nifi.minifi.bootstrap.config.log.dir=%MINIFI_LOG_DIR% -Dorg.apache.nifi.minifi.bootstrap.config.pid.dir=%MINIFI_PID_DIR% -Dorg.apache.nifi.minifi.bootstrap.config.file=%BOOTSTRAP_CONF_FILE%
 
 set JAVA_PARAMS=-cp %CONF_DIR%;%BOOTSTRAP_LIB_DIR%\*;%LIB_DIR%\* -Xms12m -Xmx24m %JAVA_ARGS% org.apache.nifi.minifi.bootstrap.RunMiNiFi
 set BOOTSTRAP_ACTION=dump

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.bat
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.bat b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.bat
new file mode 100644
index 0000000..8d1c985
--- /dev/null
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.bat
@@ -0,0 +1,29 @@
+@echo off
+rem
+rem    Licensed to the Apache Software Foundation (ASF) under one or more
+rem    contributor license agreements.  See the NOTICE file distributed with
+rem    this work for additional information regarding copyright ownership.
+rem    The ASF licenses this file to You under the Apache License, Version 2.0
+rem    (the "License"); you may not use this file except in compliance with
+rem    the License.  You may obtain a copy of the License at
+rem
+rem       http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem    Unless required by applicable law or agreed to in writing, software
+rem    distributed under the License is distributed on an "AS IS" BASIS,
+rem    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem    See the License for the specific language governing permissions and
+rem    limitations under the License.
+rem
+
+
+rem The java implementation to use
+rem set JAVA_HOME="C:\Program Files\Java\jdk1.8.0"
+
+set MINIFI_ROOT=%~sdp0..\
+
+rem The directory for the NiFi pid file
+set MINIFI_PID_DIR=%MINIFI_ROOT%\run
+
+rem The directory for NiFi log files
+set MINIFI_LOG_DIR=%MINIFI_ROOT%\logs
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.sh
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.sh b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.sh
new file mode 100644
index 0000000..a9fa1d6
--- /dev/null
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi-env.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+#    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.
+#
+
+# The java implementation to use.
+#export JAVA_HOME=/usr/java/jdk1.8.0/
+
+export MINIFI_HOME=$(cd "${SCRIPT_DIR}" && cd .. && pwd)
+
+#The directory for the NiFi pid file
+export MINIFI_PID_DIR="${MINIFI_HOME}/run"
+
+#The directory for NiFi log files
+export MINIFI_LOG_DIR="${MINIFI_HOME}/logs"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
index 45fabc7..5469382 100755
--- a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
@@ -15,17 +15,38 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 #
-# chkconfig: 2345 20 80
-# description: Apache NiFi - MiNiFi
-#
 
 # Script structure inspired from Apache Karaf and other Apache projects with similar startup approaches
 
-SCRIPT_DIR=$(dirname "$0")
+# Discover the path of the file
+
+
+# Since MacOS X, FreeBSD and some other systems lack gnu readlink, we use a more portable
+# approach based on following StackOverflow comment http://stackoverflow.com/a/1116890/888876
+
+TARGET_FILE=$0
+
+cd $(dirname $TARGET_FILE)
+TARGET_FILE=$(basename $TARGET_FILE)
+
+# Iterate down a (possible) chain of symlinks
+while [ -L "$TARGET_FILE" ]
+do
+    TARGET_FILE=$(readlink $TARGET_FILE)
+    cd $(dirname $TARGET_FILE)
+    TARGET_FILE=$(basename $TARGET_FILE)
+done
+
+# Compute the canonicalized name by finding the physical path
+# for the directory we're in and appending the target file.
+PHYS_DIR=`pwd -P`
+
+SCRIPT_DIR=$PHYS_DIR
 SCRIPT_NAME=$(basename "$0")
-MINIFI_HOME=$(cd "${SCRIPT_DIR}" && cd .. && pwd)
 PROGNAME=$(basename "$0")
 
+. "$SCRIPT_DIR"/minifi-env.sh
+
 
 warn() {
     echo "${PROGNAME}: $*"
@@ -142,22 +163,72 @@ init() {
 
 
 install() {
-        SVC_NAME=minifi
-        if [ "x$2" != "x" ] ; then
-                SVC_NAME=$2
-        fi
+   detectOS
 
-        SVC_FILE="/etc/init.d/${SVC_NAME}"
-        cp "$0" "${SVC_FILE}"
-        sed -i s:MINIFI_HOME=.*:MINIFI_HOME="${MINIFI_HOME}": "${SVC_FILE}"
-        sed -i s:PROGNAME=.*:PROGNAME="${SCRIPT_NAME}": "${SVC_FILE}"
-        rm -f "/etc/rc2.d/S65${SVC_NAME}"
-        ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc2.d/S65${SVC_NAME}"
-        rm -f "/etc/rc2.d/K65${SVC_NAME}"
-        ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc2.d/K65${SVC_NAME}"
-        echo "Service ${SVC_NAME} installed"
-}
+    if [ "${darwin}" = "true"  ] || [ "${cygwin}" = "true" ]; then
+        echo 'Installing Apache MiNiFi as a service is not supported on OS X or Cygwin.'
+        exit 1
+    fi
 
+    SVC_NAME=minifi
+    if [ "x$2" != "x" ] ; then
+        SVC_NAME=$2
+    fi
+
+    initd_dir='/etc/init.d'
+    SVC_FILE="${initd_dir}/${SVC_NAME}"
+
+    if [ ! -w  "${initd_dir}" ]; then
+        echo "Current user does not have write permissions to ${initd_dir}. Cannot install MiNiFi as a service."
+        exit 1
+    fi
+
+# Create the init script, overwriting anything currently present
+cat <<SERVICEDESCRIPTOR > ${SVC_FILE}
+#!/bin/sh
+
+#
+#    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.
+#
+# chkconfig: 2345 20 80
+# description: Apache NiFi is a dataflow system based on the principles of Flow-Based Programming.
+#
+
+# Make use of the configured NIFI_HOME directory and pass service requests to the nifi.sh executable
+MINIFI_HOME=${MINIFI_HOME}
+bin_dir=\${MINIFI_HOME}/bin
+minifi_executable=\${bin_dir}/minifi.sh
+
+\${minifi_executable} "\$@"
+SERVICEDESCRIPTOR
+
+    if [ ! -f "${SVC_FILE}" ]; then
+        echo "Could not create service file ${SVC_FILE}"
+        exit 1
+    fi
+
+    # Provide the user execute access on the file
+    chmod u+x ${SVC_FILE}
+
+    rm -f "/etc/rc2.d/S65${SVC_NAME}"
+    ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc2.d/S65${SVC_NAME}" || { echo "Could not create link /etc/rc2.d/S65${SVC_NAME}"; exit 1; }
+    rm -f "/etc/rc2.d/K65${SVC_NAME}"
+    ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc2.d/K65${SVC_NAME}" || { echo "Could not create link /etc/rc2.d/K65${SVC_NAME}"; exit 1; }
+    echo "Service ${SVC_NAME} installed"
+}
 
 run() {
     BOOTSTRAP_CONF_DIR="${MINIFI_HOME}/conf"
@@ -165,7 +236,7 @@ run() {
     MINIFI_LIBS="${MINIFI_HOME}/lib/*"
     BOOTSTRAP_LIBS="${MINIFI_HOME}/lib/bootstrap/*"
 
-    run_as=$(grep run.as "${BOOTSTRAP_CONF}" | cut -d'=' -f2)
+    run_as=$(grep '^\s*run.as' "${BOOTSTRAP_CONF}" | cut -d'=' -f2)
     # If the run as user is the same as that starting the process, ignore this configuration
     if [ "$run_as" = "$(whoami)" ]; then
         unset run_as
@@ -211,13 +282,24 @@ run() {
     echo "Bootstrap Config File: ${BOOTSTRAP_CONF}"
     echo
 
+
+    #setup directory parameters
+    BOOTSTRAP_LOG_PARAMS="-Dorg.apache.nifi.minifi.bootstrap.config.log.dir="\""${MINIFI_LOG_DIR}"\"""
+    BOOTSTRAP_PID_PARAMS="-Dorg.apache.nifi.minifi.bootstrap.config.pid.dir="\""${MINIFI_PID_DIR}"\"""
+    BOOTSTRAP_CONF_PARAMS="-Dorg.apache.nifi.minifi.bootstrap.config.file="\""${BOOTSTRAP_CONF}"\"""
+
+    BOOTSTRAP_DIR_PARAMS="${BOOTSTRAP_LOG_PARAMS} ${BOOTSTRAP_PID_PARAMS} ${BOOTSTRAP_CONF_PARAMS}"
+
+    RUN_MINIFI_CMD="cd "\""${MINIFI_HOME}"\"" && ${sudo_cmd_prefix} "\""${JAVA}"\"" -cp "\""${BOOTSTRAP_CLASSPATH}"\"" -Xms12m -Xmx24m ${BOOTSTRAP_DIR_PARAMS}  org.apache.nifi.minifi.bootstrap.RunMiNiFi"
+
     # run 'start' in the background because the process will continue to run, monitoring MiNiFi.
     # all other commands will terminate quickly so want to just wait for them
     if [ "$1" = "start" ]; then
-        (cd "${MINIFI_HOME}" && ${sudo_cmd_prefix} "${JAVA}" -cp "${BOOTSTRAP_CLASSPATH}" -Xms12m -Xmx24m -Dorg.apache.nifi.minifi.bootstrap.config.file="${BOOTSTRAP_CONF}" org.apache.nifi.minifi.bootstrap.RunMiNiFi $@ &)
+        (eval $RUN_MINIFI_CMD $@ &)
     else
-        (cd "${MINIFI_HOME}" && ${sudo_cmd_prefix} "${JAVA}" -cp "${BOOTSTRAP_CLASSPATH}" -Xms12m -Xmx24m -Dorg.apache.nifi.minifi.bootstrap.config.file="${BOOTSTRAP_CONF}" org.apache.nifi.minifi.bootstrap.RunMiNiFi $@)
+        (eval $RUN_MINIFI_CMD $@)
     fi
+    EXIT_STATUS=$?
 
     # Wait just a bit (3 secs) to wait for the logging to finish and then echo a new-line.
     # We do this to avoid having logs spewed on the console after running the command and then not giving
@@ -238,11 +320,13 @@ case "$1" in
         ;;
     start|stop|run|status|flowStatus|dump|env)
         main "$@"
+        exit $EXIT_STATUS
         ;;
     restart)
         init
-    run "stop"
-    run "start"
+        run "stop"
+        run "start"
+        exit $EXIT_STATUS
     ;;
     *)
         echo "Usage minifi {start|stop|run|restart|status|flowStatus|dump|install}"

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/run-minifi.bat
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/run-minifi.bat b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/run-minifi.bat
index d0b50d8..7bc5d31 100644
--- a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/run-minifi.bat
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/run-minifi.bat
@@ -16,6 +16,10 @@ rem    See the License for the specific language governing permissions and
 rem    limitations under the License.
 rem
 
+rem Set environment variables
+
+call minifi-env.bat
+
 rem Use JAVA_HOME if it's set; otherwise, just use java
 
 if "%JAVA_HOME%" == "" goto noJavaHome
@@ -38,7 +42,7 @@ set LIB_DIR=lib
 set CONF_DIR=conf
 
 set BOOTSTRAP_CONF_FILE=%CONF_DIR%\bootstrap.conf
-set JAVA_ARGS=-Dorg.apache.nifi.minifi.bootstrap.config.file=%BOOTSTRAP_CONF_FILE%
+set JAVA_ARGS=-Dorg.apache.nifi.minifi.bootstrap.config.log.dir=%MINIFI_LOG_DIR% -Dorg.apache.nifi.minifi.bootstrap.config.pid.dir=%MINIFI_PID_DIR% -Dorg.apache.nifi.minifi.bootstrap.config.file=%BOOTSTRAP_CONF_FILE%
 
 set JAVA_PARAMS=-cp %CONF_DIR%;%BOOTSTRAP_LIB_DIR%\*;%LIB_DIR%\* -Xms12m -Xmx24m %JAVA_ARGS% org.apache.nifi.minifi.bootstrap.RunMiNiFi
 set BOOTSTRAP_ACTION=run

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/status-minifi.bat
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/status-minifi.bat b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/status-minifi.bat
index 5f36259..8189d90 100644
--- a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/status-minifi.bat
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/status-minifi.bat
@@ -16,6 +16,8 @@ rem    See the License for the specific language governing permissions and
 rem    limitations under the License.
 rem
 
+call minifi-env.bat
+
 rem Use JAVA_HOME if it's set; otherwise, just use java
 
 if "%JAVA_HOME%" == "" goto noJavaHome
@@ -38,7 +40,7 @@ set LIB_DIR=lib
 set CONF_DIR=conf
 
 set BOOTSTRAP_CONF_FILE=%CONF_DIR%\bootstrap.conf
-set JAVA_ARGS=-Dorg.apache.nifi.minifi.bootstrap.config.file=%BOOTSTRAP_CONF_FILE%
+set JAVA_ARGS=-Dorg.apache.nifi.minifi.bootstrap.config.log.dir=%MINIFI_LOG_DIR% -Dorg.apache.nifi.minifi.bootstrap.config.pid.dir=%MINIFI_PID_DIR% -Dorg.apache.nifi.minifi.bootstrap.config.file=%BOOTSTRAP_CONF_FILE%
 
 set JAVA_PARAMS=-cp %CONF_DIR%;%BOOTSTRAP_LIB_DIR%\*;%LIB_DIR%\* -Xms12m -Xmx24m %JAVA_ARGS% org.apache.nifi.minifi.bootstrap.RunMiNiFi
 set BOOTSTRAP_ACTION=status

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/5ac121fa/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/conf/logback.xml
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/conf/logback.xml b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/conf/logback.xml
index f7f6f26..33c1534 100644
--- a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/conf/logback.xml
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/conf/logback.xml
@@ -20,7 +20,7 @@
     </contextListener>
     
     <appender name="APP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>logs/minifi-app.log</file>
+        <file>${org.apache.nifi.minifi.bootstrap.config.log.dir}/minifi-app.log</file>
         <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
             <!--
               For daily rollover, use 'app_%d.log'.
@@ -28,7 +28,7 @@
               To GZIP rolled files, replace '.log' with '.log.gz'.
               To ZIP rolled files, replace '.log' with '.log.zip'.
             -->
-            <fileNamePattern>./logs/minifi-app_%d{yyyy-MM-dd_HH}.%i.log.gz</fileNamePattern>
+            <fileNamePattern>${org.apache.nifi.minifi.bootstrap.config.log.dir}/minifi-app_%d{yyyy-MM-dd_HH}.%i.log.gz</fileNamePattern>
             <!-- Keep 10 rolling periods worth of log files-->
             <maxHistory>10</maxHistory>
             <!-- Max size each log file will be-->
@@ -47,7 +47,7 @@
     </appender>
 
     <appender name="BOOTSTRAP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>logs/minifi-bootstrap.log</file>
+        <file>${org.apache.nifi.minifi.bootstrap.config.log.dir}/minifi-bootstrap.log</file>
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <!--
               For daily rollover, use 'user_%d.log'.
@@ -55,7 +55,7 @@
               To GZIP rolled files, replace '.log' with '.log.gz'.
               To ZIP rolled files, replace '.log' with '.log.zip'.
             -->
-            <fileNamePattern>./logs/minifi-bootstrap_%d.log.gz</fileNamePattern>
+            <fileNamePattern>${org.apache.nifi.minifi.bootstrap.config.log.dir}/minifi-bootstrap_%d.log.gz</fileNamePattern>
             <!-- Keep 5 rolling periods worth of logs-->
             <maxHistory>5</maxHistory>
         </rollingPolicy>
@@ -73,6 +73,8 @@
     <!-- valid logging levels: TRACE, DEBUG, INFO, WARN, ERROR -->
     
     <logger name="org.apache.nifi" level="INFO"/>
+    <logger name="org.apache.nifi.processors" level="WARN"/>
+    <logger name="org.apache.nifi.processors.standard.LogAttribute" level="INFO"/>
     <logger name="org.apache.nifi.controller.repository.StandardProcessSession" level="WARN" />
 
     <!-- Logger for managing logging statements for jetty -->