Details
diff --git a/azkaban-common/src/main/java/azkaban/utils/StdOutErrRedirect.java b/azkaban-common/src/main/java/azkaban/utils/StdOutErrRedirect.java
new file mode 100644
index 0000000..f921267
--- /dev/null
+++ b/azkaban-common/src/main/java/azkaban/utils/StdOutErrRedirect.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2016 LinkedIn Corp.
+ *
+ * Licensed 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 azkaban.utils;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+/**
+ * A class to encapsulate the redirection of stdout and stderr to log4j
+ * This allows us to catch messages written to the console (although we should
+ * not be using System.out to write out).
+ */
+
+public class StdOutErrRedirect {
+ private static final Logger logger = Logger.getLogger(StdOutErrRedirect.class);
+ private static final PrintStream infoStream = createStream(System.out, Level.INFO);
+ private static final PrintStream errorStream = createStream(System.out, Level.ERROR);
+
+ public static void redirectOutAndErrToLog() {
+ System.setOut(infoStream);
+ System.setErr(errorStream);
+ }
+
+ private static PrintStream createStream(PrintStream stream, Level level) {
+ return new LogStream(stream, level);
+ };
+
+ private static class LogStream extends PrintStream {
+ private final Level level;
+
+ public LogStream(OutputStream out, Level level) {
+ super(out);
+ this.level = level;
+ }
+
+ // Underlying mechanism to log to log4j - all print methods will use this
+ private void write(String string) {
+ logger.log(level, string);
+ }
+
+ // String
+ @Override
+ public void println(final String string) {
+ print(string);
+ }
+
+ @Override
+ public void print(final String string) {
+ write(string);
+ }
+
+ // Boolean
+ @Override
+ public void println(final boolean bool) {
+ print(bool);
+ }
+
+ @Override
+ public void print(final boolean bool) {
+ write(String.valueOf(bool));
+ }
+
+ // Int
+ @Override
+ public void println(final int i) {
+ print(i);
+ }
+
+ @Override
+ public void print(final int i) {
+ write(String.valueOf(i));
+ }
+
+ // Float
+ @Override
+ public void println(final float f) {
+ print(f);
+ }
+
+ @Override
+ public void print(final float f) {
+ write(String.valueOf(f));
+ }
+
+ // Char
+ @Override
+ public void println(final char c) {
+ print(c);
+ }
+
+ @Override
+ public void print(final char c) {
+ write(String.valueOf(c));
+ }
+
+ // Long
+ @Override
+ public void println(final long l) {
+ print(l);
+ }
+
+ @Override
+ public void print(final long l) {
+ write(String.valueOf(l));
+ }
+
+ // Double
+ @Override
+ public void println(final double d) {
+ print(d);
+ }
+
+ @Override
+ public void print(final double d) {
+ write(String.valueOf(d));
+ }
+
+ // Char []
+ @Override
+ public void println(final char[] c) {
+ print(c);
+ }
+
+ @Override
+ public void print(final char[] c) {
+ write(new String(c));
+ }
+
+ // Object
+ @Override
+ public void println(final Object o) {
+ print(o);
+ }
+
+ @Override
+ public void print(final Object o) {
+ write(o.toString());
+ }
+ }
+}
diff --git a/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecutorServer.java b/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecutorServer.java
index 0a69dc4..3dfc4c3 100644
--- a/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecutorServer.java
+++ b/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecutorServer.java
@@ -70,6 +70,7 @@ import azkaban.project.JdbcProjectLoader;
import azkaban.project.ProjectLoader;
import azkaban.server.AzkabanServer;
import azkaban.utils.Props;
+import azkaban.utils.StdOutErrRedirect;
import azkaban.utils.SystemMemoryInfo;
import azkaban.utils.Utils;
import azkaban.metrics.MetricsManager;
@@ -356,6 +357,9 @@ public class AzkabanExecutorServer {
* @throws IOException
*/
public static void main(String[] args) throws Exception {
+ // Redirect all std out and err messages into log4j
+ StdOutErrRedirect.redirectOutAndErrToLog();
+
logger.info("Starting Jetty Azkaban Executor...");
Props azkabanSettings = AzkabanServer.loadProps(args);
diff --git a/azkaban-solo-server/src/main/resources/log4j.properties b/azkaban-solo-server/src/main/resources/log4j.properties
index b67828a..705b927 100644
--- a/azkaban-solo-server/src/main/resources/log4j.properties
+++ b/azkaban-solo-server/src/main/resources/log4j.properties
@@ -1,7 +1,5 @@
log4j.rootLogger=INFO, Console
-log4j.logger.azkaban.webapp=INFO, server
-log4j.logger.azkaban.execapp=INFO, server
-log4j.logger.azkaban.soloserver=INFO, server
+log4j.logger.azkaban=INFO, server
log4j.appender.server=org.apache.log4j.RollingFileAppender
log4j.appender.server.layout=org.apache.log4j.PatternLayout
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/AzkabanWebServer.java b/azkaban-web-server/src/main/java/azkaban/webapp/AzkabanWebServer.java
index c5d2ff9..2053f0b 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/AzkabanWebServer.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/AzkabanWebServer.java
@@ -89,6 +89,7 @@ import azkaban.utils.Emailer;
import azkaban.utils.FileIOUtils;
import azkaban.utils.Props;
import azkaban.utils.PropsUtils;
+import azkaban.utils.StdOutErrRedirect;
import azkaban.utils.Utils;
import azkaban.webapp.plugin.PluginRegistry;
import azkaban.webapp.plugin.TriggerPlugin;
@@ -690,6 +691,9 @@ public class AzkabanWebServer extends AzkabanServer {
* @param args
*/
public static void main(String[] args) throws Exception {
+ // Redirect all std out and err messages into log4j
+ StdOutErrRedirect.redirectOutAndErrToLog();
+
logger.info("Starting Jetty Azkaban Web Server...");
Props azkabanSettings = AzkabanServer.loadProps(args);