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,49 +30,43 @@
/** /**
* 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) { this.eventBuffer = new ArrayDeque<>();
tail = new LinkedList<LoggingEvent>();
}
setFile(new File(this.containerLogDir, containerLogFile).toString());
setAppend(true);
super.activateOptions();
} }
setFile(new File(this.containerLogDir, containerLogFile).toString());
setAppend(true);
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 (eventBuffer != null) {
if (tail == null) { if (eventBuffer.size() == maxEvents) {
super.append(event); eventBuffer.removeFirst();
} else {
if (tail.size() >= maxEvents) {
tail.remove();
}
tail.add(event);
} }
eventBuffer.addLast(event);
} else {
super.append(event);
} }
} }
@Override @Override
public void flush() { public void flush() {
if (qw != null) { if (qw != null) {
@ -82,13 +76,17 @@ 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) {
super.append(event); for (LoggingEvent event : eventBuffer) {
super.append(event);
}
// let garbage collection do its work
eventBuffer = null;
} }
super.close();
} }
super.close();
} }
/** /**
@ -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);
} }
} }