blob: 022de0b076565b1ce66a61be4115887e791dde9a [file] [log] [blame]
/**
* 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.hadoop.contrib.failmon;
import java.util.Properties;
import java.util.Calendar;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**********************************************************
* This class takes care of the information that needs to be
* persistently stored locally on nodes. Bookkeeping is done for the
* state of parsing of log files, so that the portion of the file that
* has already been parsed in previous calls will not be parsed again.
* For each log file, we maintain the byte offset of the last
* character parsed in previous passes. Also, the first entry in the
* log file is stored, so that FailMon can determine when a log file
* has been rotated (and thus parsing needs to start from the
* beginning of the file). We use a property file to store that
* information. For each log file we create a property keyed by the
* filename, the value of which contains the byte offset and first log
* entry separated by a SEPARATOR.
*
**********************************************************/
public class PersistentState {
private final static String SEPARATOR = "###";
static String filename;
static Properties persData = new Properties();
/**
* Read the state of parsing for all open log files from a property
* file.
*
* @param fname the filename of the property file to be read
*/
public static void readState(String fname) {
filename = fname;
try {
persData.load(new FileInputStream(filename));
} catch (FileNotFoundException e1) {
// ignore
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Read and return the state of parsing for a particular log file.
*
* @param fname the log file for which to read the state
*/
public static ParseState getState(String fname) {
String [] fields = persData.getProperty(fname, "null" + SEPARATOR + "0").split(SEPARATOR, 2);
String firstLine;
long offset;
if (fields.length < 2) {
System.err.println("Malformed persistent state data found");
Environment.logInfo("Malformed persistent state data found");
firstLine = null;
offset = 0;
} else {
firstLine = (fields[0].equals("null") ? null : fields[0]);
offset = Long.parseLong(fields[1]);
}
return new ParseState(fname, firstLine, offset);
}
/**
* Set the state of parsing for a particular log file.
*
* @param state the ParseState to set
*/
public static void setState(ParseState state) {
if (state == null) {
System.err.println("Null state found");
Environment.logInfo("Null state found");
}
persData.setProperty(state.filename, state.firstLine + SEPARATOR + state.offset);
}
/**
* Upadate the state of parsing for a particular log file.
*
* @param filename the log file for which to update the state
* @param firstLine the first line of the log file currently
* @param offset the byte offset of the last character parsed
*/
public static void updateState(String filename, String firstLine, long offset) {
ParseState ps = getState(filename);
if (firstLine != null)
ps.firstLine = firstLine;
ps.offset = offset;
setState(ps);
}
/**
* Write the state of parsing for all open log files to a property
* file on disk.
*
* @param fname the filename of the property file to write to
*/
public static void writeState(String fname) {
try {
persData.store(new FileOutputStream(fname), Calendar.getInstance().getTime().toString());
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**********************************************************
* This class represents the state of parsing for a particular log
* file.
*
**********************************************************/
class ParseState {
public String filename;
public String firstLine;
public long offset;
public ParseState(String _filename, String _firstLine, long _offset) {
this.filename = _filename;
this.firstLine = _firstLine;
this.offset = _offset;
}
}