Author: kamrul
Date: Sat Dec 10 19:37:11 2011
New Revision: 1212853

URL: http://svn.apache.org/viewvc?rev=1212853&view=rev
Log:
OOZIE-627 Handle GZ log retrieval failures gracefully.(Kiran via Mohammad)

Modified:
    
incubator/oozie/trunk/core/src/main/java/org/apache/oozie/util/XLogStreamer.java
    
incubator/oozie/trunk/core/src/test/java/org/apache/oozie/util/TestLogStreamer.java
    incubator/oozie/trunk/release-log.txt

Modified: 
incubator/oozie/trunk/core/src/main/java/org/apache/oozie/util/XLogStreamer.java
URL: 
http://svn.apache.org/viewvc/incubator/oozie/trunk/core/src/main/java/org/apache/oozie/util/XLogStreamer.java?rev=1212853&r1=1212852&r2=1212853&view=diff
==============================================================================
--- 
incubator/oozie/trunk/core/src/main/java/org/apache/oozie/util/XLogStreamer.java
 (original)
+++ 
incubator/oozie/trunk/core/src/main/java/org/apache/oozie/util/XLogStreamer.java
 Sat Dec 10 19:37:11 2011
@@ -37,6 +37,7 @@ import java.util.zip.GZIPInputStream;
  * XLogStreamer streams the given log file to logWriter after applying the 
