You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2022/10/01 18:59:41 UTC
[logging-log4j2] 01/02: [LOG4J2-1376] Define eid as String instead of int to allow for Oid according to RFC5424 (#836)
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit ad4e0c1925115807a3a4139b124eb416575e3daa
Author: mneundorfer <co...@mneundorfer.de>
AuthorDate: Mon May 16 10:01:03 2022 +0200
[LOG4J2-1376] Define eid as String instead of int to allow for Oid
according to RFC5424 (#836)
* LOG4J2-1376 - define eid as String instead of int to allow for Oid
according to RFC5424
* LOG4J2-1376 - Define eid as String to allow for OID fragments
Co-authored-by: ppkarwasz <pi...@karwasz.org>
---
.../log4j/message/StructuredDataMessageTest.java | 8 +
.../logging/log4j/message/StructuredDataId.java | 75 +++++++--
.../log4j/core/layout/Rfc5424LayoutTest.java | 85 ++++++++--
.../log4j/core/appender/SyslogAppender.java | 38 ++++-
.../logging/log4j/core/layout/LoggerFields.java | 11 +-
.../logging/log4j/core/layout/Rfc5424Layout.java | 178 ++++++++++++++++++---
.../log4j/flume/appender/FlumeAppender.java | 18 ++-
7 files changed, 351 insertions(+), 62 deletions(-)
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java
index 39e0d02b38..b592fcea8b 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java
@@ -108,4 +108,12 @@ public class StructuredDataMessageTest {
final String expected2 = "Alert [MsgId@1 memo=\"Added later\" message=\"Test message {}\" project=\"Log4j\"] Test message {}";
assertEquals(expected2, result2);
}
+
+ @Test
+ public void testEnterpriseNoAsOidFragment() {
+ final String testMsg = "Test message {}";
+ final StructuredDataMessage structuredDataMessage = new StructuredDataMessage("XX_DATA@1234.55.6.7", testMsg, "Nothing");
+ assertNotNull(structuredDataMessage);
+ }
+
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
index 2b21e6499b..47d392431c 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
@@ -47,14 +47,14 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
/**
* Reserved enterprise number.
*/
- public static final int RESERVED = -1;
+ public static final String RESERVED = "-1";
- private static final long serialVersionUID = 9031746276396249990L;
+ private static final long serialVersionUID = -8252896346202183738L;
private static final int MAX_LENGTH = 32;
private static final String AT_SIGN = "@";
private final String name;
- private final int enterpriseNumber;
+ private final String enterpriseNumber;
private final String[] required;
private final String[] optional;
@@ -111,7 +111,7 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
if (index > 0) {
this.name = name.substring(0, index);
- this.enterpriseNumber = Integer.parseInt(name.substring(index + 1));
+ this.enterpriseNumber = name.substring(index + 1).trim();
} else {
this.name = name;
this.enterpriseNumber = RESERVED;
@@ -128,11 +128,26 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
* @param required The list of keys that are required for this id.
* @param optional The list of keys that are optional for this id.
*/
- public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,
+ public StructuredDataId(final String name, final String enterpriseNumber, final String[] required,
final String[] optional) {
this(name, enterpriseNumber, required, optional, MAX_LENGTH);
}
+ /**
+ * A Constructor that helps conformance to RFC 5424.
+ *
+ * @param name The name portion of the id.
+ * @param enterpriseNumber The enterprise number.
+ * @param required The list of keys that are required for this id.
+ * @param optional The list of keys that are optional for this id.
+ * @deprecated Use {@link #StructuredDataId(String, String, String[], String[])} instead.
+ */
+ @Deprecated
+ public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,
+ final String[] optional) {
+ this(name, String.valueOf(enterpriseNumber), required, optional, MAX_LENGTH);
+ }
+
/**
* A Constructor that helps conformance to RFC 5424.
*
@@ -143,15 +158,15 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
* @param maxLength The maximum length of the StructuredData Id key.
* @since 2.9
*/
- public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,
- final String[] optional, final int maxLength) {
+ public StructuredDataId(final String name, final String enterpriseNumber, final String[] required,
+ final String[] optional, final int maxLength) {
if (name == null) {
throw new IllegalArgumentException("No structured id name was supplied");
}
if (name.contains(AT_SIGN)) {
throw new IllegalArgumentException("Structured id name cannot contain an " + Strings.quote(AT_SIGN));
}
- if (enterpriseNumber <= 0) {
+ if (RESERVED.equals(enterpriseNumber)) {
throw new IllegalArgumentException("No enterprise number was supplied");
}
this.name = name;
@@ -164,6 +179,23 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
this.optional = optional;
}
+ /**
+ * A Constructor that helps conformance to RFC 5424.
+ *
+ * @param name The name portion of the id.
+ * @param enterpriseNumber The enterprise number.
+ * @param required The list of keys that are required for this id.
+ * @param optional The list of keys that are optional for this id.
+ * @param maxLength The maximum length of the StructuredData Id key.
+ * @since 2.9
+ * @deprecated Use {@link #StructuredDataId(String, String, String[], String[], int)} instead.
+ */
+ @Deprecated
+ public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,
+ final String[] optional, final int maxLength) {
+ this(name, String.valueOf(enterpriseNumber), required, optional, maxLength);
+ }
+
/**
* Creates an id using another id to supply default values.
*
@@ -184,11 +216,11 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
* @param anEnterpriseNumber The enterprise number.
* @return a StructuredDataId.
*/
- public StructuredDataId makeId(final String defaultId, final int anEnterpriseNumber) {
- final String id;
- final String[] req;
- final String[] opt;
- if (anEnterpriseNumber <= 0) {
+ public StructuredDataId makeId(final String defaultId, final String anEnterpriseNumber) {
+ String id;
+ String[] req;
+ String[] opt;
+ if (RESERVED.equals(anEnterpriseNumber)) {
return this;
}
if (this.name != null) {
@@ -204,6 +236,19 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
return new StructuredDataId(id, anEnterpriseNumber, req, opt);
}
+ /**
+ * Creates an id based on the current id.
+ *
+ * @param defaultId The default id to use if this StructuredDataId doesn't have a name.
+ * @param anEnterpriseNumber The enterprise number.
+ * @return a StructuredDataId.
+ * @deprecated Use {@link StructuredDataId#makeId(String, String)} instead
+ */
+ @Deprecated
+ public StructuredDataId makeId(final String defaultId, final int anEnterpriseNumber) {
+ return makeId(defaultId, String.valueOf(anEnterpriseNumber));
+ }
+
/**
* Returns a list of required keys.
*
@@ -236,7 +281,7 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
*
* @return the enterprise number.
*/
- public int getEnterpriseNumber() {
+ public String getEnterpriseNumber() {
return enterpriseNumber;
}
@@ -246,7 +291,7 @@ public class StructuredDataId implements Serializable, StringBuilderFormattable
* @return true if the id uses the reserved enterprise number, false otherwise.
*/
public boolean isReserved() {
- return enterpriseNumber <= 0;
+ return RESERVED.equals(enterpriseNumber);
}
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java
index c5bad85c8d..aee0460aed 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java
@@ -16,6 +16,11 @@
*/
package org.apache.logging.log4j.core.layout;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
@@ -26,6 +31,7 @@ import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.net.Facility;
import org.apache.logging.log4j.core.test.BasicConfigurationFactory;
import org.apache.logging.log4j.core.test.appender.ListAppender;
+import org.apache.logging.log4j.core.util.Integers;
import org.apache.logging.log4j.core.util.KeyValuePair;
import org.apache.logging.log4j.core.util.ProcessIdUtil;
import org.apache.logging.log4j.message.StructuredDataCollectionMessage;
@@ -37,13 +43,15 @@ import org.apache.logging.log4j.util.Strings;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
@UsingAnyThreadContext
public class Rfc5424LayoutTest {
@@ -136,7 +144,7 @@ public class Rfc5424LayoutTest {
final int firstSpacePosition = frame.indexOf(' ');
final String messageLength = frame.substring(0, firstSpacePosition);
try {
- length = Integer.parseInt(messageLength);
+ length = Integers.parseInt(messageLength);
// the ListAppender removes the ending newline, so we expect one less size
assertEquals(frameLength, messageLength.length() + length);
}
@@ -189,7 +197,7 @@ public class Rfc5424LayoutTest {
final StructuredDataMessage msg2 = new StructuredDataMessage("Extra@18060", null, "Audit");
msg2.put("Item1", "Hello");
msg2.put("Item2", "World");
- List<StructuredDataMessage> messages = new ArrayList<>();
+ final List<StructuredDataMessage> messages = new ArrayList<>();
messages.add(msg);
messages.add(msg2);
final StructuredDataCollectionMessage collectionMessage = new StructuredDataCollectionMessage(messages);
@@ -214,7 +222,7 @@ public class Rfc5424LayoutTest {
final int firstSpacePosition = frame.indexOf(' ');
final String messageLength = frame.substring(0, firstSpacePosition);
try {
- length = Integer.parseInt(messageLength);
+ length = Integers.parseInt(messageLength);
// the ListAppender removes the ending newline, so we expect one less size
assertEquals(frameLength, messageLength.length() + length);
}
@@ -498,8 +506,8 @@ public class Rfc5424LayoutTest {
// set up appender
final AbstractStringLayout layout = Rfc5424Layout.createLayout(Facility.LOCAL0, "Event", 3692, true, "RequestContext",
null, null, true, null, "ATM", null, "key1, key2, locale", null, null, null, true, null, null);
- final ListAppender appender = new ListAppender("List", null, layout, true, false);
+ final ListAppender appender = new ListAppender("List", null, layout, true, false);
appender.start();
// set appender on root and set level to debug
@@ -517,4 +525,61 @@ public class Rfc5424LayoutTest {
appender.stop();
}
}
+
+ @Test
+ void testLayoutBuilder() {
+ for (final Appender appender : root.getAppenders().values()) {
+ root.removeAppender(appender);
+ }
+
+ final AbstractStringLayout layout = new Rfc5424Layout.Rfc5424LayoutBuilder()
+ .setFacility(Facility.LOCAL0)
+ .setId("Event")
+ .setEin("1234.56.7")
+ .setIncludeMDC(true)
+ .setMdcId("RequestContext")
+ .setIncludeNL(true)
+ .setAppName("ATM")
+ .setExcludes("key1, key2, locale")
+ .setUseTLSMessageFormat(true)
+ .build();
+
+ final ListAppender appender = new ListAppender("List", null, layout, true, false);
+ appender.start();
+
+ root.addAppender(appender);
+ root.setLevel(Level.DEBUG);
+ root.info("Hello {}", "World");
+ try {
+ final List<String> list = appender.getMessages();
+ assertTrue(list.size() > 0, "Not enough list entries");
+ final String message = list.get(0);
+ assertTrue(message.contains("Hello World"),
+ "Incorrect message. Expected - Hello World, Actual - " + message);
+ } finally {
+ root.removeAppender(appender);
+ appender.stop();
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = { "123456789", "0", "2147483647", "123.45.6.78.9", "0.0.0.0.0.0.0.0.0.0.0.0.0.0" })
+ void testLayoutBuilderValidEids(String eid) {
+ final AbstractStringLayout layout = new Rfc5424Layout.Rfc5424LayoutBuilder()
+ .setEin(eid)
+ .build();
+
+ assertNotNull(layout);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = { "abc", "someEid", "-1" })
+ void testLayoutBuilderInvalidEids(String eid) {
+ final AbstractStringLayout layout = new Rfc5424Layout.Rfc5424LayoutBuilder()
+ .setEin(eid)
+ .build();
+
+ assertNull(layout);
+ }
+
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
index 1d555475d0..14e36a4f5d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
@@ -56,7 +56,7 @@ public class SyslogAppender extends SocketAppender {
private String id;
@PluginBuilderAttribute(value = "enterpriseNumber")
- private int enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER;
+ private String enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER;
@PluginBuilderAttribute(value = "includeMdc")
private boolean includeMdc = true;
@@ -113,10 +113,26 @@ public class SyslogAppender extends SocketAppender {
Layout<? extends Serializable> layout = getLayout();
if (layout == null) {
layout = RFC5424.equalsIgnoreCase(format)
- ? Rfc5424Layout.createLayout(facility, id, enterpriseNumber, includeMdc, mdcId, mdcPrefix,
- eventPrefix, newLine, escapeNL, appName, msgId, excludes, includes, required,
- exceptionPattern, useTlsMessageFormat, loggerFields, configuration)
- :
+ ? new Rfc5424Layout.Rfc5424LayoutBuilder()
+ .setFacility(facility)
+ .setId(id)
+ .setEin(enterpriseNumber)
+ .setIncludeMDC(includeMdc)
+ .setMdcId(mdcId)
+ .setMdcPrefix(mdcPrefix)
+ .setEventPrefix(eventPrefix)
+ .setIncludeNL(newLine)
+ .setEscapeNL(escapeNL)
+ .setAppName(appName)
+ .setMessageId(msgId)
+ .setExcludes(excludes)
+ .setIncludes(includes)
+ .setRequired(required)
+ .setExceptionPattern(exceptionPattern)
+ .setUseTLSMessageFormat(useTlsMessageFormat)
+ .setLoggerFields(loggerFields)
+ .setConfig(configuration)
+ .build() :
// @formatter:off
SyslogLayout.newBuilder()
.setFacility(facility)
@@ -146,7 +162,7 @@ public class SyslogAppender extends SocketAppender {
return id;
}
- public int getEnterpriseNumber() {
+ public String getEnterpriseNumber() {
return enterpriseNumber;
}
@@ -220,11 +236,19 @@ public class SyslogAppender extends SocketAppender {
return asBuilder();
}
- public B setEnterpriseNumber(final int enterpriseNumber) {
+ public B setEnterpriseNumber(final String enterpriseNumber) {
this.enterpriseNumber = enterpriseNumber;
return asBuilder();
}
+ /**
+ * @deprecated Use {@link #setEnterpriseNumber(String)} instead
+ */
+ public B setEnterpriseNumber(final int enterpriseNumber) {
+ this.enterpriseNumber = String.valueOf(enterpriseNumber);
+ return asBuilder();
+ }
+
public B setIncludeMdc(final boolean includeMdc) {
this.includeMdc = includeMdc;
return asBuilder();
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/LoggerFields.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/LoggerFields.java
index fb44665885..b47ad6c7b6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/LoggerFields.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/LoggerFields.java
@@ -16,6 +16,10 @@
*/
package org.apache.logging.log4j.core.layout;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.logging.log4j.core.util.KeyValuePair;
import org.apache.logging.log4j.message.StructuredDataId;
import org.apache.logging.log4j.plugins.Configurable;
@@ -24,10 +28,6 @@ import org.apache.logging.log4j.plugins.PluginAttribute;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
/**
* A LoggerFields container.
*/
@@ -89,8 +89,7 @@ public final class LoggerFields {
if (enterpriseId == null || sdId == null) {
return null;
}
- final int eId = Integer.parseInt(enterpriseId);
- return new StructuredDataId(sdId, eId, null, null);
+ return new StructuredDataId(sdId, enterpriseId, null, null);
}
public boolean getDiscardIfAllFieldsAreEmpty() {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/Rfc5424Layout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/Rfc5424Layout.java
index 3cea03a754..76830e4f86 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/Rfc5424Layout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/Rfc5424Layout.java
@@ -72,9 +72,9 @@ import java.util.regex.Pattern;
public final class Rfc5424Layout extends AbstractStringLayout {
/**
- * Not a very good default - it is the Apache Software Foundation's enterprise number.
+ * The default example enterprise number from RFC5424.
*/
- public static final int DEFAULT_ENTERPRISE_NUMBER = 18060;
+ public static final String DEFAULT_ENTERPRISE_NUMBER = "32473";
/**
* The default event id.
*/
@@ -88,6 +88,11 @@ public final class Rfc5424Layout extends AbstractStringLayout {
*/
public static final Pattern PARAM_VALUE_ESCAPE_PATTERN = Pattern.compile("[\\\"\\]\\\\]");
+ /**
+ * For now, avoid too restrictive OID checks to allow for easier transition
+ */
+ public static final Pattern ENTERPRISE_ID_PATTERN = Pattern.compile("\\d+(\\.\\d+)*");
+
/**
* Default MDC ID: {@value} .
*/
@@ -102,7 +107,7 @@ public final class Rfc5424Layout extends AbstractStringLayout {
private final Facility facility;
private final String defaultId;
- private final int enterpriseNumber;
+ private final String enterpriseNumber;
private final boolean includeMdc;
private final String mdcId;
private final StructuredDataId mdcSdId;
@@ -127,11 +132,11 @@ public final class Rfc5424Layout extends AbstractStringLayout {
private final Map<String, FieldFormatter> fieldFormatters;
private final String procId;
- private Rfc5424Layout(final Configuration config, final Facility facility, final String id, final int ein,
- final boolean includeMDC, final boolean includeNL, final String escapeNL, final String mdcId,
- final String mdcPrefix, final String eventPrefix, final String appName, final String messageId,
- final String excludes, final String includes, final String required, final Charset charset,
- final String exceptionPattern, final boolean useTLSMessageFormat, final LoggerFields[] loggerFields) {
+ private Rfc5424Layout(final Configuration config, final Facility facility, final String id, final String ein,
+ final boolean includeMDC, final boolean includeNL, final String escapeNL, final String mdcId,
+ final String mdcPrefix, final String eventPrefix, final String appName, final String messageId,
+ final String excludes, final String includes, final String required, final Charset charset,
+ final String exceptionPattern, final boolean useTLSMessageFormat, final LoggerFields[] loggerFields) {
super(charset);
final PatternParser exceptionParser = createPatternParser(config, ThrowablePatternConverter.class);
exceptionFormatters = exceptionPattern == null ? null : exceptionParser.parse(exceptionPattern);
@@ -530,11 +535,11 @@ public final class Rfc5424Layout extends AbstractStringLayout {
} else {
sb.append(id.getName());
}
- int ein = id != null ? id.getEnterpriseNumber() : enterpriseNumber;
- if (ein < 0) {
+ String ein = id != null ? id.getEnterpriseNumber() : enterpriseNumber;
+ if (StructuredDataId.RESERVED.equals(ein)) {
ein = enterpriseNumber;
}
- if (ein >= 0) {
+ if (!StructuredDataId.RESERVED.equals(ein)) {
sb.append('@').append(ein);
}
return sb.toString();
@@ -605,18 +610,20 @@ public final class Rfc5424Layout extends AbstractStringLayout {
* @param loggerFields Container for the KeyValuePairs containing the patterns
* @param config The Configuration. Some Converters require access to the Interpolator.
* @return An Rfc5424Layout.
+ * @deprecated Use {@link Rfc5424LayoutBuilder instead}
*/
@PluginFactory
public static Rfc5424Layout createLayout(
// @formatter:off
- @PluginAttribute(defaultString = "LOCAL0") final Facility facility,
- @PluginAttribute final String id,
- @PluginAttribute(defaultInt = DEFAULT_ENTERPRISE_NUMBER) final int enterpriseNumber,
- @PluginAttribute(defaultBoolean = true) final boolean includeMDC,
- @PluginAttribute(defaultString = DEFAULT_MDCID) final String mdcId,
- @PluginAttribute final String mdcPrefix,
- @PluginAttribute final String eventPrefix,
- @PluginAttribute final boolean newLine,
+ @PluginAttribute(value = "facility", defaultString = "LOCAL0") final Facility facility,
+ @PluginAttribute("id") final String id,
+ @PluginAttribute(value = "enterpriseNumber", defaultInt = -1)
+ final int enterpriseNumber,
+ @PluginAttribute(value = "includeMDC", defaultBoolean = true) final boolean includeMDC,
+ @PluginAttribute(value = "mdcId", defaultString = DEFAULT_MDCID) final String mdcId,
+ @PluginAttribute("mdcPrefix") final String mdcPrefix,
+ @PluginAttribute("eventPrefix") final String eventPrefix,
+ @PluginAttribute(value = "newLine") final boolean newLine,
@PluginAttribute("newLineEscape") final String escapeNL,
@PluginAttribute final String appName,
@PluginAttribute("messageId") final String msgId,
@@ -634,11 +641,142 @@ public final class Rfc5424Layout extends AbstractStringLayout {
includes = null;
}
- return new Rfc5424Layout(config, facility, id, enterpriseNumber, includeMDC, newLine, escapeNL, mdcId,
+ return new Rfc5424Layout(config, facility, id, String.valueOf(enterpriseNumber), includeMDC, newLine, escapeNL, mdcId,
mdcPrefix, eventPrefix, appName, msgId, excludes, includes, required, StandardCharsets.UTF_8,
exceptionPattern, useTlsMessageFormat, loggerFields);
}
+ public static class Rfc5424LayoutBuilder {
+ private Configuration config;
+ private Facility facility;
+ private String id;
+ private String ein;
+ private boolean includeMDC;
+ private boolean includeNL;
+ private String escapeNL;
+ private String mdcId;
+ private String mdcPrefix;
+ private String eventPrefix;
+ private String appName;
+ private String messageId;
+ private String excludes;
+ private String includes;
+ private String required;
+ private Charset charset;
+ private String exceptionPattern;
+ private boolean useTLSMessageFormat;
+ private LoggerFields[] loggerFields;
+
+ public Rfc5424LayoutBuilder setConfig(Configuration config) {
+ this.config = config;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setFacility(Facility facility) {
+ this.facility = facility;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setEin(String ein) {
+ this.ein = ein;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setIncludeMDC(boolean includeMDC) {
+ this.includeMDC = includeMDC;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setIncludeNL(boolean includeNL) {
+ this.includeNL = includeNL;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setEscapeNL(String escapeNL) {
+ this.escapeNL = escapeNL;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setMdcId(String mdcId) {
+ this.mdcId = mdcId;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setMdcPrefix(String mdcPrefix) {
+ this.mdcPrefix = mdcPrefix;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setEventPrefix(String eventPrefix) {
+ this.eventPrefix = eventPrefix;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setAppName(String appName) {
+ this.appName = appName;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setMessageId(String messageId) {
+ this.messageId = messageId;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setExcludes(String excludes) {
+ this.excludes = excludes;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setIncludes(String includes) {
+ this.includes = includes;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setRequired(String required) {
+ this.required = required;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setCharset(Charset charset) {
+ this.charset = charset;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setExceptionPattern(String exceptionPattern) {
+ this.exceptionPattern = exceptionPattern;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setUseTLSMessageFormat(boolean useTLSMessageFormat) {
+ this.useTLSMessageFormat = useTLSMessageFormat;
+ return this;
+ }
+
+ public Rfc5424LayoutBuilder setLoggerFields(LoggerFields[] loggerFields) {
+ this.loggerFields = loggerFields;
+ return this;
+ }
+
+ public Rfc5424Layout build() {
+ if (includes != null && excludes != null) {
+ LOGGER.error("mdcIncludes and mdcExcludes are mutually exclusive. Includes wil be ignored");
+ includes = null;
+ }
+
+ if (ein != null && !ENTERPRISE_ID_PATTERN.matcher(ein).matches()) {
+ LOGGER.warn(String.format("provided EID %s is not in valid format!", ein));
+ return null;
+ }
+
+ return new Rfc5424Layout(config, facility, id, ein, includeMDC, includeNL, escapeNL, mdcId, mdcPrefix, eventPrefix, appName, messageId, excludes, includes, required, charset, exceptionPattern, useTLSMessageFormat, loggerFields);
+ }
+ }
+
private class FieldFormatter {
private final Map<String, List<PatternFormatter>> delegateMap;
diff --git a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java
index 8ef8d893ea..6b24870dec 100644
--- a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java
+++ b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java
@@ -253,10 +253,20 @@ public final class FlumeAppender extends AbstractAppender implements FlumeEventF
final int delayMillis = Integers.parseInt(maxDelayMillis, DEFAULT_MAX_DELAY);
if (layout == null) {
- final int enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER;
- layout = Rfc5424Layout.createLayout(Facility.LOCAL0, null, enterpriseNumber, true, Rfc5424Layout.DEFAULT_MDCID,
- mdcPrefix, eventPrefix, false, null, null, null, excludes, includes, required, null, false, null,
- null);
+ final String enterpriseNumber = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER;
+ layout = new Rfc5424Layout.Rfc5424LayoutBuilder()
+ .setFacility(Facility.LOCAL0)
+ .setEin(enterpriseNumber)
+ .setIncludeMDC(true)
+ .setMdcId(Rfc5424Layout.DEFAULT_MDCID)
+ .setMdcPrefix(mdcPrefix)
+ .setEventPrefix(eventPrefix)
+ .setIncludeNL(false)
+ .setExcludes(excludes)
+ .setIncludes(includes)
+ .setRequired(required)
+ .setUseTLSMessageFormat(false)
+ .build();
}
if (name == null) {