You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2022/02/11 16:21:25 UTC

[logging-log4j2] branch LOG4J2-3393 updated (f089b38 -> acd0d0f)

This is an automated email from the ASF dual-hosted git repository.

vy pushed a change to branch LOG4J2-3393
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git.


 discard f089b38  LOG4J2-3393 Create JTL benchmark main() for easy testing.
 discard ef92e25  LOG4J2-3393 Refactor JTL TemplateResolvers into smaller components.
     add 91b86fa  Bump maven-assembly-plugin from 3.1.0 to 3.3.0 (#743)
     add 05af570  Add CodeQL badge.
     add 52e3f00  Link to maven.org instead of mvnrepository.com.
     add 1abbebd  Remove unused imports.
     add c77ae68  Refactor magic strings into test constants.
     add ce63b3d  Rename test classes from MongoDB* to MongopDb3*.
     add ca161e7  Revert "LOG4J2-3394 - Allow substitution of system properties and environment variables in shorthand variables introduced in LOG4J2-3341"
     add ae2afdd  Merge branch 'release-2.x' of https://gitbox.apache.org/repos/asf/logging-log4j2 into release-2.x
     add e362e7b  Refactor magic strings into test constants.
     add 6db1c07  [LOG4J2-3391] Add optional additional fields to NoSQLAppender.
     add e064335  LOG4J2-2486 - Fix test
     add 7377a89  Fix NPEs in StructuredDataLookup and improve relevant tests. (#720)
     add 17a77f5  LOG4J2-3317: Fix RoutingAppender backcompat and improve lookup security
     add 77b6106  Sort members.
     add d532bed  Format tweaks.
     add 9a29030  [LOG4J2-3391] Add optional additional fields to NoSQLAppender.
     add 57cfe28  Possible NullPointerException in MongoDb4DocumentObject, MongoDbDocumentObject, DefaultNoSqlObject.
     add b9fbb36  Bump docker-maven-plugin from 0.33.0 to 0.39.0 (#748)
     new b3a979a  LOG4J2-3393 Refactor JTL TemplateResolvers into smaller components.
     new acd0d0f  LOG4J2-3393 Create JTL benchmark main() for easy testing.

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (f089b38)
            \
             N -- N -- N   refs/heads/LOG4J2-3393 (acd0d0f)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 README.md                                          |   3 +-
 log4j-core/revapi.json                             |  28 +++
 .../log4j/core/appender/AbstractManager.java       |  46 +++++
 .../core/appender/HttpURLConnectionManager.java    |   2 +-
 .../core/appender/db/AbstractDatabaseManager.java  |  50 ++++-
 .../core/appender/nosql/DefaultNoSqlObject.java    |  22 ++-
 .../log4j/core/appender/nosql/NoSqlAppender.java   |  19 +-
 .../core/appender/nosql/NoSqlDatabaseManager.java  | 218 ++++++++++++---------
 .../log4j/core/appender/nosql/NoSqlObject.java     |   1 +
 .../logging/log4j/core/async/AsyncLogger.java      |   4 +-
 .../logging/log4j/core/config/LoggerConfig.java    |   6 +-
 .../log4j/core/config/PropertiesPlugin.java        |  67 ++++++-
 .../apache/logging/log4j/core/config/Property.java |  43 +++-
 .../log4j/core/config/plugins/PluginValue.java     |   3 +
 .../plugins/visitors/PluginValueVisitor.java       |   4 +-
 .../properties/PropertiesConfigurationBuilder.java |   8 +-
 .../logging/log4j/core/lookup/AbstractLookup.java  |  12 +-
 .../core/lookup/ConfigurationStrSubstitutor.java   |  11 --
 .../log4j/core/lookup/DefaultLookupResult.java     |  31 +--
 .../logging/log4j/core/lookup/Interpolator.java    |  39 ++--
 .../{AbstractLookup.java => LookupResult.java}     |  23 ++-
 .../log4j/core/lookup/PropertiesLookup.java        | 126 ++++++++++--
 .../log4j/core/lookup/RuntimeStrSubstitutor.java   |  11 --
 .../logging/log4j/core/lookup/StrLookup.java       |  22 +++
 .../logging/log4j/core/lookup/StrSubstitutor.java  |  20 +-
 .../log4j/core/lookup/StructuredDataLookup.java    |  18 +-
 .../appender/nosql/NoSqlDatabaseManagerTest.java   |  17 +-
 .../rolling/action/ScriptConditionTest.java        |   5 +-
 ...r2767Test.java => RoutingAppender3350Test.java} |  50 +++--
 ...onSourceTest.java => PropertiesPluginTest.java} |  15 +-
 .../properties/PropertiesConfigurationTest.java    |  22 ---
 .../log4j/core/lookup/InterpolatorTest.java        |  17 --
 .../log4j/core/lookup/PropertiesLookupTest.java    |  70 ++++++-
 .../log4j/core/lookup/StrSubstitutorTest.java      | 166 ++++++++++++----
 .../core/lookup/StructuredDataLookupTest.java      |  40 +++-
 .../LoggerLevelAppenderTestWithSubst.properties    |  24 ---
 .../src/test/resources/log4j-routing-2767.xml      |   6 +-
 .../src/test/resources/log4j-routing-purge.xml     |   8 +-
 log4j-core/src/test/resources/log4j-routing.json   |   5 +-
 .../src/test/resources/log4j-routing.properties    |   4 +-
 log4j-core/src/test/resources/log4j-routing.xml    |   5 +-
 log4j-core/src/test/resources/log4j-routing2.json  |   5 +-
 ...og4j-routing-2767.xml => log4j-routing3350.xml} |  22 ++-
 .../log4j/mongodb3/MongoDbDocumentObject.java      |   7 +-
 ...Test.java => MongoDb3AdditionalFieldsTest.java} |  31 ++-
 ...ilureTest.java => MongoDb3AuthFailureTest.java} |  14 +-
 ...goDbCappedTest.java => MongoDb3CappedTest.java} |  14 +-
 ...essageTest.java => MongoDb3MapMessageTest.java} |  14 +-
 .../{MongoDbTest.java => MongoDb3Test.java}        |  12 +-
 ...stConstants.java => MongoDb3TestConstants.java} |   4 +-
 ...{MongoDbTestRule.java => MongoDb3TestRule.java} |   6 +-
 ...RuleTest.java => MongoDb3TestTestRuleTest.java} |  10 +-
 ...re.xml => log4j2-mongodb-additional-fields.xml} |   6 +-
 .../test/resources/log4j2-mongodb-auth-failure.xml |   2 +-
 .../src/test/resources/log4j2-mongodb-capped.xml   |   2 +-
 .../test/resources/log4j2-mongodb-map-message.xml  |   2 +-
 .../src/test/resources/log4j2-mongodb.xml          |   2 +-
 .../log4j/mongodb4/MongoDb4DocumentObject.java     |  10 +-
 .../logging/log4j/mongodb4/MongoDb4Provider.java   |   7 -
 ...Test.java => MongoDb4AdditionalFieldsTest.java} |  36 +++-
 .../log4j/mongodb4/MongoDb4AuthFailureTest.java    |   4 +-
 .../logging/log4j/mongodb4/MongoDb4CappedTest.java |   4 +-
 .../log4j/mongodb4/MongoDb4MapMessageTest.java     |   4 +-
 .../logging/log4j/mongodb4/MongoDb4Test.java       |   4 +-
 .../log4j/mongodb4/MongoDb4TestConstants.java      |   2 +
 ...ge.xml => log4j2-mongodb-additional-fields.xml} |   5 +-
 pom.xml                                            |   4 +-
 src/changes/changes.xml                            |  12 +-
 68 files changed, 1032 insertions(+), 504 deletions(-)
 copy log4j-perf/src/main/java/org/apache/logging/log4j/perf/util/NoOpLog4jAppender.java => log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/DefaultLookupResult.java (62%)
 copy log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/{AbstractLookup.java => LookupResult.java} (59%)
 copy log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/{RoutingAppender2767Test.java => RoutingAppender3350Test.java} (54%)
 copy log4j-core/src/test/java/org/apache/logging/log4j/core/config/{ConfigurationSourceTest.java => PropertiesPluginTest.java} (69%)
 delete mode 100644 log4j-core/src/test/resources/LoggerLevelAppenderTestWithSubst.properties
 copy log4j-core/src/test/resources/{log4j-routing-2767.xml => log4j-routing3350.xml} (66%)
 copy log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{MongoDbTest.java => MongoDb3AdditionalFieldsTest.java} (68%)
 rename log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{MongoDbAuthFailureTest.java => MongoDb3AuthFailureTest.java} (85%)
 rename log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{MongoDbCappedTest.java => MongoDb3CappedTest.java} (83%)
 rename log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{MongoDbMapMessageTest.java => MongoDb3MapMessageTest.java} (86%)
 rename log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{MongoDbTest.java => MongoDb3Test.java} (87%)
 rename log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{TestConstants.java => MongoDb3TestConstants.java} (86%)
 rename log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{MongoDbTestRule.java => MongoDb3TestRule.java} (97%)
 rename log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/{MongoDbTestTestRuleTest.java => MongoDb3TestTestRuleTest.java} (88%)
 copy log4j-mongodb3/src/test/resources/{log4j2-mongodb-auth-failure.xml => log4j2-mongodb-additional-fields.xml} (79%)
 copy log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/{MongoDb4Test.java => MongoDb4AdditionalFieldsTest.java} (69%)
 copy log4j-mongodb4/src/test/resources/{log4j2-mongodb-map-message.xml => log4j2-mongodb-additional-fields.xml} (85%)

