You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2013/11/18 04:38:14 UTC
svn commit: r1542883 - in /logging/log4j/log4j2/trunk: ./
log4j-core/src/test/resources/ log4j-flume-ng/
log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/
log4j-flume-ng/src/test/java/org/apache/logging/log4j/flume/appender/
log4j-f...
Author: rgoers
Date: Mon Nov 18 03:38:13 2013
New Revision: 1542883
URL: http://svn.apache.org/r1542883
Log:
LOG4J2-453 - Upgrade Flume Appender to Flume 1.4.0
Removed:
logging/log4j/log4j2/trunk/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeConfigurationBuilder.java
logging/log4j/log4j2/trunk/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeNode.java
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/test/resources/log4j-routing2.json
logging/log4j/log4j2/trunk/log4j-flume-ng/pom.xml
logging/log4j/log4j2/trunk/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java
logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedAppenderTest.java
logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/default_embedded.xml
logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/embedded.xml
logging/log4j/log4j2/trunk/pom.xml
logging/log4j/log4j2/trunk/src/changes/changes.xml
Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/resources/log4j-routing2.json
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/resources/log4j-routing2.json?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/resources/log4j-routing2.json (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/resources/log4j-routing2.json Mon Nov 18 03:38:13 2013
@@ -14,7 +14,7 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-{ "configuration": { "status": "error", "name": "RoutingTest", "packages": "org.apache.logging.log4j.test",
+{ "configuration": { "status": "debug", "name": "RoutingTest", "packages": "org.apache.logging.log4j.test",
"properties": {
"property": { "name": "filename", "value" : "target/rolling1/rollingtest-$${sd:type}.log" }
},
@@ -44,7 +44,8 @@
"loggers": {
"logger": [
{ "name": "EventLogger", "level": "info", "additivity": "false", "AppenderRef": { "ref": "Routing" }},
- { "name": "com.foo.bar", "level": "error", "additivity": "false", "AppenderRef": { "ref": "STDOUT" }}
+ { "name": "com.foo.bar", "level": "error", "additivity": "false", "AppenderRef": { "ref": "STDOUT" }},
+ { "name": "org.apache.logging", "level": "error", "additivity": "false", "AppenderRef": [{"ref": "List"}, {"ref": "STDOUT"}]}
],
"root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
}
Modified: logging/log4j/log4j2/trunk/log4j-flume-ng/pom.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-flume-ng/pom.xml?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-flume-ng/pom.xml (original)
+++ logging/log4j/log4j2/trunk/log4j-flume-ng/pom.xml Mon Nov 18 03:38:13 2013
@@ -56,6 +56,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-jcl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
@@ -79,7 +84,7 @@
</dependency>
<dependency>
<groupId>org.apache.flume</groupId>
- <artifactId>flume-ng-node</artifactId>
+ <artifactId>flume-ng-embedded-agent</artifactId>
<optional>true</optional>
</dependency>
<dependency>
Modified: logging/log4j/log4j2/trunk/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java (original)
+++ logging/log4j/log4j2/trunk/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java Mon Nov 18 03:38:13 2013
@@ -16,13 +16,14 @@
*/
package org.apache.logging.log4j.flume.appender;
+import java.util.HashMap;
import java.util.Locale;
-import java.util.Properties;
+import java.util.Map;
import org.apache.flume.Event;
-import org.apache.flume.SourceRunner;
-import org.apache.flume.node.NodeConfiguration;
-import org.apache.flume.node.nodemanager.DefaultLogicalNodeManager;
+import org.apache.flume.EventDeliveryException;
+import org.apache.flume.agent.embedded.EmbeddedAgent;
+import org.apache.logging.log4j.LoggingException;
import org.apache.logging.log4j.core.appender.ManagerFactory;
import org.apache.logging.log4j.core.config.ConfigurationException;
import org.apache.logging.log4j.core.config.Property;
@@ -35,20 +36,13 @@ import org.apache.logging.log4j.util.Pro
*/
public class FlumeEmbeddedManager extends AbstractFlumeManager {
- /** Name for the Flume source */
- protected static final String SOURCE_NAME = "log4j-source";
-
private static final String FILE_SEP = PropertiesUtil.getProperties().getStringProperty("file.separator");
private static final String IN_MEMORY = "InMemory";
private static FlumeManagerFactory factory = new FlumeManagerFactory();
- private final FlumeNode node;
-
- private NodeConfiguration conf;
-
- private final Log4jEventSource source;
+ private EmbeddedAgent agent;
private final String shortName;
@@ -56,17 +50,13 @@ public class FlumeEmbeddedManager extend
/**
* Constructor
* @param name The unique name of this manager.
- * @param node The Flume Node.
+ * @param shortName The short version of the agent name.
+ * @param agent The embedded agent.
*/
- protected FlumeEmbeddedManager(final String name, final String shortName, final FlumeNode node) {
+ protected FlumeEmbeddedManager(final String name, final String shortName, final EmbeddedAgent agent) {
super(name);
- this.node = node;
+ this.agent = agent;
this.shortName = shortName;
- final SourceRunner runner = node.getConfiguration().getSourceRunners().get(SOURCE_NAME);
- if (runner == null || runner.getSource() == null) {
- throw new IllegalStateException("No Source has been created for Appender " + shortName);
- }
- source = (Log4jEventSource) runner.getSource();
}
/**
@@ -95,23 +85,23 @@ public class FlumeEmbeddedManager extend
boolean first = true;
if (agents != null && agents.length > 0) {
- sb.append("FlumeEmbedded[");
+ sb.append(name).append("[");
for (final Agent agent : agents) {
if (!first) {
- sb.append(",");
+ sb.append("_");
}
- sb.append(agent.getHost()).append(":").append(agent.getPort());
+ sb.append(agent.getHost()).append("-").append(agent.getPort());
first = false;
}
sb.append("]");
} else {
String sep = "";
- sb.append(name).append(":");
+ sb.append(name).append("-");
final StringBuilder props = new StringBuilder();
for (final Property prop : properties) {
props.append(sep);
props.append(prop.getName()).append("=").append(prop.getValue());
- sep = ",";
+ sep = "_";
}
sb.append(NameUtil.md5(props.toString()));
}
@@ -121,12 +111,16 @@ public class FlumeEmbeddedManager extend
@Override
public void send(final Event event) {
- source.send(event);
+ try {
+ agent.put(event);
+ } catch (EventDeliveryException ex) {
+ throw new LoggingException("Unable to deliver event to Flume Appender " + shortName, ex);
+ }
}
@Override
protected void releaseSub() {
- node.stop();
+ agent.stop();
}
/**
@@ -161,7 +155,6 @@ public class FlumeEmbeddedManager extend
* Avro Manager Factory.
*/
private static class FlumeManagerFactory implements ManagerFactory<FlumeEmbeddedManager, FactoryData> {
- private static final String SOURCE_TYPE = Log4jEventSource.class.getName();
/**
* Create the FlumeAvroManager.
@@ -172,26 +165,22 @@ public class FlumeEmbeddedManager extend
@Override
public FlumeEmbeddedManager createManager(final String name, final FactoryData data) {
try {
- final DefaultLogicalNodeManager nodeManager = new DefaultLogicalNodeManager();
- final Properties props = createProperties(data.name, data.agents, data.properties, data.batchSize,
- data.dataDir);
- final FlumeConfigurationBuilder builder = new FlumeConfigurationBuilder();
- final NodeConfiguration conf = builder.load(data.name, props, nodeManager);
-
- final FlumeNode node = new FlumeNode(nodeManager, nodeManager, conf);
-
- node.start();
-
- return new FlumeEmbeddedManager(name, data.name, node);
+ final Map<String, String> props = createProperties(data.name, data.agents, data.properties,
+ data.batchSize, data.dataDir);
+ EmbeddedAgent agent = new EmbeddedAgent(name);
+ agent.configure(props);
+ agent.start();
+ LOGGER.debug("Created Agent " + name);
+ return new FlumeEmbeddedManager(name, data.name, agent);
} catch (final Exception ex) {
LOGGER.error("Could not create FlumeEmbeddedManager", ex);
}
return null;
}
- private Properties createProperties(final String name, final Agent[] agents, final Property[] properties,
- final int batchSize, String dataDir) {
- final Properties props = new Properties();
+ private Map<String, String> createProperties(final String name, final Agent[] agents,
+ final Property[] properties, final int batchSize, String dataDir) {
+ final Map<String, String> props = new HashMap<String, String>();
if ((agents == null || agents.length == 0) && (properties == null || properties.length == 0)) {
LOGGER.error("No Flume configuration provided");
@@ -204,28 +193,23 @@ public class FlumeEmbeddedManager extend
}
if (agents != null && agents.length > 0) {
- props.put(name + ".sources", FlumeEmbeddedManager.SOURCE_NAME);
- props.put(name + ".sources." + FlumeEmbeddedManager.SOURCE_NAME + ".type", SOURCE_TYPE);
if (dataDir != null && dataDir.length() > 0) {
if (dataDir.equals(IN_MEMORY)) {
- props.put(name + ".channels", "primary");
- props.put(name + ".channels.primary.type", "memory");
+ props.put("channel.type", "memory");
} else {
- props.put(name + ".channels", "primary");
- props.put(name + ".channels.primary.type", "file");
+ props.put("channel.type", "file");
if (!dataDir.endsWith(FILE_SEP)) {
dataDir = dataDir + FILE_SEP;
}
- props.put(name + ".channels.primary.checkpointDir", dataDir + "checkpoint");
- props.put(name + ".channels.primary.dataDirs", dataDir + "data");
+ props.put("channel.checkpointDir", dataDir + "checkpoint");
+ props.put("channel.dataDirs", dataDir + "data");
}
} else {
- props.put(name + ".channels", "primary");
- props.put(name + ".channels.primary.type", "file");
+ props.put("channel.type", "file");
}
final StringBuilder sb = new StringBuilder();
@@ -234,29 +218,18 @@ public class FlumeEmbeddedManager extend
for (int i = 0; i < agents.length; ++i) {
sb.append(leading).append("agent").append(i);
leading = " ";
- final String prefix = name + ".sinks.agent" + i;
- props.put(prefix + ".channel", "primary");
+ final String prefix = "agent" + i;
props.put(prefix + ".type", "avro");
props.put(prefix + ".hostname", agents[i].getHost());
props.put(prefix + ".port", Integer.toString(agents[i].getPort()));
props.put(prefix + ".batch-size", Integer.toString(batchSize));
- props.put(name + ".sinkgroups.group1.processor.priority.agent" + i, Integer.toString(priority));
- --priority;
+ props.put("processor.priority." + prefix, Integer.toString(agents.length - i));
}
- props.put(name + ".sinks", sb.toString());
- props.put(name + ".sinkgroups", "group1");
- props.put(name + ".sinkgroups.group1.sinks", sb.toString());
- props.put(name + ".sinkgroups.group1.processor.type", "failover");
- final String sourceChannels = "primary";
- props.put(name + ".channels", sourceChannels);
- props.put(name + ".sources." + FlumeEmbeddedManager.SOURCE_NAME + ".channels", sourceChannels);
+ props.put("sinks", sb.toString());
+ props.put("processor.type", "failover");
} else {
- String channels = null;
String[] sinks = null;
- props.put(name + ".sources", FlumeEmbeddedManager.SOURCE_NAME);
- props.put(name + ".sources." + FlumeEmbeddedManager.SOURCE_NAME + ".type", SOURCE_TYPE);
-
for (final Property property : properties) {
final String key = property.getName();
@@ -275,13 +248,6 @@ public class FlumeEmbeddedManager extend
throw new ConfigurationException(msg);
}
- // Prohibit setting the sources as they are set above but allow interceptors to be set
- if (upperKey.startsWith("SOURCES.") && !upperKey.startsWith("SOURCES.LOG4J-SOURCE.INTERCEPTORS")) {
- final String msg = "Specification of Sources is not allowed in Flume Appender: " + key;
- LOGGER.error(msg);
- throw new ConfigurationException(msg);
- }
-
final String value = property.getValue();
if (Strings.isEmpty(value)) {
final String msg = "A value for property " + key + " must be provided";
@@ -289,24 +255,13 @@ public class FlumeEmbeddedManager extend
throw new ConfigurationException(msg);
}
- if (upperKey.equals("CHANNELS")) {
- channels = value.trim();
- } else if (upperKey.equals("SINKS")) {
+ if (upperKey.equals("SINKS")) {
sinks = value.trim().split(" ");
}
- props.put(name + '.' + key, value);
+ props.put(key, value);
}
- String sourceChannels = channels;
-
- if (channels == null) {
- sourceChannels = "primary";
- props.put(name + ".channels", sourceChannels);
- }
-
- props.put(name + ".sources." + FlumeEmbeddedManager.SOURCE_NAME + ".channels", sourceChannels);
-
if (sinks == null || sinks.length == 0) {
final String msg = "At least one Sink must be specified";
LOGGER.error(msg);
Modified: logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedAppenderTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedAppenderTest.java?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedAppenderTest.java (original)
+++ logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedAppenderTest.java Mon Nov 18 03:38:13 2013
@@ -193,8 +193,8 @@ public class FlumeEmbeddedAppenderTest {
" Received: " + body, body.endsWith(expected));
}
}
-
- @Test
+ /* Flume 1.4.0 does not support interceptors on the embedded agent
+ @Test */
public void testHeaderAddedByInterceptor() throws InterruptedException, IOException {
final StructuredDataMessage msg = new StructuredDataMessage("Test", "Test Log4j", "Test");
@@ -206,7 +206,7 @@ public class FlumeEmbeddedAppenderTest {
Assert.assertEquals("local", environmentHeader);
}
- @Test
+ /* @Test */
public void testPerformance() throws Exception {
final long start = System.currentTimeMillis();
final int count = 10000;
@@ -255,6 +255,7 @@ public class FlumeEmbeddedAppenderTest {
public EventCollector(final int port) {
final Responder responder = new SpecificResponder(AvroSourceProtocol.class, this);
+ System.out.println("Collector listening on port " + port);
nettyServer = new NettyServer(responder, new InetSocketAddress(HOSTNAME, port));
nettyServer.start();
}
Modified: logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/default_embedded.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/default_embedded.xml?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/default_embedded.xml (original)
+++ logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/default_embedded.xml Mon Nov 18 03:38:13 2013
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp" packages="">
+<Configuration status="debug" name="MyApp" packages="">
<Appenders>
<Flume name="eventLogger" ignoreExceptions="false" compress="true" type="embedded" dataDir="InMemory">
<Agent host="localhost" port="${sys:primaryPort}"/>
@@ -14,7 +14,7 @@
<Logger name="EventLogger" level="info" additivity="false">
<AppenderRef ref="eventLogger"/>
</Logger>
- <Root level="error">
+ <Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
Modified: logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/embedded.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/embedded.xml?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/embedded.xml (original)
+++ logging/log4j/log4j2/trunk/log4j-flume-ng/src/test/resources/embedded.xml Mon Nov 18 03:38:13 2013
@@ -1,29 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp" packages="">
+<Configuration status="debug" name="MyApp" packages="">
<Appenders>
<Flume name="eventLogger" ignoreExceptions="false" compress="true" type="embedded">
- <Property name="channels">primary</Property>
- <Property name="channels.primary.type">memory</Property>
+ <Property name="channel.type">memory</Property>
+ <!-- Flume 1.4.0 does not support interceptors on the embedded agent
<Property name="sources.log4j-source.interceptors">environment_interceptor</Property>
<Property name="sources.log4j-source.interceptors.environment_interceptor.type">static</Property>
<Property name="sources.log4j-source.interceptors.environment_interceptor.key">environment</Property>
- <Property name="sources.log4j-source.interceptors.environment_interceptor.value">local</Property>
+ <Property name="sources.log4j-source.interceptors.environment_interceptor.value">local</Property> -->
<Property name="sinks">agent1 agent2</Property>
- <Property name="sinks.agent1.channel">primary</Property>
- <Property name="sinks.agent1.type">avro</Property>
- <Property name="sinks.agent1.hostname">localhost</Property>
- <Property name="sinks.agent1.port">${sys:primaryPort}</Property>
- <Property name="sinks.agent1.batch-size">1</Property>
- <Property name="sinks.agent2.channel">primary</Property>
- <Property name="sinks.agent2.type">avro</Property>
- <Property name="sinks.agent2.hostname">localhost</Property>
- <Property name="sinks.agent2.port">${sys:alternatePort}</Property>
- <Property name="sinks.agent2.batch-size">1</Property>
- <Property name="sinkgroups">group1</Property>
- <Property name="sinkgroups.group1.sinks">agent1 agent2</Property>
- <Property name="sinkgroups.group1.processor.type">failover</Property>
- <Property name="sinkgroups.group1.processor.priority.agent1">10</Property>
- <Property name="sinkgroups.group1.processor.priority.agent2">5</Property>
+ <Property name="agent1.type">avro</Property>
+ <Property name="agent1.hostname">localhost</Property>
+ <Property name="agent1.port">${sys:primaryPort}</Property>
+ <Property name="agent1.batch-size">1</Property>
+ <Property name="agent2.type">avro</Property>
+ <Property name="agent2.hostname">localhost</Property>
+ <Property name="agent2.port">${sys:alternatePort}</Property>
+ <Property name="agent2.batch-size">1</Property>
+ <Property name="processor.type">failover</Property>
+ <Property name="processor.priority.agent1">10</Property>
+ <Property name="processor.priority.agent2">5</Property>
<RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
</Flume>
<Console name="STDOUT">
@@ -34,7 +30,7 @@
<Logger name="EventLogger" level="info" additivity="false">
<AppenderRef ref="eventLogger"/>
</Logger>
- <Root level="warn">
+ <Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
Modified: logging/log4j/log4j2/trunk/pom.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/pom.xml?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/pom.xml (original)
+++ logging/log4j/log4j2/trunk/pom.xml Mon Nov 18 03:38:13 2013
@@ -138,7 +138,7 @@
<Log4jReleaseCount>eleventh</Log4jReleaseCount>
<jackson1.version>1.9.13</jackson1.version>
<jackson2.version>2.2.2</jackson2.version>
- <flumeVersion>1.3.1</flumeVersion>
+ <flumeVersion>1.4.0</flumeVersion>
<disruptor.version>3.2.0</disruptor.version>
<!-- Configuration properties for the OSGi maven-bundle-plugin -->
<osgi.symbolicName>org.apache.logging.${project.artifactId}</osgi.symbolicName>
@@ -304,6 +304,29 @@
</dependency>
<dependency>
<groupId>org.apache.flume</groupId>
+ <artifactId>flume-ng-embedded-agent</artifactId>
+ <version>${flumeVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.flume</groupId>
<artifactId>flume-ng-node</artifactId>
<version>${flumeVersion}</version>
<exclusions>
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1542883&r1=1542882&r2=1542883&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Mon Nov 18 03:38:13 2013
@@ -21,16 +21,19 @@
</properties>
<body>
<release version="2.0RC1" date="2013-MM-DD" description="Bug fixes and enhancements">
+ <action issue="LOG4J2-453" dev="rgoers" type="update">
+ Update Flume Appender to use Flume 1.4.0.
+ </action>
<action issue="LOG4J2-423" dev="rpopma" type="add">
Added MBeans for instrumenting AsyncAppenders and AsyncLogger RingBuffers,
exposing queue size, remaining capacity and other attributes.
</action>
<action issue="LOG4J2-323" dev="rpopma" type="fix">
- Resolved memory leak by releasing reference to ThreadLocal when
+ Resolved memory leak by releasing reference to ThreadLocal when
AsyncLogger is stopped.
</action>
<action issue="LOG4J2-425" dev="rpopma" type="fix">
- Resolved memory leak by populating AsyncLoggerConfigHelper ring buffer
+ Resolved memory leak by populating AsyncLoggerConfigHelper ring buffer
via EventTranslatorTwoArg, eliminating the need for a ThreadLocal.
</action>
<action issue="LOG4J2-420" dev="ggregory" type="add">