Skip to content

Commit 72c7f01

Browse files
committed
Create DefaultLayout independent of PatternLayout
Currently, `PatternLayout` and all its patterns are a required element of Log4j Core, since `DefaultConfiguration` uses it. The default configuration is used in all Log4j Core installation as failsafe to handle logging between the time a logger context is created and the real configuration starts (a couple of ms). This PR creates a simple hardcoded layout to use with `DefaultConfiguration`.
1 parent 107e5e2 commit 72c7f01

File tree

2 files changed

+69
-5
lines changed

2 files changed

+69
-5
lines changed

log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
5959
import org.apache.logging.log4j.core.config.plugins.util.PluginType;
6060
import org.apache.logging.log4j.core.filter.AbstractFilterable;
61-
import org.apache.logging.log4j.core.layout.PatternLayout;
6261
import org.apache.logging.log4j.core.lookup.ConfigurationStrSubstitutor;
6362
import org.apache.logging.log4j.core.lookup.Interpolator;
6463
import org.apache.logging.log4j.core.lookup.PropertiesLookup;
@@ -779,10 +778,7 @@ public static Level getDefaultLevel() {
779778
protected void setToDefault() {
780779
// LOG4J2-1176 facilitate memory leak investigation
781780
setName(DefaultConfiguration.DEFAULT_NAME + "@" + Integer.toHexString(hashCode()));
782-
final Layout<? extends Serializable> layout = PatternLayout.newBuilder()
783-
.withPattern(DefaultConfiguration.DEFAULT_PATTERN)
784-
.withConfiguration(this)
785-
.build();
781+
final Layout<? extends Serializable> layout = DefaultConfiguration.createDefaultLayout();
786782
final Appender appender = ConsoleAppender.createDefaultAppenderForLayout(layout);
787783
appender.start();
788784
addAppender(appender);

log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfiguration.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
*/
1717
package org.apache.logging.log4j.core.config;
1818

19+
import java.io.IOException;
20+
import java.io.PrintWriter;
21+
import java.io.Writer;
22+
import java.nio.charset.Charset;
23+
import org.apache.logging.log4j.LoggingException;
24+
import org.apache.logging.log4j.core.Layout;
25+
import org.apache.logging.log4j.core.LogEvent;
26+
import org.apache.logging.log4j.core.layout.AbstractLayout;
27+
import org.apache.logging.log4j.core.util.StringBuilderWriter;
28+
import org.apache.logging.log4j.core.util.datetime.FixedDateFormat;
29+
import org.apache.logging.log4j.core.util.datetime.FixedDateFormat.FixedFormat;
30+
1931
/**
2032
* The default configuration writes all output to the Console using the default logging level. You configure default
2133
* logging level by setting the system property "org.apache.logging.log4j.level" to a level name. If you do not
@@ -49,4 +61,60 @@ public DefaultConfiguration() {
4961

5062
@Override
5163
protected void doConfigure() {}
64+
65+
static Layout<? extends String> createDefaultLayout() {
66+
return new DefaultLayout();
67+
}
68+
69+
/**
70+
* A simple layout used only by {@link DefaultConfiguration}
71+
* <p>
72+
* This layout allows to create applications that don't contain {@link org.apache.logging.log4j.core.layout.PatternLayout}
73+
* and all its patterns, e.g. GraalVM applications.
74+
* </p>
75+
*/
76+
private static final class DefaultLayout extends AbstractLayout<String> {
77+
78+
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
79+
80+
private final FixedDateFormat dateFormat = FixedDateFormat.create(FixedFormat.ABSOLUTE);
81+
82+
private DefaultLayout() {
83+
super(null, EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY);
84+
}
85+
86+
@Override
87+
public String toSerializable(LogEvent event) {
88+
try (Writer sw = new StringBuilderWriter();
89+
PrintWriter pw = new PrintWriter(sw)) {
90+
pw.append(dateFormat.format(event.getTimeMillis()))
91+
.append(" [")
92+
.append(event.getThreadName())
93+
.append("] ")
94+
.append(event.getLevel().toString())
95+
.append(" ")
96+
.append(event.getLoggerName())
97+
.append(" - ")
98+
.append(event.getMessage().getFormattedMessage())
99+
.append("\n");
100+
Throwable throwable = event.getThrown();
101+
if (throwable != null) {
102+
throwable.printStackTrace(pw);
103+
}
104+
return sw.toString();
105+
} catch (IOException e) {
106+
throw new LoggingException(e);
107+
}
108+
}
109+
110+
@Override
111+
public byte[] toByteArray(LogEvent event) {
112+
return toSerializable(event).getBytes(Charset.defaultCharset());
113+
}
114+
115+
@Override
116+
public String getContentType() {
117+
return "text/plain";
118+
}
119+
}
52120
}

0 commit comments

Comments
 (0)