[logging-log4j2] 02/02: LOG4J2-3393 Create JTL benchmark main() for easy testing.

Posted by vy...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vy pushed a commit to branch LOG4J2-3393
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit acd0d0fd86553d6f6ade307ef7c8d9a7625d4e52
Author: Volkan Yazici <vo...@yazi.ci>
AuthorDate: Mon Feb 7 10:54:30 2022 +0100

    LOG4J2-3393 Create JTL benchmark main() for easy testing.
---
 .../template/json/JsonTemplateLayoutBenchmark.java | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmark.java b/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmark.java
index 1099625..dce0690 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmark.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmark.java
@@ -21,6 +21,7 @@ import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.layout.ByteBufferDestination;
 import org.openjdk.jmh.annotations.Benchmark;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.List;
 
@@ -182,4 +183,29 @@ public class JsonTemplateLayoutBenchmark {
         return position;
     }
 
+    public static void main(String[] args) throws IOException {
+        System.out.format("Ready?");
+        System.in.read();
+        JsonTemplateLayoutBenchmarkState state = new JsonTemplateLayoutBenchmarkState();
+        int retryCount = 10_000;
+        measureEcs(state, retryCount);
+        measureJtl(state, retryCount);
+    }
+
+    private static void measureJtl(JsonTemplateLayoutBenchmarkState state, int retryCount) {
+        long startInstantNanos = System.nanoTime();
+        for (int i = 0; i < retryCount; i++) {
+            liteJsonTemplateLayout4EcsLayout(state);
+        }
+        System.out.format("%.3fs%n", (System.nanoTime() - startInstantNanos) / 1e9);
+    }
+
+    private static void measureEcs(JsonTemplateLayoutBenchmarkState state, int retryCount) {
+        long startInstantNanos = System.nanoTime();
+        for (int i = 0; i < retryCount; i++) {
+            liteEcsLayout(state);
+        }
+        System.out.format("%.3fs%n", (System.nanoTime() - startInstantNanos) / 1e9);
+    }
+
 }

