blob: df126e0e0385dd63ff816c63e57d8834b9a2ffca [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.mapred;
import java.io.File;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
/**
* Event log used by the fair scheduler for machine-readable debug info.
* This class uses a log4j rolling file appender to write the log, but uses
* a custom tab-separated event format of the form:
* <pre>
* DATE EVENT_TYPE PARAM_1 PARAM_2 ...
* </pre>
* Various event types are used by the fair scheduler. The purpose of logging
* in this format is to enable tools to parse the history log easily and read
* internal scheduler variables, rather than trying to make the log human
* readable. The fair scheduler also logs human readable messages in the
* JobTracker's main log.
*
* Constructing this class creates a disabled log. It must be initialized
* using {@link FairSchedulerEventLog#init(Configuration, String)} to begin
* writing to the file.
*/
class FairSchedulerEventLog {
private static final Log LOG = LogFactory.getLog(
"org.apache.hadoop.mapred.FairSchedulerEventLog");
/** Set to true if logging is disabled due to an error. */
private boolean logDisabled = true;
/**
* Log directory, set by mapred.fairscheduler.eventlog.location in conf file;
* defaults to {hadoop.log.dir}/fairscheduler.
*/
private String logDir;
/**
* Active log file, which is {LOG_DIR}/hadoop-{user}-fairscheduler.{host}.log.
* Older files are also stored as {LOG_FILE}.date (date format YYYY-MM-DD).
*/
private String logFile;
/** Log4j appender used to write to the log file */
private DailyRollingFileAppender appender;
boolean init(Configuration conf, String jobtrackerHostname) {
try {
logDir = conf.get("mapred.fairscheduler.eventlog.location",
new File(System.getProperty("hadoop.log.dir")).getAbsolutePath()
+ File.separator + "fairscheduler");
Path logDirPath = new Path(logDir);
FileSystem fs = logDirPath.getFileSystem(conf);
if (!fs.exists(logDirPath)) {
if (!fs.mkdirs(logDirPath)) {
throw new IOException(
"Mkdirs failed to create " + logDirPath.toString());
}
}
String username = System.getProperty("user.name");
logFile = String.format("%s%shadoop-%s-fairscheduler-%s.log",
logDir, File.separator, username, jobtrackerHostname);
logDisabled = false;
PatternLayout layout = new PatternLayout("%d{ISO8601}\t%m%n");
appender = new DailyRollingFileAppender(layout, logFile, "'.'yyyy-MM-dd");
appender.activateOptions();
LOG.info("Initialized fair scheduler event log, logging to " + logFile);
} catch (IOException e) {
LOG.error(
"Failed to initialize fair scheduler event log. Disabling it.", e);
logDisabled = true;
}
return !(logDisabled);
}
/**
* Log an event, writing a line in the log file of the form
* <pre>
* DATE EVENT_TYPE PARAM_1 PARAM_2 ...
* </pre>
*/
synchronized void log(String eventType, Object... params) {
try {
if (logDisabled)
return;
StringBuffer buffer = new StringBuffer();
buffer.append(eventType);
for (Object param: params) {
buffer.append("\t");
buffer.append(param);
}
String message = buffer.toString();
Logger logger = Logger.getLogger(getClass());
appender.append(new LoggingEvent("", logger, Level.INFO, message, null));
} catch (Exception e) {
LOG.error("Failed to append to fair scheduler event log", e);
logDisabled = true;
}
}
/**
* Flush and close the log.
*/
void shutdown() {
try {
if (appender != null)
appender.close();
} catch (Exception e) {}
logDisabled = true;
}
boolean isEnabled() {
return !logDisabled;
}
}