given filter.
  */
 public class XLogStreamer {
+    private static XLog LOG = XLog.getLog(XLogStreamer.class);
 
     /**
      * Filter that will construct the regular expression that will be used to 
filter the log statement. And also checks
@@ -321,28 +322,60 @@ public class XLogStreamer {
      * @return Modification time of .gz file after checking if it is relevant 
to the job
      */
     private long getGZFileCreationTime(String fileName, long startTime, long 
endTime) {
+        // Default return value of -1 to exclude the file
         long returnVal = -1;
         int dateStartIndex = 10;
         String[] dateDetails;
-        dateDetails = fileName.substring(dateStartIndex, fileName.length() - 
3).split("-");
-        int year = Integer.parseInt(dateDetails[0]);
-        int month = Integer.parseInt(dateDetails[1]);
-        int day = Integer.parseInt(dateDetails[2]);
-        int hour = Integer.parseInt(dateDetails[3]);
-        int minute = 0;
-        Calendar calendarEntry = Calendar.getInstance();
-        calendarEntry.set(year, month - 1, day, hour, minute); // give 
month-1(Say, 7 for August)
-        long logFileStartTime = calendarEntry.getTimeInMillis();
-        long milliSecondsPerHour = 3600000;
-        long logFileEndTime = logFileStartTime + milliSecondsPerHour;
-        /*  To check whether the log content is there in the initial or later 
part of the log file or
-            the log content is contained entirely within this log file or
-            the entire log file contains the event log where the event spans 
across hours
-        */
-        if ((startTime >= logFileStartTime && startTime <= logFileEndTime)
-                || (endTime >= logFileStartTime && endTime <= logFileEndTime)
-                || (startTime <= logFileStartTime && endTime >= 
logFileEndTime)) {
-            returnVal = logFileStartTime;
+        try {
+            dateDetails = fileName.substring(dateStartIndex, fileName.length() 
- 3).split("-");
+            // Terminate the execution if all the details year, month, day and 
hour are not available
+            if (dateDetails.length == 4) {
+                int year = Integer.parseInt(dateDetails[0]);
+                int month = Integer.parseInt(dateDetails[1]);
+                int day = Integer.parseInt(dateDetails[2]);
+                int hour = Integer.parseInt(dateDetails[3]);
+                int minute = 0;
+                Calendar calendarEntry = Calendar.getInstance();
+                calendarEntry.set(year, month - 1, day, hour, minute); // give 
month-1(Say, 7 for August)
+                long logFileStartTime = calendarEntry.getTimeInMillis();
+                long milliSecondsPerHour = 3600000;
+                long logFileEndTime = logFileStartTime + milliSecondsPerHour;
+                /*  To check whether the log content is there in the initial 
or later part of the log file or
+                    the log content is contained entirely within this log file 
or
+                    the entire log file contains the event log where the event 
spans across hours
+                */
+                if ((startTime >= logFileStartTime && startTime <= 
logFileEndTime)
+                        || (endTime >= logFileStartTime && endTime <= 
logFileEndTime)
+                        || (startTime <= logFileStartTime && endTime >= 
logFileEndTime)) {
+                    returnVal = logFileStartTime;
+                }
+            }
+        } catch (StringIndexOutOfBoundsException ex) {
+            // Inclusion of oozie.log as oozie.log.gz if it is accidentally 
GZipped
+            LOG.warn("oozie.log has been GZipped, which is unexpected");
+            if (fileName.equals("oozie.log.gz")) {
+                // Return a value other than -1 to include the file in list
+                returnVal = 0;
+            } else {
+                returnVal = -1;
+            }
+        } catch (NumberFormatException ex) {
+            StringBuilder sb = new StringBuilder("");
+            sb.append("NumberFormatException encountered. Filename " + 
fileName + " is in invalid format\n");
+            for (StackTraceElement stackTraceElement : ex.getStackTrace())
+                sb.append(stackTraceElement + "\n");
+            LOG.debug(sb);
+            // Return -1 to exclude the file
+            returnVal = -1;
+        } catch (Exception ex) {
+            StringBuilder sb = new StringBuilder("");
+            sb.append("Exception occured while trying to retrieve the log 
content from the GZip file " + fileName
+                    + ". This is an unexpected behavior\n");
+            for (StackTraceElement stackTraceElement : ex.getStackTrace())
+                sb.append(stackTraceElement + "\n");
+            LOG.debug(sb);
+            // Return -1 to exclude the file
+            returnVal = -1;
         }
         return returnVal;
     }

Modified: 
incubator/oozie/trunk/core/src/test/java/org/apache/oozie/util/TestLogStreamer.java
URL: 
http://svn.apache.org/viewvc/incubator/oozie/trunk/core/src/test/java/org/apache/oozie/util/TestLogStreamer.java?rev=1212853&r1=1212852&r2=1212853&view=diff
==============================================================================
--- 
incubator/oozie/trunk/core/src/test/java/org/apache/oozie/util/TestLogStreamer.java
 (original)
+++ 
incubator/oozie/trunk/core/src/test/java/org/apache/oozie/util/TestLogStreamer.java
 Sat Dec 10 19:37:11 2011
@@ -44,6 +44,8 @@ public class TestLogStreamer extends XTe
         xf.setParameter("JOB", "14-200904160239--example-forkjoinwf");
         xf.setLogLevel("DEBUG|INFO");
 
+        // This file will be included in the list of files for log retrieval, 
provided the modification time lies
+        // between the start and end times of the job
         FileWriter fw1 = new FileWriter(getTestCaseDir() + "/oozie.log");
         StringBuilder sb1 = new StringBuilder();
         sb1.append("2009-06-24 02:43:13,958 DEBUG _L1_:323 - USER[oozie] 
GROUP[-] TOKEN[-] APP[example-forkjoinwf] "
@@ -56,6 +58,8 @@ public class TestLogStreamer extends XTe
         File f1 = new File(getTestCaseDir() + "/oozie.log");
         f1.setLastModified(currTime - 9000);
 
+        // This file will be included in the list of files for log retrieval, 
provided the modification time lies
+        // between the start and end times of the job
         FileWriter fw2 = new FileWriter(getTestCaseDir() + "/oozie.log.1");
         StringBuilder sb2 = new StringBuilder();
         sb2.append("\n2009-06-24 02:43:13,986 WARN _L3_:539 - USER[-] GROUP[-] 
TOKEN[-] APP[example-forkjoinwf] "
@@ -70,6 +74,8 @@ public class TestLogStreamer extends XTe
         File f2 = new File(getTestCaseDir() + "/oozie.log.1");
         f2.setLastModified(currTime - 8000);
 
+        // This file will be included in the list of files for log retrieval, 
provided, the modification time lies
+        // between the start and end times of the job
         FileWriter fw3 = new FileWriter(getTestCaseDir() + "/oozie.log.2");
         StringBuilder sb3 = new StringBuilder();
         sb3.append("\n2009-06-24 02:43:14,505 INFO _L5_:317 - USER[oozie] 
GROUP[oozie] TOKEN[-] APP[-] JOB[-] "
@@ -83,6 +89,9 @@ public class TestLogStreamer extends XTe
         File f3 = new File(getTestCaseDir() + "/oozie.log.2");
         f3.setLastModified(currTime);
 
+        // This file will not be included in the list of files for log 
retrieval, since the file name neither is equal
+        // to nor does begin with the log file pattern specified in log4j 
properties file. The default value is
+        // "oozie.log"
         FileWriter fwerr = new FileWriter(getTestCaseDir() + "/testerr.log");
         StringBuilder sberr = new StringBuilder();
         sberr.append("2009-06-24 02:43:13,958 WARN _L1_:323 - USER[oozie] 
GROUP[-] TOKEN[-] APP[example-forkjoinwf] "
@@ -95,6 +104,9 @@ public class TestLogStreamer extends XTe
         File ferr = new File(getTestCaseDir() + "/testerr.log");
         ferr.setLastModified(currTime - 8000);
 
+        // This GZip file would be included in list of files for log 
retrieval, provided, there is an overlap between
+        // the two time windows i) time duration during which the GZipped log 
file is modified ii) time window between
+        // start and end times of the job
         Calendar cal = new GregorianCalendar();
         String outFilename = "oozie.log." + cal.get(Calendar.YEAR) + "-" + 
(cal.get(Calendar.MONTH) + 1) + "-"
                 + cal.get(Calendar.DATE) + "-" + cal.get(Calendar.HOUR_OF_DAY) 
+ ".gz";
@@ -112,27 +124,76 @@ public class TestLogStreamer extends XTe
         gzout.finish();
         gzout.close();
 
+        // oozie.log.gz GZip file would always be included in list of files 
for log retrieval
+        outFilename = "oozie.log.gz";
+        f = new File(getTestCaseDir() + "/" + outFilename);
+        gzout = new GZIPOutputStream(new FileOutputStream(f));
+        // Generate and write log content to the GZip file
+        sb = new StringBuilder();
+        sb.append("\n2009-06-24 02:43:13,958 DEBUG _L10_:323 - USER[oozie] 
GROUP[-] TOKEN[-] APP[example-"
+                + "forkjoinwf] " + "JOB[14-200904160239--example-forkjoinwf] 
ACTION[-] End workflow state change");
+        sb.append("\n2009-06-24 02:43:13,961 INFO _L11_:317 - USER[-] GROUP[-] 
TOKEN[-] APP[example-forkjoinwf] "
+                + "JOB[14-200904160239--example-forkjoinwf] ACTION[-] 
[org.apache.oozie.core."
+                + "command.WorkflowRunnerCallable] " + "released lock");
+        strg = sb.toString();
+        buf = strg.getBytes();
+        gzout.write(buf, 0, buf.length);
+        gzout.finish();
+        gzout.close();
+
+        // Test to check if an invalid GZip file(file name not in the expected 
format oozie.log-YYYY-MM-DD-HH.gz) is
+        // excluded from log retrieval
+        outFilename = "oozie.log-2011-12-03-15.bz2.gz";
+        f = new File(getTestCaseDir() + "/" + outFilename);
+        gzout = new GZIPOutputStream(new FileOutputStream(f));
+        // Generate and write log content to the GZip file
+        sb = new StringBuilder();
+        sb.append("\n2009-06-24 02:43:13,958 DEBUG _L12_:323 - USER[oozie] 
GROUP[-] TOKEN[-] APP[example-"
+                + "forkjoinwf] " + "JOB[14-200904160239--example-forkjoinwf] 
ACTION[-] End workflow state change");
+        sb.append("\n2009-06-24 02:43:13,961 INFO _L13_:317 - USER[-] GROUP[-] 
TOKEN[-] APP[example-forkjoinwf] "
+                + "JOB[14-200904160239--example-forkjoinwf] ACTION[-] 
[org.apache.oozie.core."
+                + "command.WorkflowRunnerCallable] " + "released lock");
+        strg = sb.toString();
+        buf = strg.getBytes();
+        gzout.write(buf, 0, buf.length);
+        gzout.finish();
+        gzout.close();
+
+        // Test for the log retrieval of the job that began 10 seconds before 
and ended 5 seconds before current time
+        // respectively
         StringWriter sw = new StringWriter();
         XLogStreamer str = new XLogStreamer(xf, sw, getTestCaseDir(), 
"oozie.log", 1);
         str.streamLog(new Date(currTime - 10000), new Date(currTime - 5000));
         String[] out = sw.toString().split("\n");
-        assertEquals(5, out.length);
-        assertEquals(true, out[0].contains("_L8_"));
-        assertEquals(true, out[1].contains("_L9_"));
-        assertEquals(true, out[2].contains("_L1_"));
-        assertEquals(true, out[3].contains("_L2_"));
-        assertEquals(true, out[4].contains("_L4_"));
+        // Check if the retrieved log content is of length seven lines after 
filtering based on time window, file name
+        // pattern and parameters like JobId, Username etc. and/or based on 
log level like INFO, DEBUG, etc.
+        assertEquals(7, out.length);
+        // Check if the lines of the log contain the expected strings
+        assertEquals(true, out[0].contains("_L10_"));
+        assertEquals(true, out[1].contains("_L11_"));
+        assertEquals(true, out[2].contains("_L8_"));
+        assertEquals(true, out[3].contains("_L9_"));
+        assertEquals(true, out[4].contains("_L1_"));
+        assertEquals(true, out[5].contains("_L2_"));
+        assertEquals(true, out[6].contains("_L4_"));
 
+        // Test to check if the null values for startTime and endTime are 
translated to 0 and current time respectively
+        // and corresponding log content is retrieved properly
         StringWriter sw1 = new StringWriter();
         XLogStreamer str1 = new XLogStreamer(xf, sw1, getTestCaseDir(), 
"oozie.log", 1);
         str1.streamLog(null, null);
         out = sw1.toString().split("\n");
-        assertEquals(6, out.length);
-        assertEquals(true, out[0].contains("_L8_"));
-        assertEquals(true, out[1].contains("_L9_"));
-        assertEquals(true, out[2].contains("_L1_"));
-        assertEquals(true, out[3].contains("_L2_"));
-        assertEquals(true, out[4].contains("_L4_"));
-        assertEquals(true, out[5].contains("_L7_"));
+        // Check if the retrieved log content is of length eight lines after 
filtering based on time window, file name
+        // pattern and parameters like JobId, Username etc. and/or based on 
log level like INFO, DEBUG, etc.
+        assertEquals(8, out.length);
+        // Check if the lines of the log contain the expected strings
+        assertEquals(true, out[0].contains("_L10"));
+        assertEquals(true, out[1].contains("_L11_"));
+        assertEquals(true, out[2].contains("_L8_"));
+        assertEquals(true, out[3].contains("_L9_"));
+        assertEquals(true, out[4].contains("_L1_"));
+        assertEquals(true, out[5].contains("_L2_"));
+        assertEquals(true, out[6].contains("_L4_"));
+        assertEquals(true, out[7].contains("_L7_"));
     }
 }

Modified: incubator/oozie/trunk/release-log.txt
URL: 
http://svn.apache.org/viewvc/incubator/oozie/trunk/release-log.txt?rev=1212853&r1=1212852&r2=1212853&view=diff
==============================================================================
--- incubator/oozie/trunk/release-log.txt (original)
+++ incubator/oozie/trunk/release-log.txt Sat Dec 10 19:37:11 2011
@@ -1,5 +1,6 @@
 -- Oozie 3.2.0 release
 
+OOZIE-627 Handle GZ log retrieval failures gracefully.(Kiran via Mohammad)
 OOZIE-8   Variable not getting replaced with value in workflow rerun.(Mona via 
Mohammad)
 OOZIE-15  Coordinator input/output event instance should limit 1 instance. 
(Mona via Mohammad)
 OOZIE-633 Create sharelib directory for oozie.(Mohammad)


Reply via email to