[ofbiz-framework] branch trunk updated: Improved: Allow logging to be disabled for getJs request (OFBIZ-11980)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[ofbiz-framework] branch trunk updated: Improved: Allow logging to be disabled for getJs request (OFBIZ-11980)

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

jamesyong pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 4a03567  Improved: Allow logging to be disabled for getJs request (OFBIZ-11980)
4a03567 is described below

commit 4a03567996c03b93acdf9511586c6c3e0b79fd8c
Author: James Yong <[hidden email]>
AuthorDate: Sun Aug 30 21:34:34 2020 +0800

    Improved: Allow logging to be disabled for getJs request (OFBIZ-11980)
   
    Hide non-error logs related to getJs request as it doesn't provide meaningful data.
   
    Thanks Jacques for initial review
---
 .../ofbiz/product/category/CatalogUrlFilter.java   |  15 +-
 framework/base/config/log4j2.xml                   |   6 +-
 .../base/log4j/OFBizDynamicThresholdFilter.java    | 243 +++++++++++++++++++++
 .../apache/ofbiz/webapp/control/ControlFilter.java |  10 +-
 4 files changed, 270 insertions(+), 4 deletions(-)

diff --git a/applications/product/src/main/java/org/apache/ofbiz/product/category/CatalogUrlFilter.java b/applications/product/src/main/java/org/apache/ofbiz/product/category/CatalogUrlFilter.java
index 6f9c6f9..13ef0af 100644
--- a/applications/product/src/main/java/org/apache/ofbiz/product/category/CatalogUrlFilter.java
+++ b/applications/product/src/main/java/org/apache/ofbiz/product/category/CatalogUrlFilter.java
@@ -33,6 +33,7 @@ import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.StringUtil;
 import org.apache.ofbiz.base.util.StringUtil.StringWrapper;
@@ -344,8 +345,18 @@ public class CatalogUrlFilter implements Filter {
             //Check path alias
             UrlServletHelper.checkPathAlias(request, httpResponse, delegator, pathInfo);
         }
-        // we're done checking; continue on
-        chain.doFilter(request, response);
+        try {
+            String uriWithContext = httpRequest.getRequestURI();
+            String context = httpRequest.getContextPath();
+            String uri = uriWithContext.substring(context.length());
+            // support OFBizDynamicThresholdFilter in log4j2.xml
+            ThreadContext.put("uri", uri);
+
+            // we're done checking; continue on
+            chain.doFilter(request, response);
+        } finally {
+            ThreadContext.remove("uri");
+        }
     }
 
     @Override
diff --git a/framework/base/config/log4j2.xml b/framework/base/config/log4j2.xml
index 9ee1e20..1b04cd1 100644
--- a/framework/base/config/log4j2.xml
+++ b/framework/base/config/log4j2.xml
@@ -17,7 +17,11 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
-<Configuration monitorInterval="60">
+<Configuration monitorInterval="60" packages="org.apache.ofbiz.base.log4j">
+    <OFBizDynamicThresholdFilter key="uri" onMatch="ACCEPT" onMismatch="DENY">
+        <KeyValuePair key="/getJs" value="ERROR"/>
+        <KeyValuePair key="/control/getJs" value="ERROR"/>
+    </OFBizDynamicThresholdFilter>
     <!--
       Default configuration for logging; for customizations refer to http://logging.apache.org/log4j/2.x/manual/configuration.html.
       With this configuration the following behavior is defined:
diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/log4j/OFBizDynamicThresholdFilter.java b/framework/base/src/main/java/org/apache/ofbiz/base/log4j/OFBizDynamicThresholdFilter.java
new file mode 100644
index 0000000..b1a65a0
--- /dev/null
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/log4j/OFBizDynamicThresholdFilter.java
@@ -0,0 +1,243 @@
+package org.apache.ofbiz.base.log4j;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.ContextDataInjector;
+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.Node;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.filter.AbstractFilter;
+import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
+import org.apache.logging.log4j.core.util.KeyValuePair;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.PerformanceSensitive;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+import org.apache.ofbiz.base.util.Debug;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Adapted from {@link org.apache.logging.log4j.core.filter.DynamicThresholdFilter}
+ * Check for active individual levels instead of default threshold
+ */
+@Plugin(name = "OFBizDynamicThresholdFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
+@PerformanceSensitive("allocation")
+public final class OFBizDynamicThresholdFilter extends AbstractFilter {
+
+    /**
+     * Creates a DynamicThresholdFilter.
+     * @param key The name of the key to compare.
+     * @param pairs An array of value and Level pairs.
+     * @param onMatch The action to perform if a match occurs.
+     * @param onMismatch The action to perform if no match occurs.
+     * @return The DynamicThresholdFilter.
+     */
+    // TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder
+    @PluginFactory
+    public static OFBizDynamicThresholdFilter createFilter(
+            @PluginAttribute("key") final String key,
+            @PluginElement("Pairs") final KeyValuePair[] pairs,
+            @PluginAttribute("onMatch") final Result onMatch,
+            @PluginAttribute("onMismatch") final Result onMismatch) {
+        final Map<String, Level> map = new HashMap<>();
+        for (final KeyValuePair pair : pairs) {
+            map.put(pair.getKey(), Level.toLevel(pair.getValue()));
+        }
+        return new OFBizDynamicThresholdFilter(key, map, onMatch, onMismatch);
+    }
+
+    private final String key;
+    private final ContextDataInjector injector = ContextDataInjectorFactory.createInjector();
+    private Map<String, Level> levelMap = new HashMap<>();
+
+    private OFBizDynamicThresholdFilter(final String key, final Map<String, Level> pairs,
+                                   final Result onMatch, final Result onMismatch) {
+        super(onMatch, onMismatch);
+        Objects.requireNonNull(key, "key cannot be null");
+        this.key = key;
+        this.levelMap = pairs;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equalsImpl(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final OFBizDynamicThresholdFilter other = (OFBizDynamicThresholdFilter) obj;
+        if (key == null) {
+            if (other.key != null) {
+                return false;
+            }
+        } else if (!key.equals(other.key)) {
+            return false;
+        }
+        if (levelMap == null) {
+            if (other.levelMap != null) {
+                return false;
+            }
+        } else if (!levelMap.equals(other.levelMap)) {
+            return false;
+        }
+        return true;
+    }
+
+    private Result filter(final Level level, final ReadOnlyStringMap contextMap) {
+        final String value = contextMap.getValue(key);
+        Level ctxLevel = null;
+        if (value != null && !"".equals(value)) {
+            ctxLevel = levelMap.get(value);
+        }
+        if (ctxLevel == null) {
+            return Result.NEUTRAL;
+        }
+        int intLevel = level.intLevel() / 100;
+        boolean isOn = Debug.isOn(intLevel) && level.isMoreSpecificThan(ctxLevel);
+        return isOn ? onMatch : onMismatch;
+    }
+
+    @Override
+    public Result filter(final LogEvent event) {
+        return filter(event.getLevel(), event.getContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
+                         final Throwable t) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
+                         final Throwable t) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object... params) {
+        return filter(level, currentContextData());
+    }
+
+    private ReadOnlyStringMap currentContextData() {
+        return injector.rawContextData();
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2, final Object p3) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2, final Object p3,
+                         final Object p4) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2, final Object p3,
+                         final Object p4, final Object p5) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2, final Object p3,
+                         final Object p4, final Object p5, final Object p6) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2, final Object p3,
+                         final Object p4, final Object p5, final Object p6,
+                         final Object p7) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2, final Object p3,
+                         final Object p4, final Object p5, final Object p6,
+                         final Object p7, final Object p8) {
+        return filter(level, currentContextData());
+    }
+
+    @Override
+    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
+                         final Object p0, final Object p1, final Object p2, final Object p3,
+                         final Object p4, final Object p5, final Object p6,
+                         final Object p7, final Object p8, final Object p9) {
+        return filter(level, currentContextData());
+    }
+
+    public String getKey() {
+        return this.key;
+    }
+
+    public Map<String, Level> getLevelMap() {
+        return levelMap;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCodeImpl();
+        result = prime * result + ((key == null) ? 0 : key.hashCode());
+        result = prime * result + ((levelMap == null) ? 0 : levelMap.hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("key=").append(key);
+        sb.append(", ");
+        if (levelMap.size() > 0) {
+            sb.append('{');
+            boolean first = true;
+            for (final Map.Entry<String, Level> entry : levelMap.entrySet()) {
+                if (!first) {
+                    sb.append(", ");
+                    first = false;
+                }
+                sb.append(entry.getKey()).append('=').append(entry.getValue());
+            }
+            sb.append('}');
+        }
+        return sb.toString();
+    }
+}
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
index 7de204d..a6d8e96 100644
--- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
@@ -34,6 +34,7 @@ import javax.servlet.http.HttpSession;
 
 import org.apache.commons.lang.BooleanUtils;
 import org.apache.commons.validator.routines.UrlValidator;
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.ofbiz.base.util.Debug;
 
 /**
@@ -148,7 +149,14 @@ public class ControlFilter extends HttpFilter {
 
             // Check if the requested URI is allowed.
             if (allowedPaths.stream().anyMatch(uri::startsWith)) {
-                chain.doFilter(req, resp);
+                try {
+                    // support OFBizDynamicThresholdFilter in log4j2.xml
+                    ThreadContext.put("uri", uri);
+
+                    chain.doFilter(req, resp);
+                } finally {
+                    ThreadContext.remove("uri");
+                }
             } else {
                 if (redirectPath == null) {
                     resp.sendError(errorCode, uriWithContext);