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)