[logging-log4j2] 01/02: LOG4J2-3393 Refactor JTL TemplateResolvers into smaller components.

Posted by vy...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vy pushed a commit to branch LOG4J2-3393
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit b3a979a996b1c7893976d941fe94279ef3d8770f
Author: Volkan Yazici <vo...@yazi.ci>
AuthorDate: Mon Feb 7 10:53:48 2022 +0100

    LOG4J2-3393 Refactor JTL TemplateResolvers into smaller components.
---
 .../template/json/resolver/TemplateResolvers.java  | 224 +++++++++++++++------
 1 file changed, 160 insertions(+), 64 deletions(-)

diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java
index 20ad802..450b874 100644
--- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java
+++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolvers.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * Main class for compiling {@link TemplateResolver}s from a template.
@@ -192,6 +193,28 @@ public final class TemplateResolvers {
             return ofResolver(context, map);
         }
 
+        // Collect field resolver contexts.
+        List<FieldResolverContext<V>> fieldResolverContexts =
+                populateFieldResolverMethods(context, map);
+
+        // Short-circuit if the object is empty.
+        final int fieldCount = fieldResolverContexts.size();
+        if (fieldCount == 0) {
+            @SuppressWarnings("unchecked")
+            final TemplateResolver<V> emptyObjectResolver =
+                    (TemplateResolver<V>) EMPTY_OBJECT_RESOLVER;
+            return emptyObjectResolver;
+        }
+
+        // Create the resolver.
+        return new MapResolver<>(fieldResolverContexts);
+
+    }
+
+    private static <V, C extends TemplateResolverContext<V, C>> List<FieldResolverContext<V>> populateFieldResolverMethods(
+            final C context,
+            final Map<String, Object> map) {
+
         // Create resolver for each object field.
         final List<String> fieldNames = new ArrayList<>();
         final List<TemplateResolver<V>> fieldResolvers = new ArrayList<>();
@@ -204,15 +227,6 @@ public final class TemplateResolvers {
             }
         });
 
