You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by ra...@apache.org on 2014/09/10 23:27:11 UTC

git commit: FALCON-696 Pull oozie logs at the end of tests. Contributed by Raghav Kumar Gautam

Repository: incubator-falcon
Updated Branches:
  refs/heads/master e82042def -> 5836d352c


FALCON-696 Pull oozie logs at the end of tests. Contributed by Raghav Kumar Gautam


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

Branch: refs/heads/master
Commit: 5836d352c2cff32ead3019157735658cd86ec3ac
Parents: e82042d
Author: Raghav Kumar Gautam <ra...@apache.org>
Authored: Wed Sep 10 14:26:41 2014 -0700
Committer: Raghav Kumar Gautam <ra...@apache.org>
Committed: Wed Sep 10 14:26:41 2014 -0700

----------------------------------------------------------------------
 falcon-regression/CHANGES.txt                   |   2 +
 .../falcon/regression/core/util/Config.java     |   3 +
 .../falcon/regression/core/util/LogUtil.java    | 321 +++++++++++++++++++
 .../falcon/regression/TestngListener.java       |  39 ++-
 4 files changed, 356 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/5836d352/falcon-regression/CHANGES.txt
----------------------------------------------------------------------
diff --git a/falcon-regression/CHANGES.txt b/falcon-regression/CHANGES.txt
index b74a4ee..d360e9b 100644
--- a/falcon-regression/CHANGES.txt
+++ b/falcon-regression/CHANGES.txt
@@ -9,6 +9,8 @@ Trunk (Unreleased)
    via Samarth Gupta)
 
   IMPROVEMENTS
+   FALCON-696 Pull oozie logs at the end of tests (Raghav Kumar Gautam)
+
    FALCON-675 Request URLS moved from parameters into methods in falcon-regression (Ruslan
    Ostafiychuk)
 

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/5836d352/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Config.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Config.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Config.java
index a897661..9ae3f0b 100644
--- a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Config.java
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/Config.java
@@ -52,4 +52,7 @@ public final class Config {
         return INSTANCE.confObj.getString(key, defaultValue);
     }
 
