/** * 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.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Calendar; /********************************************************** * This class represents objects that provide log parsing * functionality. Typically, such objects read log files line * by line and for each log entry they identify, they create a * corresponding EventRecord. In this way, disparate log files * can be merged using the uniform format of EventRecords and can, * thus, be processed in a uniform way. * **********************************************************/ public abstract class LogParser implements Monitored { File file; BufferedReader reader; String hostname; Object [] ips; String dateformat; String timeformat; private String firstLine; private long offset; /** * Create a parser that will read from the specified log file. * * @param fname the filename of the log file to be read */ public LogParser(String fname) { file = new File(fname); ParseState ps = PersistentState.getState(file.getAbsolutePath()); firstLine = ps.firstLine; offset = ps.offset; try { reader = new BufferedReader(new FileReader(file)); checkForRotation(); Environment.logInfo("Checked for rotation..."); reader.skip(offset); } catch (FileNotFoundException e) { System.err.println(e.getMessage()); e.printStackTrace(); } catch (IOException e) { System.err.println(e.getMessage()); e.printStackTrace(); } setNetworkProperties(); } protected void setNetworkProperties() { // determine hostname and ip addresses for the node try { // Get hostname hostname = InetAddress.getLocalHost().getCanonicalHostName(); // Get all associated ip addresses ips = InetAddress.getAllByName(hostname); } catch (UnknownHostException e) { e.printStackTrace(); } } /** * Insert all EventRecords that can be extracted for * the represented hardware component into a LocalStore. * * @param ls the LocalStore into which the EventRecords * are to be stored. */ public void monitor(LocalStore ls) { int in = 0; EventRecord er = null; Environment.logInfo("Started processing log..."); while ((er = getNext()) != null) { // Environment.logInfo("Processing log line:\t" + in++); if (er.isValid()) { ls.insert(er); } } PersistentState.updateState(file.getAbsolutePath(), firstLine, offset); PersistentState.writeState("conf/parsing.state"); } /** * Get an array of all EventRecords that can be extracted for * the represented hardware component. * * @return The array of EventRecords */ public EventRecord[] monitor() { ArrayList<EventRecord> recs = new ArrayList<EventRecord>(); EventRecord er; while ((er = getNext()) != null) recs.add(er); EventRecord[] T = new EventRecord[recs.size()]; return recs.toArray(T); } /** * Continue parsing the log file until a valid log entry is identified. * When one such entry is found, parse it and return a corresponding EventRecord. * * * @return The EventRecord corresponding to the next log entry */ public EventRecord getNext() { try { String line = reader.readLine(); if (line != null) { if (firstLine == null) firstLine = new String(line); offset += line.length() + 1; return parseLine(line); } } catch (IOException e) { e.printStackTrace(); } return null; } /** * Return the BufferedReader, that reads the log file * * @return The BufferedReader that reads the log file */ public BufferedReader getReader() { return reader; } /** * Check whether the log file has been rotated. If so, * start reading the file from the beginning. * */ public void checkForRotation() { try { BufferedReader probe = new BufferedReader(new FileReader(file.getAbsoluteFile())); if (firstLine == null || (!firstLine.equals(probe.readLine()))) { probe.close(); // start reading the file from the beginning reader.close(); reader = new BufferedReader(new FileReader(file.getAbsoluteFile())); firstLine = null; offset = 0; } } catch (IOException e) { e.printStackTrace(); } } /** * Parses one line of the log. If the line contains a valid * log entry, then an appropriate EventRecord is returned, after all * relevant fields have been parsed. * * @param line the log line to be parsed * * @return the EventRecord representing the log entry of the line. If * the line does not contain a valid log entry, then the EventRecord * returned has isValid() = false. When the end-of-file has been reached, * null is returned to the caller. */ abstract public EventRecord parseLine(String line) throws IOException; /** * Parse a date found in Hadoop log file. * * @return a Calendar representing the date */ abstract protected Calendar parseDate(String strDate, String strTime); }