YARN-7687. ContainerLogAppender Improvements. Contributed by BELUGA BEHR.

This commit is contained in:
Miklos Szegedi 2018-01-02 16:36:51 -08:00
parent 5c28804b95
commit 33ae2a4ae1

View File

@ -20,8 +20,8 @@
import java.io.File; import java.io.File;
import java.io.Flushable; import java.io.Flushable;
import java.util.LinkedList; import java.util.ArrayDeque;
import java.util.Queue; import java.util.Deque;
import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Unstable; import org.apache.hadoop.classification.InterfaceStability.Unstable;
@ -30,46 +30,40 @@
/** /**
* A simple log4j-appender for container's logs. * A simple log4j-appender for container's logs.
*
*/ */
@Public @Public
@Unstable @Unstable
public class ContainerLogAppender extends FileAppender public class ContainerLogAppender extends FileAppender
implements Flushable implements Flushable {
{
private String containerLogDir; private String containerLogDir;
private String containerLogFile; private String containerLogFile;
//so that log4j can configure it from the configuration(log4j.properties).
private int maxEvents; private int maxEvents;
private Queue<LoggingEvent> tail = null; private Deque<LoggingEvent> eventBuffer;
private boolean closing = false; private boolean closed = false;
@Override @Override
public void activateOptions() { public synchronized void activateOptions() {
synchronized (this) {
if (maxEvents > 0) { if (maxEvents > 0) {
tail = new LinkedList<LoggingEvent>(); this.eventBuffer = new ArrayDeque<>();
} }
setFile(new File(this.containerLogDir, containerLogFile).toString()); setFile(new File(this.containerLogDir, containerLogFile).toString());
setAppend(true); setAppend(true);
super.activateOptions(); super.activateOptions();
} }
}
@Override @Override
public void append(LoggingEvent event) { public synchronized void append(LoggingEvent event) {
synchronized (this) { if (closed) {
if (closing) { // When closing drop any new/transitive CLA appending
return; return;
} }
if (tail == null) { if (eventBuffer != null) {
super.append(event); if (eventBuffer.size() == maxEvents) {
eventBuffer.removeFirst();
}
eventBuffer.addLast(event);
} else { } else {
if (tail.size() >= maxEvents) { super.append(event);
tail.remove();
}
tail.add(event);
}
} }
} }
@ -82,14 +76,18 @@ public void flush() {
@Override @Override
public synchronized void close() { public synchronized void close() {
closing = true; if (!closed) {
if (tail != null) { closed = true;
for (LoggingEvent event : tail) { if (eventBuffer != null) {
for (LoggingEvent event : eventBuffer) {
super.append(event); super.append(event);
} }
// let garbage collection do its work
eventBuffer = null;
} }
super.close(); super.close();
} }
}
/** /**
* Getter/Setter methods for log4j. * Getter/Setter methods for log4j.
@ -111,13 +109,17 @@ public void setContainerLogFile(String containerLogFile) {
this.containerLogFile = containerLogFile; this.containerLogFile = containerLogFile;
} }
private static final int EVENT_SIZE = 100; private static final long EVENT_SIZE = 100;
public long getTotalLogFileSize() { public long getTotalLogFileSize() {
return maxEvents * EVENT_SIZE; return maxEvents * EVENT_SIZE;
} }
/**
* Setter so that log4j can configure it from the
* configuration(log4j.properties).
*/
public void setTotalLogFileSize(long logSize) { public void setTotalLogFileSize(long logSize) {
maxEvents = (int) logSize / EVENT_SIZE; maxEvents = (int)(logSize / EVENT_SIZE);
} }
} }