diff --git a/nifi/nifi-assembly/src/main/assembly/dependencies.xml b/nifi/nifi-assembly/src/main/assembly/dependencies.xml
index 27eb32dd8c..a3e3a18597 100644
--- a/nifi/nifi-assembly/src/main/assembly/dependencies.xml
+++ b/nifi/nifi-assembly/src/main/assembly/dependencies.xml
@@ -49,6 +49,8 @@
true
nifi-bootstrap
+ slf4j-api
+ logback-classic
diff --git a/nifi/nifi-bootstrap/pom.xml b/nifi/nifi-bootstrap/pom.xml
index bdf508928b..ff27fd3c5c 100644
--- a/nifi/nifi-bootstrap/pom.xml
+++ b/nifi/nifi-bootstrap/pom.xml
@@ -21,4 +21,11 @@
nifi-bootstrap
jar
+
+
+
+ org.slf4j
+ slf4j-api
+
+
diff --git a/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NiFiListener.java b/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NiFiListener.java
index 171347880e..8d74f16a89 100644
--- a/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NiFiListener.java
+++ b/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NiFiListener.java
@@ -23,6 +23,7 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.apache.nifi.bootstrap.util.LimitingInputStream;
@@ -40,6 +41,7 @@ public class NiFiListener {
listener = new Listener(serverSocket, runner);
final Thread listenThread = new Thread(listener);
listenThread.setName("Listen to NiFi");
+ listenThread.setDaemon(true);
listenThread.start();
return localPort;
}
@@ -62,7 +64,16 @@ public class NiFiListener {
public Listener(final ServerSocket serverSocket, final RunNiFi runner) {
this.serverSocket = serverSocket;
- this.executor = Executors.newFixedThreadPool(2);
+ this.executor = Executors.newFixedThreadPool(2, new ThreadFactory() {
+ @Override
+ public Thread newThread(final Runnable runnable) {
+ final Thread t = Executors.defaultThreadFactory().newThread(runnable);
+ t.setDaemon(true);
+ t.setName("NiFi Bootstrap Command Listener");
+ return t;
+ }
+ });
+
this.runner = runner;
}
diff --git a/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java b/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
index e6b1bc5039..2bc44cc726 100644
--- a/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
+++ b/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
@@ -41,13 +41,17 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Handler;
-import java.util.logging.Level;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
*
@@ -94,19 +98,27 @@ public class RunNiFi {
private final File bootstrapConfigFile;
- private final java.util.logging.Logger logger;
+ // used for logging initial info; these will be logged to console by default when the app is started
+ private final Logger cmdLogger = LoggerFactory.getLogger("org.apache.nifi.bootstrap.Command");
+ // used for logging all info. These by default will be written to the log file
+ private final Logger defaultLogger = LoggerFactory.getLogger(RunNiFi.class);
+
+
+ private final ExecutorService loggingExecutor;
+ private volatile Set> loggingFutures = new HashSet<>(2);
public RunNiFi(final File bootstrapConfigFile, final boolean verbose) {
this.bootstrapConfigFile = bootstrapConfigFile;
- logger = java.util.logging.Logger.getLogger("Bootstrap");
- if (verbose) {
- logger.info("Enabling Verbose Output");
- logger.setLevel(Level.FINE);
- final Handler handler = new ConsoleHandler();
- handler.setLevel(Level.FINE);
- logger.addHandler(handler);
- }
+ loggingExecutor = Executors.newFixedThreadPool(2, new ThreadFactory() {
+ @Override
+ public Thread newThread(final Runnable runnable) {
+ final Thread t = Executors.defaultThreadFactory().newThread(runnable);
+ t.setDaemon(true);
+ t.setName("NiFi logging handler");
+ return t;
+ }
+ });
}
private static void printUsage() {
@@ -185,10 +197,10 @@ public class RunNiFi {
switch (cmd.toLowerCase()) {
case "start":
- runNiFi.start(false);
+ runNiFi.start();
break;
case "run":
- runNiFi.start(true);
+ runNiFi.start();
break;
case "stop":
runNiFi.stop();
@@ -198,7 +210,7 @@ public class RunNiFi {
break;
case "restart":
runNiFi.stop();
- runNiFi.start(false);
+ runNiFi.start();
break;
case "dump":
runNiFi.dump(dumpFile);
@@ -206,40 +218,44 @@ public class RunNiFi {
}
}
- public File getStatusFile() {
+ File getStatusFile() {
+ return getStatusFile(defaultLogger);
+ }
+
+ 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, "nifi.pid");
- logger.log(Level.FINE, "Status File: {0}", statusFile);
+ logger.debug("Status File: {}", statusFile);
return statusFile;
}
- private Properties loadProperties() throws IOException {
+ private Properties loadProperties(final Logger logger) throws IOException {
final Properties props = new Properties();
- final File statusFile = getStatusFile();
+ final File statusFile = getStatusFile(logger);
if (statusFile == null || !statusFile.exists()) {
- logger.fine("No status file to load properties from");
+ logger.debug("No status file to load properties from");
return props;
}
- try (final FileInputStream fis = new FileInputStream(getStatusFile())) {
+ try (final FileInputStream fis = new FileInputStream(getStatusFile(logger))) {
props.load(fis);
}
final Map