You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2015/04/10 15:44:22 UTC

[47/62] [abbrv] incubator-nifi git commit: NIFI-488: Redirect nifi output streams and redirect bootstrap log messages to file

NIFI-488: Redirect nifi output streams and redirect bootstrap log messages to file


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

Branch: refs/heads/NIFI-25
Commit: abd279c1e01e3aea3332e6b378701554722317e6
Parents: 7819afb
Author: Mark Payne <ma...@hotmail.com>
Authored: Wed Apr 8 13:41:34 2015 -0400
Committer: Mark Payne <ma...@hotmail.com>
Committed: Wed Apr 8 13:41:34 2015 -0400

----------------------------------------------------------------------
 .../java/org/apache/nifi/bootstrap/RunNiFi.java | 131 ++++++++++++++++---
 .../src/main/resources/conf/bootstrap.conf      |   5 +
 2 files changed, 119 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/abd279c1/nifi/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/RunNiFi.java
----------------------------------------------------------------------
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 28a9b71..d25df97 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
@@ -45,9 +45,10 @@ 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.FileHandler;
 import java.util.logging.Handler;
 import java.util.logging.Level;
+import java.util.logging.SimpleFormatter;
 
 
 /**
@@ -92,16 +93,82 @@ public class RunNiFi {
 
 	private final java.util.logging.Logger logger;
 	
-	public RunNiFi(final File bootstrapConfigFile, final boolean verbose) {
+	public RunNiFi(final File bootstrapConfigFile, final boolean verbose) throws IOException {
 		this.bootstrapConfigFile = bootstrapConfigFile;
 		logger = java.util.logging.Logger.getLogger("Bootstrap");
+		
+		final Properties bootstrapProps = new Properties();
+		try (final InputStream configIn = new FileInputStream(bootstrapConfigFile)) {
+			bootstrapProps.load(configIn);
+		}
+
+		String logFilename = bootstrapProps.getProperty("bootstrap.log.file");
+		if ( logFilename == null ) {
+			logFilename = "./logs/bootstrap.log";
+		}
+		
+		File logFile = new File(logFilename);
+		if ( !logFile.isAbsolute() ) {
+			final File workDir = getDefaultWorkingDirectory();
+			logFile = new File(workDir, logFilename);
+		}
+		
+		final File logFileDir = logFile.getParentFile();
+		final Handler fileHandler;
+		if ( logFileDir.exists() || logFileDir.mkdirs() ) {
+			final int maxSize = getIntProp(bootstrapProps, "bootstrap.log.max.bytes", 1024 * 1024 * 10);	// 10 MB
+			final int numFiles = getIntProp(bootstrapProps, "bootstrap.log.count", 10);
+			
+			fileHandler = new FileHandler(logFile.getAbsolutePath(), maxSize, numFiles, true);
+			fileHandler.setFormatter(new SimpleFormatter());
+			logger.addHandler(fileHandler);
+		} else {
+			fileHandler = null;
+			logger.severe("Could not create log file directory " + logFileDir + ". Will not log bootstrap info to file or redirect NiFi standard out to file");
+		}
+		
 		if ( verbose ) {
 		    logger.info("Enabling Verbose Output");
 		    
 		    logger.setLevel(Level.FINE);
-		    final Handler handler = new ConsoleHandler();
-		    handler.setLevel(Level.FINE);
-		    logger.addHandler(handler);
+		    
+		    for ( final Handler handler : logger.getHandlers() ) {
+		    	handler.setLevel(Level.FINE);
+		    }
+		}
+	}
+	
+	
+	private File getLogFile() throws IOException {
+		final Properties bootstrapProps = new Properties();
+		try (final InputStream configIn = new FileInputStream(bootstrapConfigFile)) {
+			bootstrapProps.load(configIn);
+		}
+
+		String logFilename = bootstrapProps.getProperty("bootstrap.log.file");
+		if ( logFilename == null ) {
+			logFilename = "./logs/bootstrap.log";
+		}
+		
+		File logFile = new File(logFilename);
+		if ( !logFile.isAbsolute() ) {
+			final File workDir = getDefaultWorkingDirectory();
+			logFile = new File(workDir, logFilename);
+		}
+
+		return logFile;
+	}
+	
+	private static int getIntProp(final Properties properties, final String name, final int defaultValue) {
+		String propVal = properties.getProperty(name);
+		if ( propVal == null || propVal.trim().isEmpty() ) {
+			return defaultValue;
+		}
+		
+		try {
+			return Integer.parseInt(propVal.trim());
+		} catch (final NumberFormatException nfe) {
+			throw new NumberFormatException("Expected bootstrap property '" + name + "' to be an integer but found value: " + propVal);
 		}
 	}
 	
@@ -581,6 +648,35 @@ public class RunNiFi {
 		}
 	}
 	
+	private void redirectOutput(final Process process) {
+		redirectStreamToLogs(process.getInputStream());
+		redirectStreamToLogs(process.getErrorStream());
+	}
+	
+	private void redirectStreamToLogs(final InputStream in) {
+		final Thread t = new Thread(new Runnable() {
+			@Override
+			public void run() {
+				try (final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
+					String line;
+					while ((line = reader.readLine()) != null) {
+						logger.info(line);
+					}
+				} catch (IOException e) {
+					logger.warning("Failed to read output of NiFi console: " + e);
+				}
+			}
+		});
+		t.setDaemon(true);
+		t.start();
+	}
+	
+	private File getDefaultWorkingDirectory() {
+		final File bootstrapConfigAbsoluteFile = bootstrapConfigFile.getAbsoluteFile();
+		final File binDir = bootstrapConfigAbsoluteFile.getParentFile();
+		return binDir.getParentFile();
+	}
+	
 	@SuppressWarnings({ "rawtypes", "unchecked" })
 	public void start(final boolean monitor) throws IOException, InterruptedException {
 		final Integer port = getCurrentPort();
@@ -590,7 +686,6 @@ public class RunNiFi {
 		}
 		
 		final ProcessBuilder builder = new ProcessBuilder();
-
 		if ( !bootstrapConfigFile.exists() ) {
 			throw new FileNotFoundException(bootstrapConfigFile.getAbsolutePath());
 		}
@@ -604,18 +699,17 @@ public class RunNiFi {
 		props.putAll( (Map) properties );
 
 		final String specifiedWorkingDir = props.get("working.dir");
-		if ( specifiedWorkingDir != null ) {
-			builder.directory(new File(specifiedWorkingDir));
-		}
-
-		final File bootstrapConfigAbsoluteFile = bootstrapConfigFile.getAbsoluteFile();
-		final File binDir = bootstrapConfigAbsoluteFile.getParentFile();
-		final File workingDir = binDir.getParentFile();
-		
+		final File workingDir = getDefaultWorkingDirectory();
 		if ( specifiedWorkingDir == null ) {
 			builder.directory(workingDir);
+		} else {
+			builder.directory(new File(specifiedWorkingDir));
 		}
 		
+		final File logDir = getLogFile().getParentFile();
+		builder.redirectError(new File(logDir, "nifi.err"));
+		builder.redirectOutput(new File(logDir, "nifi.out"));
+		
 		final String libFilename = replaceNull(props.get("lib.dir"), "./lib").trim();
 		File libDir = getFile(libFilename, workingDir);
 		
@@ -738,14 +832,15 @@ public class RunNiFi {
 			try {
 				gracefulShutdownSeconds = Integer.parseInt(gracefulShutdown);
 			} catch (final NumberFormatException nfe) {
-				throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigAbsoluteFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
+				throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
 			}
 			
 			if ( gracefulShutdownSeconds < 0 ) {
-				throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigAbsoluteFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
+				throw new NumberFormatException("The '" + GRACEFUL_SHUTDOWN_PROP + "' property in Bootstrap Config File " + bootstrapConfigFile.getAbsolutePath() + " has an invalid value. Must be a non-negative integer");
 			}
 			
 			Process process = builder.start();
+			redirectOutput(process);
 			Long pid = getPid(process);
 		    if ( pid != null ) {
                 nifiPid = pid;
@@ -776,7 +871,8 @@ public class RunNiFi {
 					if (autoRestartNiFi) {
 						logger.warning("Apache NiFi appears to have died. Restarting...");
 						process = builder.start();
-						
+						redirectOutput(process);
+
 						pid = getPid(process);
 						if ( pid != null ) {
 			                nifiPid = pid;
@@ -802,6 +898,7 @@ public class RunNiFi {
 			}
 		} else {
 			final Process process = builder.start();
+			redirectOutput(process);
 			final Long pid = getPid(process);
 			
 			if ( pid != null ) {

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/abd279c1/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/bootstrap.conf
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/bootstrap.conf b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/bootstrap.conf
index c1536d8..e87bde2 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/bootstrap.conf
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/bootstrap.conf
@@ -21,6 +21,11 @@ java=java
 # Username to use when running NiFi. This value will be ignored on Windows.
 run.as=
 
+# Bootstrap logger info
+bootstrap.log.file=logs/nifi-bootstrap.log
+bootstrap.log.max.bytes=10485760
+bootstrap.log.count=10
+
 # Configure where NiFi's lib and conf directories live
 lib.dir=./lib
 conf.dir=./conf