|
@@ -38,7 +38,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
|
|
|
|
|
import javax.crypto.SecretKey;
|
|
|
|
|
|
-import com.google.common.base.Preconditions;
|
|
|
import org.apache.commons.logging.Log;
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
@@ -110,6 +109,7 @@ import org.apache.hadoop.yarn.state.MultipleArcTransition;
|
|
|
import org.apache.hadoop.yarn.state.SingleArcTransition;
|
|
|
import org.apache.hadoop.yarn.state.StateMachine;
|
|
|
import org.apache.hadoop.yarn.state.StateMachineFactory;
|
|
|
+import org.apache.hadoop.yarn.util.BoundedAppender;
|
|
|
import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
|
|
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
@@ -1326,7 +1326,7 @@ public class RMAppAttemptImpl implements RMAppAttempt, Recoverable {
|
|
|
// AFTER the initial saving on app-attempt-start
|
|
|
// These fields can be visible from outside only after they are saved in
|
|
|
// StateStore
|
|
|
- BoundedAppender diags = new BoundedAppender(diagnostics.limit);
|
|
|
+ BoundedAppender diags = new BoundedAppender(diagnostics.getLimit());
|
|
|
|
|
|
// don't leave the tracking URL pointing to a non-existent AM
|
|
|
if (conf.getBoolean(YarnConfiguration.APPLICATION_HISTORY_ENABLED,
|
|
@@ -2295,114 +2295,4 @@ public class RMAppAttemptImpl implements RMAppAttempt, Recoverable {
|
|
|
return Collections.EMPTY_SET;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * A {@link CharSequence} appender that considers its {@link #limit} as upper
|
|
|
- * bound.
|
|
|
- * <p>
|
|
|
- * When {@link #limit} would be reached on append, past messages will be
|
|
|
- * truncated from head, and a header telling the user about truncation will be
|
|
|
- * prepended, with ellipses in between header and messages.
|
|
|
- * <p>
|
|
|
- * Note that header and ellipses are not counted against {@link #limit}.
|
|
|
- * <p>
|
|
|
- * An example:
|
|
|
- *
|
|
|
- * <pre>
|
|
|
- * {@code
|
|
|
- * // At the beginning it's an empty string
|
|
|
- * final Appendable shortAppender = new BoundedAppender(80);
|
|
|
- * // The whole message fits into limit
|
|
|
- * shortAppender.append(
|
|
|
- * "message1 this is a very long message but fitting into limit\n");
|
|
|
- * // The first message is truncated, the second not
|
|
|
- * shortAppender.append("message2 this is shorter than the previous one\n");
|
|
|
- * // The first message is deleted, the second truncated, the third
|
|
|
- * // preserved
|
|
|
- * shortAppender.append("message3 this is even shorter message, maybe.\n");
|
|
|
- * // The first two are deleted, the third one truncated, the last preserved
|
|
|
- * shortAppender.append("message4 the shortest one, yet the greatest :)");
|
|
|
- * // Current contents are like this:
|
|
|
- * // Diagnostic messages truncated, showing last 80 chars out of 199:
|
|
|
- * // ...s is even shorter message, maybe.
|
|
|
- * // message4 the shortest one, yet the greatest :)
|
|
|
- * }
|
|
|
- * </pre>
|
|
|
- * <p>
|
|
|
- * Note that <tt>null</tt> values are {@link #append(CharSequence) append}ed
|
|
|
- * just like in {@link StringBuilder#append(CharSequence) original
|
|
|
- * implementation}.
|
|
|
- * <p>
|
|
|
- * Note that this class is not thread safe.
|
|
|
- */
|
|
|
- @VisibleForTesting
|
|
|
- static class BoundedAppender {
|
|
|
- @VisibleForTesting
|
|
|
- static final String TRUNCATED_MESSAGES_TEMPLATE =
|
|
|
- "Diagnostic messages truncated, showing last "
|
|
|
- + "%d chars out of %d:%n...%s";
|
|
|
-
|
|
|
- private final int limit;
|
|
|
- private final StringBuilder messages = new StringBuilder();
|
|
|
- private int totalCharacterCount = 0;
|
|
|
-
|
|
|
- BoundedAppender(final int limit) {
|
|
|
- Preconditions.checkArgument(limit > 0, "limit should be positive");
|
|
|
-
|
|
|
- this.limit = limit;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Append a {@link CharSequence} considering {@link #limit}, truncating
|
|
|
- * from the head of {@code csq} or {@link #messages} when necessary.
|
|
|
- *
|
|
|
- * @param csq the {@link CharSequence} to append
|
|
|
- * @return this
|
|
|
- */
|
|
|
- BoundedAppender append(final CharSequence csq) {
|
|
|
- appendAndCount(csq);
|
|
|
- checkAndCut();
|
|
|
-
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- private void appendAndCount(final CharSequence csq) {
|
|
|
- final int before = messages.length();
|
|
|
- messages.append(csq);
|
|
|
- final int after = messages.length();
|
|
|
- totalCharacterCount += after - before;
|
|
|
- }
|
|
|
-
|
|
|
- private void checkAndCut() {
|
|
|
- if (messages.length() > limit) {
|
|
|
- final int newStart = messages.length() - limit;
|
|
|
- messages.delete(0, newStart);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get current length of messages considering truncates
|
|
|
- * without header and ellipses.
|
|
|
- *
|
|
|
- * @return current length
|
|
|
- */
|
|
|
- int length() {
|
|
|
- return messages.length();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get a string representation of the actual contents, displaying also a
|
|
|
- * header and ellipses when there was a truncate.
|
|
|
- *
|
|
|
- * @return String representation of the {@link #messages}
|
|
|
- */
|
|
|
- @Override
|
|
|
- public String toString() {
|
|
|
- if (messages.length() < totalCharacterCount) {
|
|
|
- return String.format(TRUNCATED_MESSAGES_TEMPLATE, messages.length(),
|
|
|
- totalCharacterCount, messages.toString());
|
|
|
- }
|
|
|
-
|
|
|
- return messages.toString();
|
|
|
- }
|
|
|
- }
|
|
|
}
|