-        // Short-circuit if the object is empty.
-        final int fieldCount = fieldNames.size();
-        if (fieldCount == 0) {
-            @SuppressWarnings("unchecked")
-            final TemplateResolver<V> emptyObjectResolver =
-                    (TemplateResolver<V>) EMPTY_OBJECT_RESOLVER;
-            return emptyObjectResolver;
-        }
-
         // Prepare field names to avoid escape and truncation costs at runtime.
         final List<String> fieldPrefixes = fieldNames
                 .stream()
@@ -225,70 +239,152 @@ public final class TemplateResolvers {
                 })
                 .collect(Collectors.toList());
 
-        return new TemplateResolver<V>() {
-
-            @Override
-            public boolean isResolvable() {
-                // We have already excluded unresolvable ones while collecting
-                // the resolvers. Hence it is safe to return true here.
-                return true;
-            }
-
-            /**
-             * The parent resolver checking if each child is resolvable given
-             * the passed {@code value}.
-             *
-             * This is an optimization to skip the rendering of a parent if all
-             * its children are not resolvable given the passed {@code value}.
-             */
-            @Override
-            public boolean isResolvable(final V value) {
-                for (int fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
-                    final TemplateResolver<V> fieldResolver = fieldResolvers.get(fieldIndex);
-                    final boolean resolvable = fieldResolver.isResolvable(value);
-                    if (resolvable) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-
-            /**
-             * The parent resolver combining all child resolver executions.
-              */
-            @Override
-            public void resolve(final V value, final JsonWriter jsonWriter) {
-                final StringBuilder jsonWriterStringBuilder = jsonWriter.getStringBuilder();
-                jsonWriter.writeObjectStart();
-                for (int resolvedFieldCount = 0, fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
+        // Collect field resolver contexts.
+        final int fieldCount = fieldNames.size();
+        return IntStream
+                .range(0, fieldCount)
+                .mapToObj(fieldIndex -> {
                     final TemplateResolver<V> fieldResolver = fieldResolvers.get(fieldIndex);
-                    final boolean resolvable = fieldResolver.isResolvable(value);
-                    if (!resolvable) {
-                        continue;
-                    }
-                    final boolean succeedingEntry = resolvedFieldCount > 0;
+                    final FieldResolverMethod<V> fieldResolverMethod;
                     final boolean flattening = fieldResolver.isFlattening();
                     if (flattening) {
-                        final int initLength = jsonWriterStringBuilder.length();
-                        fieldResolver.resolve(value, jsonWriter, succeedingEntry);
-                        final boolean resolved = jsonWriterStringBuilder.length() > initLength;
-                        if (resolved) {
-                            resolvedFieldCount++;
-                        }
+                        fieldResolverMethod = new FlatteningFieldResolverMethod<>(fieldResolver);
                     } else {
-                        if (succeedingEntry) {
-                            jsonWriter.writeSeparator();
-                        }
                         final String fieldPrefix = fieldPrefixes.get(fieldIndex);
-                        jsonWriter.writeRawString(fieldPrefix);
-                        fieldResolver.resolve(value, jsonWriter, succeedingEntry);
-                        resolvedFieldCount++;
+                        fieldResolverMethod = new PrefixedFieldResolverMethod<>(fieldPrefix, fieldResolver);
                     }
+                    return new FieldResolverContext<>(fieldResolver, fieldResolverMethod);
+                })
+                .collect(Collectors.toList());
+
+    }
+
+    private static final class FieldResolverContext<V> {
+
+        private final TemplateResolver<V> resolver;
+
+        private final FieldResolverMethod<V> resolverMethod;
+
+        private FieldResolverContext(final TemplateResolver<V> resolver, final FieldResolverMethod<V> resolverMethod) {
+            this.resolver = resolver;
+            this.resolverMethod = resolverMethod;
+        }
+
+    }
+
+    @FunctionalInterface
+    private interface FieldResolverMethod<V> {
+
+        boolean resolve(V value, JsonWriter jsonWriter, boolean succeedingEntry);
+
+    }
+
+    private static final class FlatteningFieldResolverMethod<V> implements FieldResolverMethod<V> {
+
+        private final TemplateResolver<V> fieldResolver;
+
+        private FlatteningFieldResolverMethod(final TemplateResolver<V> fieldResolver) {
+            this.fieldResolver = fieldResolver;
+        }
+
+        @Override
+        public boolean resolve(final V value, final JsonWriter jsonWriter, final boolean succeedingEntry) {
+            final boolean resolvable = fieldResolver.isResolvable(value);
+            if (!resolvable) {
+                return false;
+            }
+            final StringBuilder jsonWriterStringBuilder = jsonWriter.getStringBuilder();
+            final int initLength = jsonWriterStringBuilder.length();
+            fieldResolver.resolve(value, jsonWriter, succeedingEntry);
+            return jsonWriterStringBuilder.length() > initLength;
+        }
+
+    }
+
+    private static final class PrefixedFieldResolverMethod<V> implements FieldResolverMethod<V> {
+
+        private final String fieldPrefix;
+
+        private final TemplateResolver<V> fieldResolver;
+
+        private PrefixedFieldResolverMethod(final String fieldPrefix, final TemplateResolver<V> fieldResolver) {
+            this.fieldPrefix = fieldPrefix;
+            this.fieldResolver = fieldResolver;
+        }
+
+        @Override
+        public boolean resolve(final V value, final JsonWriter jsonWriter, final boolean succeedingEntry) {
+            final boolean resolvable = fieldResolver.isResolvable(value);
+            if (!resolvable) {
+                return false;
+            }
+            if (succeedingEntry) {
+                jsonWriter.writeSeparator();
+            }
+            jsonWriter.writeRawString(fieldPrefix);
+            fieldResolver.resolve(value, jsonWriter, succeedingEntry);
+            return true;
+        }
+
+    }
+
+    private static final class MapResolver<V> implements TemplateResolver<V> {
+
+        private final List<FieldResolverContext<V>> fieldResolverContexts;
+
+        private MapResolver(final List<FieldResolverContext<V>> fieldResolverContexts) {
+            this.fieldResolverContexts = fieldResolverContexts;
+        }
+
+        @Override
+        public boolean isResolvable() {
+            // We have already excluded unresolvable ones while collecting
+            // the resolvers; it is safe to return true here.
+            return true;
+        }
+
+        /**
+         * The parent resolver checking if each child is resolvable given
+         * the passed {@code value}.
+         *
+         * This is an optimization to skip the rendering of a parent if all
+         * its children are not resolvable for the given {@code value}.
+         */
+        @Override
+        public boolean isResolvable(final V value) {
+            int fieldCount = fieldResolverContexts.size();
+            // noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
+            for (int fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
+                final TemplateResolver<V> fieldResolver = fieldResolverContexts.get(fieldIndex).resolver;
+                final boolean resolvable = fieldResolver.isResolvable(value);
+                if (resolvable) {
+                    return true;
                 }
-                jsonWriter.writeObjectEnd();
             }
+            return false;
+        }
 
-        };
+        /**
+         * The parent resolver combining all child resolver executions.
+         */
+        @Override
+        public void resolve(final V value, final JsonWriter jsonWriter) {
+            jsonWriter.writeObjectStart();
+            int fieldCount = fieldResolverContexts.size();
+            for (int resolvedFieldCount = 0, fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
+                FieldResolverContext<V> fieldResolverContext = fieldResolverContexts.get(fieldIndex);
+                final boolean resolvable = fieldResolverContext.resolver.isResolvable(value);
+                if (!resolvable) {
+                    continue;
+                }
+                final boolean succeedingEntry = resolvedFieldCount > 0;
+                final boolean resolved = fieldResolverContext.resolverMethod.resolve(value, jsonWriter, succeedingEntry);
+                if (resolved) {
+                    resolvedFieldCount++;
+                }
+            }
+            jsonWriter.writeObjectEnd();
+        }
 
     }