+    public static boolean getBoolean(String key, boolean defaultValue) {
+        return INSTANCE.confObj.getBoolean(key, defaultValue);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/5836d352/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/LogUtil.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/LogUtil.java b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/LogUtil.java
new file mode 100644
index 0000000..42583fa
--- /dev/null
+++ b/falcon-regression/merlin-core/src/main/java/org/apache/falcon/regression/core/util/LogUtil.java
@@ -0,0 +1,321 @@
+/**
+ * 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.
+ */
+
+package org.apache.falcon.regression.core.util;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.falcon.regression.core.helpers.ColoHelper;
+import org.apache.log4j.Logger;
+import org.apache.oozie.client.BundleJob;
+import org.apache.oozie.client.CoordinatorAction;
+import org.apache.oozie.client.CoordinatorJob;
+import org.apache.oozie.client.OozieClient;
+import org.apache.oozie.client.OozieClientException;
+import org.apache.oozie.client.WorkflowAction;
+import org.apache.oozie.client.WorkflowJob;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Collection;
+import java.util.List;
+
+public class LogUtil {
+    private static final Logger logger = Logger.getLogger(LogUtil.class);
+    private static final char nl = '\n';
+    private static final String hr = StringUtils.repeat("-", 80);
+    private static final String hr2 = StringUtils.repeat("-", 120);
+    private static final String hr3 = StringUtils.repeat("-", 160);
+
+    private LogUtil() {
+        throw new AssertionError("Instantiating utility class...");
+    }
+
+    private enum OozieDump {
+        BundleDump {
+            @Override
+            void writeLogs(OozieClient oozieClient, String location, Collection<File> filter) {
+                final List<BundleJob> bundleJobsInfo;
+                try {
+                    bundleJobsInfo = oozieClient.getBundleJobsInfo("", 0, 1000000);
+                } catch (OozieClientException e) {
+                    logger.error("Couldn't fetch list of bundles. Exception: " + e);
+                    return;
+                }
+                for (BundleJob oneJobInfo : bundleJobsInfo) {
+                    final String bundleJobId = oneJobInfo.getId();
+                    writeOneJobInfo(oozieClient, bundleJobId, location, filter);
+                    writeOneJobLog(oozieClient, bundleJobId, location, filter);
+                }
+            }
+
+            /**
+             * Pull and dump info of one job.
+             * @param oozieClient oozie client that will be used for pulling log
+             * @param bundleJobId job id of the bundle job
+             * @param location local location where logs will be dumped
+             * @param filter list of files that have already been dumped
+             */
+            private void writeOneJobInfo(OozieClient oozieClient, String bundleJobId,
+                                         String location, Collection<File> filter) {
+                final String fileName = OSUtil.getPath(location, bundleJobId + "-info.log");
+                final File file = new File(fileName);
+                if (filter != null && filter.contains(file)) {
+                    return;
+                }
+                final BundleJob info;
+                try {
+                    info = oozieClient.getBundleJobInfo(bundleJobId);
+                } catch (OozieClientException e) {
+                    logger.error("Couldn't fetch bundle info for " + bundleJobId + ". " +
+                        "Exception: " + e);
+                    return;
+                }
+                StringBuilder sb = new StringBuilder();
+                sb.append("Bundle ID : ").append(info.getId()).append(nl);
+                sb.append(hr).append(nl);
+                sb.append("Bundle Name : ").append(info.getAppName()).append(nl);
+                sb.append("App Path : ").append(info.getAppPath()).append(nl);
+                sb.append("Status : ").append(info.getStatus()).append(nl);
+                sb.append("User : ").append(info.getUser()).append(nl);
+                sb.append("Created : ").append(info.getCreatedTime()).append(nl);
+                sb.append("Started : ").append(info.getStartTime()).append(nl);
+                sb.append("EndTime : ").append(info.getEndTime()).append(nl);
+                sb.append("Kickoff time : ").append(info.getKickoffTime()).append(nl);
+                sb.append(hr2).append(nl);
+                final String format = "%-40s %-10s %-5s %-10s %-30s %-20s";
+                sb.append(String.format(format,
+                    "Job ID", "Status", "Freq", "Unit", "Started", "Next Materialized")).append(nl);
+                sb.append(hr2).append(nl);
+                for (CoordinatorJob cj : info.getCoordinators()) {
+                    sb.append(String.format(format,
+                        cj.getId(), cj.getStatus(),  cj.getFrequency(), cj.getTimeUnit(), cj.getStartTime(),
+                        cj.getNextMaterializedTime())).append(nl);
+                }
+                sb.append(hr2).append(nl);
+                try {
+                    FileUtils.writeStringToFile(file, sb.toString());
+                } catch (IOException e) {
+                    logger.error("Couldn't write bundle info for " + bundleJobId + ". " +
+                        "Exception: " + e);
+                }
+            }
+        },
+
+        CoordDump {
+            @Override
+            void writeLogs(OozieClient oozieClient, String location, Collection<File> filter) {
+                final List<CoordinatorJob> coordJobsInfo;
+                try {
+                    coordJobsInfo = oozieClient.getCoordJobsInfo("", 0, 1000000);
+                } catch (OozieClientException e) {
+                    logger.error("Couldn't fetch list of bundles. Exception: " + e);
+                    return;
+                }
+                for (CoordinatorJob oneJobInfo : coordJobsInfo) {
+                    final String coordJobId = oneJobInfo.getId();
+                    writeOneJobInfo(oozieClient, coordJobId, location, filter);
+                    writeOneJobLog(oozieClient, coordJobId, location, filter);
+                }
+            }
+
+            /**
+             * Pull and dump info of one job.
+             * @param oozieClient oozie client that will be used for pulling log
+             * @param coordJobId job id of the coordinator job
+             * @param location local location where logs will be dumped
+             * @param filter list of files that have already been dumped
+             */
+            private void writeOneJobInfo(OozieClient oozieClient, String coordJobId,
+                                         String location, Collection<File> filter) {
+                final String fileName = OSUtil.getPath(location, coordJobId + "-info.log");
+                final File file = new File(fileName);
+                if (filter != null && filter.contains(file)) {
+                    return;
+                }
+                final CoordinatorJob info;
+                try {
+                    info = oozieClient.getCoordJobInfo(coordJobId);
+                } catch (OozieClientException e) {
+                    logger.error("Couldn't fetch bundle info for " + coordJobId + ". " +
+                        "Exception: " + e);
+                    return;
+                }
+                StringBuilder sb = new StringBuilder();
+                sb.append("Coordinator Job ID : ").append(info.getId()).append(nl);
+                sb.append(hr).append(nl);
+                sb.append("Job Name : ").append(info.getAppName()).append(nl);
+                sb.append("App Path : ").append(info.getAppPath()).append(nl);
+                sb.append("Status : ").append(info.getStatus()).append(nl);
+                sb.append("User : ").append(info.getUser()).append(nl);
+                sb.append("Started : ").append(info.getStartTime()).append(nl);
+                sb.append("EndTime : ").append(info.getEndTime()).append(nl);
+                sb.append(hr3).append(nl);
+                final String format = "%-40s %-10s %-40s %-10s %-30s %-30s";
+                sb.append(String.format(format,
+                    "Job ID", "Status", "Ext ID", "Err Code", "Created","Nominal Time")).append(nl);
+                sb.append(hr3).append(nl);
+                for (CoordinatorAction cj : info.getActions()) {
+                    sb.append(String.format(format,
+                        cj.getId(), cj.getStatus(),  cj.getExternalId(), cj.getErrorCode(),
+                        cj.getCreatedTime(), cj.getNominalTime())).append(nl);
+                }
+                sb.append(hr3).append(nl);
+                try {
+                    FileUtils.writeStringToFile(file, sb.toString());
+                } catch (IOException e) {
+                    logger.error("Couldn't write coord job info for " + coordJobId + ". " +
+                        "Exception: " + e);
+                }
+            }
+        },
+
+        WfDump {
+            @Override
+            void writeLogs(OozieClient oozieClient, String location, Collection<File> filter) {
+                final List<WorkflowJob> wfJobsInfo;
+                try {
+                    wfJobsInfo = oozieClient.getJobsInfo("", 0, 1000000);
+                } catch (OozieClientException e) {
+                    logger.error("Couldn't fetch list of bundles. Exception: " + e);
+                    return;
+                }
+                for (WorkflowJob oneJobInfo : wfJobsInfo) {
+                    final String wfJobId = oneJobInfo.getId();
+                    writeOneJobInfo(oozieClient, wfJobId, location, filter);
+                    writeOneJobLog(oozieClient, wfJobId, location, filter);
+                }
+            }
+
+            /**
+             * Pull and dump info of one job.
+             * @param oozieClient oozie client that will be used for pulling log
+             * @param wfJobId job id of the workflow job
+             * @param location local location where logs will be dumped
+             * @param filter list of files that have already been dumped
+             */
+            private void writeOneJobInfo(OozieClient oozieClient, String wfJobId,
+                                         String location, Collection<File> filter) {
+                final String fileName = OSUtil.getPath(location, wfJobId + "-info.log");
+                final File file = new File(fileName);
+                if (filter != null && filter.contains(file)) {
+                    return;
+                }
+                final WorkflowJob info;
+                try {
+                    info = oozieClient.getJobInfo(wfJobId);
+                } catch (OozieClientException e) {
+                    logger.error("Couldn't fetch bundle info for " + wfJobId + ". Exception: " + e);
+                    return;
+                }
+                StringBuilder sb = new StringBuilder();
+                sb.append("Workflow Job ID : ").append(info.getId()).append(nl);
+                sb.append(hr).append(nl);
+                sb.append("Wf Name : ").append(info.getAppName()).append(nl);
+                sb.append("App Path : ").append(info.getAppPath()).append(nl);
+                sb.append("Status : ").append(info.getStatus()).append(nl);
+                sb.append("Run : ").append(info.getRun()).append(nl);
+                sb.append("User : ").append(info.getUser()).append(nl);
+                sb.append("Group : ").append(info.getGroup()).append(nl);
+                sb.append("Created : ").append(info.getCreatedTime()).append(nl);
+                sb.append("Started : ").append(info.getStartTime()).append(nl);
+                sb.append("Last Modified : ").append(info.getLastModifiedTime()).append(nl);
+                sb.append("EndTime : ").append(info.getEndTime()).append(nl);
+                sb.append("External ID : ").append(info.getExternalId()).append(nl);
+                sb.append(nl).append("Actions").append(nl);
+                sb.append(hr3).append(nl);
+                final String format = "%-80s %-10s %-40s %-15s %-10s";
+                sb.append(String.format(format,
+                    "Job ID", "Status", "Ext ID", "Ext Status", "Err Code")).append(nl);
+                sb.append(hr3).append(nl);
+                for (WorkflowAction cj : info.getActions()) {
+                    sb.append(String.format(format,
+                        cj.getId(), cj.getStatus(),  cj.getExternalId(), cj.getExternalStatus(),
+                        cj.getErrorCode())).append(nl);
+                }
+                sb.append(hr3).append(nl);
+                try {
+                    FileUtils.writeStringToFile(file, sb.toString());
+                } catch (IOException e) {
+                    logger.error("Couldn't write wf job info for " + wfJobId + ". Exception: " + e);
+                }
+            }
+        },
+        ;
+
+        /**
+         * Pull and dump info and log of all jobs of a type
+         * @param oozieClient oozie client that will be used for pulling log
+         * @param location local location where logs will be dumped
+         * @param filter list of files that have already been dumped
+         */
+        abstract void writeLogs(OozieClient oozieClient, String location, Collection<File> filter);
+
+        /**
+         * Pull and dump log of one job.
+         * @param oozieClient oozie client that will be used for pulling log
+         * @param jobId job id of the job
+         * @param location local location where logs will be dumped
+         * @param filter list of files that have already been dumped
+         */
+        private static void writeOneJobLog(OozieClient oozieClient, String jobId,
+            String location, Collection<File> filter) {
+            final String fileName = OSUtil.getPath(location, jobId + ".log");
+            assert fileName != null;
+            final File file = new File(fileName);
+            if (filter != null && filter.contains(file)) {
+                return;
+            }
+            try {
+                oozieClient.getJobLog(jobId, "", "", new PrintStream(file));
+            } catch (OozieClientException e) {
+                logger.error("Couldn't fetch log for " + jobId + ". Exception: " + e);
+            } catch (FileNotFoundException e) {
+                logger.error("Couldn't write log for " + jobId + ". Exception: " + e);
+            }
+        }
+    }
+
+    /**
+     * Pulls and dumps oozie logs at a configured location.
+     * @param coloHelper coloHelper of the cluster from which oozie logs are going to be pulled
+     * @param logLocation local location at which logs are going to be dumped
+     */
+    public static void writeOozieLogs(ColoHelper coloHelper, String logLocation) {
+        final OozieClient oozieClient = coloHelper.getFeedHelper().getOozieClient();
+        final String hostname = coloHelper.getClusterHelper().getQaHost();
+        final String oozieLogLocation = OSUtil.getPath(logLocation + "oozie_logs", hostname);
+        assert oozieLogLocation != null;
+        final File directory = new File(oozieLogLocation);
+        if (!directory.exists()) {
+            try {
+                FileUtils.forceMkdir(directory);
+            } catch (IOException e) {
+                logger.error("Directory creation failed for: " + directory + ". Exception: " + e);
+                return;
+            }
+        }
+        final Collection<File> filter = FileUtils.listFiles(directory, null, true);
+        for (OozieDump oozieDump : OozieDump.values()) {
+            oozieDump.writeLogs(oozieClient, oozieLogLocation, filter);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/5836d352/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
----------------------------------------------------------------------
diff --git a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
index 5cba005..e3af96d 100644
--- a/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
+++ b/falcon-regression/merlin/src/test/java/org/apache/falcon/regression/TestngListener.java
@@ -20,12 +20,17 @@ package org.apache.falcon.regression;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.falcon.regression.core.helpers.ColoHelper;
+import org.apache.falcon.regression.core.util.Config;
+import org.apache.falcon.regression.core.util.LogUtil;
 import org.apache.falcon.regression.core.util.OSUtil;
 import org.apache.falcon.regression.testHelper.BaseUITestClass;
 import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
 import org.openqa.selenium.OutputType;
 import org.openqa.selenium.TakesScreenshot;
+import org.testng.IExecutionListener;
 import org.testng.ITestContext;
 import org.testng.ITestListener;
 import org.testng.ITestResult;
@@ -34,29 +39,25 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 
-public class TestngListener implements ITestListener {
+public class TestngListener implements ITestListener, IExecutionListener {
     private static final Logger logger = Logger.getLogger(TestngListener.class);
+    private final String hr = StringUtils.repeat("-", 100);
 
     @Override
     public void onTestStart(ITestResult result) {
-        logLine();
+        logger.info(hr);
         logger.info(
             String.format("Testing going to start for: %s.%s(%s)", result.getTestClass().getName(),
                 result.getName(), Arrays.toString(result.getParameters())));
         NDC.push(result.getName());
     }
 
-    private void logLine() {
-        logger.info(
-            "-----------------------------------------------------------------------------------------------");
-    }
-
     private void logEndOfTest(ITestResult result, String outcome) {
         logger.info(
             String.format("Testing going to end for: %s.%s(%s) %s", result.getTestClass().getName(),
                 result.getName(), Arrays.toString(result.getParameters()), outcome));
         NDC.pop();
-        logLine();
+        logger.info(hr);
     }
 
     @Override
@@ -80,7 +81,7 @@ public class TestngListener implements ITestListener {
         }
 
         logger.info(ExceptionUtils.getStackTrace(result.getThrowable()));
-        logLine();
+        logger.info(hr);
     }
 
     @Override
@@ -100,4 +101,24 @@ public class TestngListener implements ITestListener {
     @Override
     public void onFinish(ITestContext context) {
     }
+
+    @Override
+    public void onExecutionStart() {
+    }
+
+    @Override
+    public void onExecutionFinish() {
+        if (!Config.getBoolean("log.capture.oozie", false)) {
+            logger.info("oozie log capturing is disabled");
+            return;
+        }
+        final String logLocation = Config.getProperty("log.capture.location", "./");
+        final String[] serverNames = Config.getStringArray("servers");
+        for (final String serverName : serverNames) {
+            final ColoHelper coloHelper = new ColoHelper(serverName.trim());
+            LogUtil.writeOozieLogs(coloHelper, logLocation);
+        }
+    }
+
+
 }