This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit db408cb5f34535baab1a53d05dce00117dd6c170 Author: Volkan Yazıcı <[email protected]> AuthorDate: Wed Nov 29 14:17:15 2023 +0100 Use recycler in `StructuredDataFilter` (#1969) --- .../core/filter/StructuredDataFilterTest.java | 5 +- .../log4j/core/filter/StructuredDataFilter.java | 58 ++++++++++++---------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java index 406f656e89..fd44535715 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java @@ -22,6 +22,7 @@ import java.util.Collection; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.DefaultConfiguration; import org.apache.logging.log4j.core.test.junit.LoggerContextSource; import org.apache.logging.log4j.core.util.KeyValuePair; import org.apache.logging.log4j.message.StructuredDataMessage; @@ -35,7 +36,7 @@ public class StructuredDataFilterTest { final KeyValuePair[] pairs = new KeyValuePair[] { new KeyValuePair("id.name", "AccountTransfer"), new KeyValuePair("ToAccount", "123456") }; - StructuredDataFilter filter = StructuredDataFilter.createFilter(pairs, "and", null, null); + StructuredDataFilter filter = StructuredDataFilter.createFilter(new DefaultConfiguration(), pairs, "and", null, null); assertNotNull(filter); filter.start(); StructuredDataMessage msg = new StructuredDataMessage("AccountTransfer@18060", "Transfer Successful", "Audit"); @@ -46,7 +47,7 @@ public class StructuredDataFilterTest { assertSame(Filter.Result.NEUTRAL, filter.filter(null, Level.DEBUG, null, msg, null)); msg.put("ToAccount", "111111"); assertSame(Filter.Result.DENY, filter.filter(null, Level.ERROR, null, msg, null)); - filter = StructuredDataFilter.createFilter(pairs, "or", null, null); + filter = StructuredDataFilter.createFilter(new DefaultConfiguration(), pairs, "or", null, null); assertNotNull(filter); filter.start(); msg = new StructuredDataMessage("AccountTransfer@18060", "Transfer Successful", "Audit"); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/StructuredDataFilter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/StructuredDataFilter.java index 3245c158ae..408d0845d3 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/StructuredDataFilter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/StructuredDataFilter.java @@ -25,6 +25,8 @@ import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.Logger; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; import org.apache.logging.log4j.core.util.KeyValuePair; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.StructuredDataMessage; @@ -33,6 +35,8 @@ import org.apache.logging.log4j.plugins.Plugin; import org.apache.logging.log4j.plugins.PluginAttribute; import org.apache.logging.log4j.plugins.PluginElement; import org.apache.logging.log4j.plugins.PluginFactory; +import org.apache.logging.log4j.spi.Recycler; +import org.apache.logging.log4j.spi.RecyclerFactory; import org.apache.logging.log4j.util.IndexedReadOnlyStringMap; import org.apache.logging.log4j.util.PerformanceSensitive; import org.apache.logging.log4j.util.StringBuilders; @@ -46,11 +50,17 @@ import org.apache.logging.log4j.util.StringBuilders; public final class StructuredDataFilter extends MapFilter { private static final int MAX_BUFFER_SIZE = 2048; - private static final ThreadLocal<StringBuilder> threadLocalStringBuilder = new ThreadLocal<>(); + + private final Recycler<StringBuilder> stringBuilderRecycler; private StructuredDataFilter( - final Map<String, List<String>> map, final boolean oper, final Result onMatch, final Result onMismatch) { + final RecyclerFactory recyclerFactory, + final Map<String, List<String>> map, + final boolean oper, + final Result onMatch, + final Result onMismatch) { super(map, oper, onMatch, onMismatch); + this.stringBuilderRecycler = recyclerFactory.create(StringBuilder::new); } @Override @@ -74,22 +84,29 @@ public final class StructuredDataFilter extends MapFilter { protected Result filter(final StructuredDataMessage message) { boolean match = false; final IndexedReadOnlyStringMap map = getStringMap(); - for (int i = 0; i < map.size(); i++) { - final StringBuilder toMatch = getValue(message, map.getKeyAt(i)); - if (toMatch != null) { - match = listContainsValue((List<String>) map.getValueAt(i), toMatch); - } else { - match = false; - } - if ((!isAnd() && match) || (isAnd() && !match)) { - break; + final StringBuilder sb = stringBuilderRecycler.acquire(); + try { + for (int i = 0; i < map.size(); i++) { + final StringBuilder toMatch = getValue(sb, message, map.getKeyAt(i)); + if (toMatch != null) { + final List<String> candidates = map.getValueAt(i); + match = listContainsValue(candidates, toMatch); + } else { + match = false; + } + if ((!isAnd() && match) || (isAnd() && !match)) { + break; + } + StringBuilders.trimToMaxSize(sb, MAX_BUFFER_SIZE); + sb.setLength(0); } + } finally { + stringBuilderRecycler.release(sb); } return match ? onMatch : onMismatch; } - private StringBuilder getValue(final StructuredDataMessage data, final String key) { - final StringBuilder sb = getStringBuilder(); + private StringBuilder getValue(final StringBuilder sb, final StructuredDataMessage data, final String key) { if (key.equalsIgnoreCase("id")) { data.getId().formatTo(sb); return sb; @@ -105,17 +122,6 @@ public final class StructuredDataFilter extends MapFilter { } } - private StringBuilder getStringBuilder() { - StringBuilder result = threadLocalStringBuilder.get(); - if (result == null) { - result = new StringBuilder(); - threadLocalStringBuilder.set(result); - } - StringBuilders.trimToMaxSize(result, MAX_BUFFER_SIZE); - result.setLength(0); - return result; - } - private StringBuilder appendOrNull(final String value, final StringBuilder sb) { if (value == null) { return null; @@ -157,6 +163,7 @@ public final class StructuredDataFilter extends MapFilter { // TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder @PluginFactory public static StructuredDataFilter createFilter( + @PluginConfiguration final Configuration configuration, @PluginElement final KeyValuePair[] pairs, @PluginAttribute final String operator, @PluginAttribute final Result onMatch, @@ -191,6 +198,7 @@ public final class StructuredDataFilter extends MapFilter { return null; } final boolean isAnd = operator == null || !operator.equalsIgnoreCase("or"); - return new StructuredDataFilter(map, isAnd, onMatch, onMismatch); + final RecyclerFactory recyclerFactory = configuration.getRecyclerFactory(); + return new StructuredDataFilter(recyclerFactory, map, isAnd, onMatch, onMismatch); } }
