This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/release-2.x by this push:
new 303045d [LOG4J2-2337] Allow custom end-of-line with JsonLayout (2.x
branch) (#264)
303045d is described below
commit 303045d1602bd2bd73cf6a1e60026830369389ba
Author: Patrice Ferrot <[email protected]>
AuthorDate: Tue Apr 23 15:09:06 2019 +0200
[LOG4J2-2337] Allow custom end-of-line with JsonLayout (2.x branch) (#264)
* Allow custom end-of-line with JsonLayout (fix for LOG4J2-2337)
* Added justification for JsonLayout constructor change
---
log4j-core/revapi.json | 6 +++++
.../log4j/core/layout/AbstractJacksonLayout.java | 18 +++++++++++---
.../logging/log4j/core/layout/JsonLayout.java | 14 +++++------
.../logging/log4j/core/layout/XmlLayout.java | 12 ++++-----
.../logging/log4j/core/layout/YamlLayout.java | 12 ++++-----
.../logging/log4j/core/layout/JsonLayoutTest.java | 29 ++++++++++++++++------
src/site/xdoc/manual/layouts.xml.vm | 8 ++++++
7 files changed, 69 insertions(+), 30 deletions(-)
diff --git a/log4j-core/revapi.json b/log4j-core/revapi.json
index ae62904..fd2438b 100644
--- a/log4j-core/revapi.json
+++ b/log4j-core/revapi.json
@@ -77,6 +77,12 @@
"old": "method java.net.Socket
org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.lang.String,
int, org.apache.logging.log4j.core.net.SocketOptions, int) throws
java.io.IOException",
"new": "method java.net.Socket
org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.net.InetSocketAddress)
throws java.io.IOException",
"justification": "LOG4J2-2586 - Support the host name resolving to
mulitple ip addresses"
+ },
+ {
+ "code": "java.method.numberOfParametersChanged",
+ "old": "method void
org.apache.logging.log4j.core.layout.JsonLayout::<init>(org.apache.logging.log4j.core.config.Configuration,
boolean, boolean, boolean, boolean, boolean, boolean, java.lang.String,
java.lang.String, java.nio.charset.Charset, boolean)",
+ "new": "method void
org.apache.logging.log4j.core.layout.JsonLayout::<init>(org.apache.logging.log4j.core.config.Configuration,
boolean, boolean, boolean, boolean, boolean, boolean, java.lang.String,
java.lang.String, java.lang.String, java.nio.charset.Charset, boolean)",
+ "justification": "LOG4J2-2337 - Allow to specify custom end-of-line
for JSON layout"
}
]
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
index 2e6f652..2e5e7f4 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
@@ -52,6 +52,9 @@ abstract class AbstractJacksonLayout extends
AbstractStringLayout {
private boolean eventEol;
@PluginBuilderAttribute
+ private String endOfLine;
+
+ @PluginBuilderAttribute
private boolean compact;
@PluginBuilderAttribute
@@ -83,6 +86,10 @@ abstract class AbstractJacksonLayout extends
AbstractStringLayout {
return eventEol;
}
+ public String getEndOfLine() {
+ return endOfLine;
+ }
+
public boolean isCompact() {
return compact;
}
@@ -122,6 +129,11 @@ abstract class AbstractJacksonLayout extends
AbstractStringLayout {
return asBuilder();
}
+ public B setEndOfLine(final String endOfLine) {
+ this.endOfLine = endOfLine;
+ return asBuilder();
+ }
+
public B setCompact(final boolean compact) {
this.compact = compact;
return asBuilder();
@@ -201,18 +213,18 @@ abstract class AbstractJacksonLayout extends
AbstractStringLayout {
protected AbstractJacksonLayout(final Configuration config, final
ObjectWriter objectWriter, final Charset charset,
final boolean compact, final boolean complete, final boolean
eventEol, final Serializer headerSerializer,
final Serializer footerSerializer, final boolean
includeNullDelimiter) {
- this(config, objectWriter, charset, compact, complete, eventEol,
headerSerializer, footerSerializer, includeNullDelimiter, null);
+ this(config, objectWriter, charset, compact, complete, eventEol, null,
headerSerializer, footerSerializer, includeNullDelimiter, null);
}
protected AbstractJacksonLayout(final Configuration config, final
ObjectWriter objectWriter, final Charset charset,
- final boolean compact, final boolean complete, final boolean
eventEol, final Serializer headerSerializer,
+ final boolean compact, final boolean complete, final boolean
eventEol, final String endOfLine, final Serializer headerSerializer,
final Serializer footerSerializer, final boolean
includeNullDelimiter,
final KeyValuePair[] additionalFields) {
super(config, charset, headerSerializer, footerSerializer);
this.objectWriter = objectWriter;
this.compact = compact;
this.complete = complete;
- this.eol = compact && !eventEol ? COMPACT_EOL : DEFAULT_EOL;
+ this.eol = endOfLine != null ? endOfLine : compact && !eventEol ?
COMPACT_EOL : DEFAULT_EOL;
this.includeNullDelimiter = includeNullDelimiter;
this.additionalFields = prepareAdditionalFields(config,
additionalFields);
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
index fbbd597..679f55c 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
@@ -97,7 +97,7 @@ public final class JsonLayout extends AbstractJacksonLayout {
final String headerPattern = toStringOrNull(getHeader());
final String footerPattern = toStringOrNull(getFooter());
return new JsonLayout(getConfiguration(), isLocationInfo(),
isProperties(), encodeThreadContextAsList,
- isComplete(), isCompact(), getEventEol(), headerPattern,
footerPattern, getCharset(),
+ isComplete(), isCompact(), getEventEol(), getEndOfLine(),
headerPattern, footerPattern, getCharset(),
isIncludeStacktrace(), isStacktraceAsString(),
isIncludeNullDelimiter(),
getAdditionalFields(), getObjectMessageAsJsonObject());
}
@@ -138,11 +138,11 @@ public final class JsonLayout extends
AbstractJacksonLayout {
@Deprecated
protected JsonLayout(final Configuration config, final boolean
locationInfo, final boolean properties,
final boolean encodeThreadContextAsList,
- final boolean complete, final boolean compact, final boolean
eventEol, final String headerPattern,
+ final boolean complete, final boolean compact, final boolean
eventEol, final String endOfLine,final String headerPattern,
final String footerPattern, final Charset charset, final boolean
includeStacktrace) {
super(config, new JacksonFactory.JSON(encodeThreadContextAsList,
includeStacktrace, false, false).newWriter(
locationInfo, properties, compact),
- charset, compact, complete, eventEol,
+ charset, compact, complete, eventEol, endOfLine,
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
false, null);
@@ -150,14 +150,14 @@ public final class JsonLayout extends
AbstractJacksonLayout {
private JsonLayout(final Configuration config, final boolean locationInfo,
final boolean properties,
final boolean encodeThreadContextAsList,
- final boolean complete, final boolean compact, final
boolean eventEol,
+ final boolean complete, final boolean compact, final
boolean eventEol, final String endOfLine,
final String headerPattern, final String footerPattern,
final Charset charset,
final boolean includeStacktrace, final boolean
stacktraceAsString,
final boolean includeNullDelimiter,
final KeyValuePair[] additionalFields, final boolean
objectMessageAsJsonObject) {
super(config, new JacksonFactory.JSON(encodeThreadContextAsList,
includeStacktrace, stacktraceAsString, objectMessageAsJsonObject).newWriter(
locationInfo, properties, compact),
- charset, compact, complete, eventEol,
+ charset, compact, complete, eventEol, endOfLine,
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
includeNullDelimiter,
@@ -265,7 +265,7 @@ public final class JsonLayout extends AbstractJacksonLayout
{
final boolean includeStacktrace) {
final boolean encodeThreadContextAsList = properties &&
propertiesAsList;
return new JsonLayout(config, locationInfo, properties,
encodeThreadContextAsList, complete, compact, eventEol,
- headerPattern, footerPattern, charset, includeStacktrace,
false, false, null, false);
+ null, headerPattern, footerPattern, charset,
includeStacktrace, false, false, null, false);
}
@PluginBuilderFactory
@@ -279,7 +279,7 @@ public final class JsonLayout extends AbstractJacksonLayout
{
* @return A JSON Layout.
*/
public static JsonLayout createDefaultLayout() {
- return new JsonLayout(new DefaultConfiguration(), false, false, false,
false, false, false,
+ return new JsonLayout(new DefaultConfiguration(), false, false, false,
false, false, false, null,
DEFAULT_HEADER, DEFAULT_FOOTER, StandardCharsets.UTF_8, true,
false, false, null, false);
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
index c9cd886..94f6c40 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
@@ -75,7 +75,7 @@ public final class XmlLayout extends AbstractJacksonLayout {
@Override
public XmlLayout build() {
return new XmlLayout(getConfiguration(), isLocationInfo(),
isProperties(), isComplete(),
- isCompact(), getCharset(), isIncludeStacktrace(),
isStacktraceAsString(),
+ isCompact(), getEndOfLine(), getCharset(),
isIncludeStacktrace(), isStacktraceAsString(),
isIncludeNullDelimiter(), getAdditionalFields());
}
}
@@ -86,17 +86,17 @@ public final class XmlLayout extends AbstractJacksonLayout {
@Deprecated
protected XmlLayout(final boolean locationInfo, final boolean properties,
final boolean complete,
final boolean compact, final Charset charset, final
boolean includeStacktrace) {
- this(null, locationInfo, properties, complete, compact, charset,
includeStacktrace, false, false, null);
+ this(null, locationInfo, properties, complete, compact, null, charset,
includeStacktrace, false, false, null);
}
private XmlLayout(final Configuration config, final boolean locationInfo,
final boolean properties,
- final boolean complete, final boolean compact, final
Charset charset,
+ final boolean complete, final boolean compact, final
String endOfLine, final Charset charset,
final boolean includeStacktrace, final boolean
stacktraceAsString,
final boolean includeNullDelimiter,
final KeyValuePair[] additionalFields) {
super(config, new JacksonFactory.XML(includeStacktrace,
stacktraceAsString).newWriter(
locationInfo, properties, compact),
- charset, compact, complete, false, null, null,
includeNullDelimiter,
+ charset, compact, complete, false, endOfLine, null, null,
includeNullDelimiter,
additionalFields);
}
@@ -188,7 +188,7 @@ public final class XmlLayout extends AbstractJacksonLayout {
final boolean compact,
final Charset charset,
final boolean includeStacktrace) {
- return new XmlLayout(null, locationInfo, properties, complete,
compact, charset, includeStacktrace, false,
+ return new XmlLayout(null, locationInfo, properties, complete,
compact, null, charset, includeStacktrace, false,
false, null);
}
@@ -203,6 +203,6 @@ public final class XmlLayout extends AbstractJacksonLayout {
* @return an XML Layout.
*/
public static XmlLayout createDefaultLayout() {
- return new XmlLayout(null, false, false, false, false,
StandardCharsets.UTF_8, true, false, false, null);
+ return new XmlLayout(null, false, false, false, false, null,
StandardCharsets.UTF_8, true, false, false, null);
}
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
index 0245cd8..4cf803c 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
@@ -67,7 +67,7 @@ public final class YamlLayout extends AbstractJacksonLayout {
final String headerPattern = toStringOrNull(getHeader());
final String footerPattern = toStringOrNull(getFooter());
return new YamlLayout(getConfiguration(), isLocationInfo(),
isProperties(), isComplete(),
- isCompact(), getEventEol(), headerPattern, footerPattern,
getCharset(),
+ isCompact(), getEventEol(), getEndOfLine(), headerPattern,
footerPattern, getCharset(),
isIncludeStacktrace(), isStacktraceAsString(),
isIncludeNullDelimiter(),
getAdditionalFields());
}
@@ -81,20 +81,20 @@ public final class YamlLayout extends AbstractJacksonLayout
{
final boolean complete, final boolean compact, final boolean
eventEol, final String headerPattern,
final String footerPattern, final Charset charset, final boolean
includeStacktrace) {
super(config, new JacksonFactory.YAML(includeStacktrace,
false).newWriter(locationInfo, properties, compact),
- charset, compact, complete, eventEol,
+ charset, compact, complete, eventEol, null,
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
false, null);
}
private YamlLayout(final Configuration config, final boolean locationInfo,
final boolean properties,
- final boolean complete, final boolean compact, final
boolean eventEol,
+ final boolean complete, final boolean compact, final
boolean eventEol, final String endOfLine,
final String headerPattern, final String footerPattern,
final Charset charset,
final boolean includeStacktrace, final boolean
stacktraceAsString,
final boolean includeNullDelimiter,
final KeyValuePair[] additionalFields) {
super(config, new JacksonFactory.YAML(includeStacktrace,
stacktraceAsString).newWriter(locationInfo, properties, compact),
- charset, compact, complete, eventEol,
+ charset, compact, complete, eventEol, endOfLine,
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
includeNullDelimiter,
@@ -185,7 +185,7 @@ public final class YamlLayout extends AbstractJacksonLayout
{
final String footerPattern,
final Charset charset,
final boolean includeStacktrace) {
- return new YamlLayout(config, locationInfo, properties, false, false,
true, headerPattern, footerPattern,
+ return new YamlLayout(config, locationInfo, properties, false, false,
true, null, headerPattern, footerPattern,
charset, includeStacktrace, false, false, null);
}
@@ -200,7 +200,7 @@ public final class YamlLayout extends AbstractJacksonLayout
{
* @return A YAML Layout.
*/
public static AbstractJacksonLayout createDefaultLayout() {
- return new YamlLayout(new DefaultConfiguration(), false, false, false,
false, false, DEFAULT_HEADER,
+ return new YamlLayout(new DefaultConfiguration(), false, false, false,
false, false, null, DEFAULT_HEADER,
DEFAULT_FOOTER, StandardCharsets.UTF_8, true, false, false,
null);
}
}
diff --git
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
index 9dfade0..7bdd4cc 100644
---
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
+++
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
@@ -133,7 +133,7 @@ public class JsonLayoutTest {
}
private void testAllFeatures(final boolean locationInfo, final boolean
compact, final boolean eventEol,
- final boolean includeContext, final boolean contextMapAslist,
final boolean includeStacktrace)
+ final String endOfLine, final boolean includeContext, final
boolean contextMapAslist, final boolean includeStacktrace)
throws Exception {
final Log4jLogEvent expected = LogEventFixtures.createLogEvent();
// @formatter:off
@@ -144,16 +144,24 @@ public class JsonLayoutTest {
.setComplete(false)
.setCompact(compact)
.setEventEol(eventEol)
+ .setEndOfLine(endOfLine)
.setCharset(StandardCharsets.UTF_8)
.setIncludeStacktrace(includeStacktrace)
.build();
// @formatter:off
final String str = layout.toSerializable(expected);
this.toPropertySeparator(compact);
- // Just check for \n since \r might or might not be there.
- assertEquals(str, !compact || eventEol, str.contains("\n"));
+ if (endOfLine == null) {
+ // Just check for \n since \r might or might not be there.
+ assertEquals(str, !compact || eventEol, str.contains("\n"));
+ }
+ else {
+ assertEquals(str, !compact || eventEol, str.contains(endOfLine));
+ assertEquals(str, compact && eventEol, str.endsWith(endOfLine));
+ }
assertEquals(str, locationInfo, str.contains("source"));
assertEquals(str, includeContext, str.contains("contextMap"));
+
final Log4jLogEvent actual = new
Log4jJsonObjectMapper(contextMapAslist, includeStacktrace, false,
false).readValue(str, Log4jLogEvent.class);
LogEventFixtures.assertEqualLogEvents(expected, actual, locationInfo,
includeContext, includeStacktrace);
if (includeContext) {
@@ -453,27 +461,32 @@ public class JsonLayoutTest {
@Test
public void testLocationOffCompactOffMdcOff() throws Exception {
- this.testAllFeatures(false, false, false, false, false, true);
+ this.testAllFeatures(false, false, false, null, false, false, true);
}
@Test
public void testLocationOnCompactOnMdcOn() throws Exception {
- this.testAllFeatures(true, true, false, true, false, true);
+ this.testAllFeatures(true, true, false, null, true, false, true);
}
@Test
public void testLocationOnCompactOnEventEolOnMdcOn() throws Exception {
- this.testAllFeatures(true, true, true, true, false, true);
+ this.testAllFeatures(true, true, true, null, true, false, true);
}
@Test
public void testLocationOnCompactOnEventEolOnMdcOnMdcAsList() throws
Exception {
- this.testAllFeatures(true, true, true, true, true, true);
+ this.testAllFeatures(true, true, true, null, true, true, true);
}
@Test
public void testExcludeStacktrace() throws Exception {
- this.testAllFeatures(false, false, false, false, false, false);
+ this.testAllFeatures(false, false, false, null, false, false, false);
+ }
+
+ @Test
+ public void testLocationOnCustomEndOfLine() throws Exception {
+ this.testAllFeatures(true, true, true, "CUSTOM_END_OF_LINE", true,
false, true);
}
@Test
diff --git a/src/site/xdoc/manual/layouts.xml.vm
b/src/site/xdoc/manual/layouts.xml.vm
index 0508966..73d9722 100644
--- a/src/site/xdoc/manual/layouts.xml.vm
+++ b/src/site/xdoc/manual/layouts.xml.vm
@@ -429,6 +429,14 @@ logger.debug("one={}, two={}, three={}", 1, 2, 3);
</td>
</tr>
<tr>
+ <td>endOfLine</td>
+ <td>String</td>
+ <td>
+ If set, overrides the default end-of-line string. E.g. set it
to "\n" and use with eventEol=true and compact=true
+ to have one record per line separated by "\n" instead of
"\r\n". Defaults to null (i.e. not set).
+ </td>
+ </tr>
+ <tr>
<td>complete</td>
<td>boolean</td>
<td>If true, the appender includes the JSON header and footer,
and comma between records. Defaults to false.</td>