vy commented on code in PR #2691:
URL: https://github.com/apache/logging-log4j2/pull/2691#discussion_r1746962343


##########
log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowableRenderer.java:
##########
@@ -0,0 +1,290 @@
+/*
+ * 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.logging.log4j.core.pattern;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.logging.log4j.core.util.internal.StringBuilders;
+
+class ThrowableRenderer<C extends ThrowableRenderer.Context> {
+
+    private static final String CAUSED_BY_CAPTION = "Caused by: ";
+
+    static final String SUPPRESSED_CAPTION = "Suppressed: ";
+
+    final List<String> ignoredPackageNames;
+
+    final int maxLineCount;
+
+    ThrowableRenderer(final List<String> ignoredPackageNames, final int 
maxLineCount) {
+        this.ignoredPackageNames = ignoredPackageNames;
+        this.maxLineCount = maxLineCount;
+    }
+
+    final void renderThrowable(final StringBuilder buffer, final Throwable 
throwable, final String lineSeparator) {
+        C context = createContext(throwable);
+        renderThrowable(buffer, throwable, context, new HashSet<>(), 
lineSeparator);
+        StringBuilders.truncateAfterDelimiter(buffer, lineSeparator, 
maxLineCount);
+    }
+
+    @SuppressWarnings("unchecked")
+    C createContext(final Throwable throwable) {
+        final Map<Throwable, Context.Metadata> metadataByThrowable = 
Context.Metadata.ofThrowable(throwable);
+        return (C) new Context(0, metadataByThrowable);
+    }
+
+    void renderThrowable(
+            final StringBuilder buffer,
+            final Throwable throwable,
+            final C context,
+            final Set<Throwable> visitedThrowables,
+            final String lineSeparator) {
+        renderThrowable(buffer, throwable, context, visitedThrowables, "", 
lineSeparator, "");
+    }
+
+    private void renderThrowable(
+            final StringBuilder buffer,
+            final Throwable throwable,
+            final C context,
+            final Set<Throwable> visitedThrowables,
+            final String prefix,
+            final String lineSeparator,
+            final String caption) {
+        if (visitedThrowables.contains(throwable)) {
+            return;
+        }
+        visitedThrowables.add(throwable);
+        buffer.append(prefix);
+        buffer.append(caption);
+        renderThrowableMessage(buffer, throwable);
+        buffer.append(lineSeparator);
+        renderStackTraceElements(buffer, throwable, context, prefix, 
lineSeparator);
+        renderSuppressed(buffer, throwable.getSuppressed(), context, 
visitedThrowables, prefix + '\t', lineSeparator);
+        renderCause(buffer, throwable.getCause(), context, visitedThrowables, 
prefix, lineSeparator);
+    }
+
+    void renderSuppressed(
+            final StringBuilder buffer,
+            final Throwable[] suppressedThrowables,
+            final C context,
+            final Set<Throwable> visitedThrowables,
+            final String prefix,
+            final String lineSeparator) {
+        for (final Throwable suppressedThrowable : suppressedThrowables) {
+            renderThrowable(
+                    buffer, suppressedThrowable, context, visitedThrowables, 
prefix, lineSeparator, SUPPRESSED_CAPTION);
+        }
+    }
+
+    void renderCause(
+            final StringBuilder buffer,
+            final Throwable cause,
+            final C context,
+            final Set<Throwable> visitedThrowables,
+            final String prefix,
+            final String lineSeparator) {
+        if (cause != null) {
+            renderThrowable(buffer, cause, context, visitedThrowables, prefix, 
lineSeparator, CAUSED_BY_CAPTION);
+        }
+    }
+
+    static void renderThrowableMessage(final StringBuilder buffer, final 
Throwable throwable) {
+        final String message = throwable.getMessage();
+        buffer.append(throwable.getClass().getName());
+        if (message != null) {
+            buffer.append(": ");
+            buffer.append(message);
+        }
+    }
+
+    final void renderStackTraceElements(
+            final StringBuilder buffer,
+            final Throwable throwable,
+            final C context,
+            final String prefix,
+            final String lineSeparator) {
+        context.ignoredStackTraceElementCount = 0;
+        final Context.Metadata metadata = 
context.metadataByThrowable.get(throwable);
+        final StackTraceElement[] stackTraceElements = 
throwable.getStackTrace();
+        for (int i = 0; i < metadata.stackLength; i++) {
+            renderStackTraceElement(buffer, stackTraceElements[i], context, 
prefix, lineSeparator);
+        }
+        if (context.ignoredStackTraceElementCount > 0) {
+            renderSuppressedCount(buffer, 
context.ignoredStackTraceElementCount, prefix, lineSeparator);
+        }
+        if (metadata.commonElementCount != 0) {
+            buffer.append(prefix);
+            buffer.append("\t... ");
+            buffer.append(metadata.commonElementCount);
+            buffer.append(" more");
+            buffer.append(lineSeparator);
+        }
+    }
+
+    void renderStackTraceElement(
+            final StringBuilder buffer,
+            final StackTraceElement stackTraceElement,
+            final C context,
+            final String prefix,
+            final String lineSeparator) {
+
+        // Short-circuit on ignored stack trace elements
+        final boolean stackTraceElementIgnored = 
isStackTraceElementIgnored(stackTraceElement, ignoredPackageNames);
+        if (stackTraceElementIgnored) {
+            context.ignoredStackTraceElementCount += 1;
+            return;
+        }
+
+        // Render the stack trace element
+        if (context.ignoredStackTraceElementCount > 0) {
+            renderSuppressedCount(buffer, 
context.ignoredStackTraceElementCount, prefix, lineSeparator);
+            context.ignoredStackTraceElementCount = 0;
+        }
+        buffer.append(prefix);
+        buffer.append("\tat ");
+        buffer.append(stackTraceElement.toString());
+        buffer.append(lineSeparator);
+    }

Review Comment:
   I prefer not to support/use `TextRenderer` anymore; it is an incomplete 
implementation, it is non-vital, and it will be dropped in Log4j 3.
   
   Note that in case of a push back from users, we always have the option to 
introduce it back.
   
   Are you strongly objecting? Can we convince you the other way around?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to