You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2023/02/06 06:17:56 UTC

[ranger] branch ranger-2.4 updated: RANGER-4024: support to add requestId in Ranger admin server logs via MDC

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

madhan pushed a commit to branch ranger-2.4
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.4 by this push:
     new 09facecdd RANGER-4024: support to add requestId in Ranger admin server logs via MDC
09facecdd is described below

commit 09facecdda2a9b161970bad4d957122125c3bfb8
Author: Ramachandran Krishnan <ra...@gmail.com>
AuthorDate: Sun Feb 5 21:44:36 2023 -0800

    RANGER-4024: support to add requestId in Ranger admin server logs via MDC
    
    Signed-off-by: Madhan Neethiraj <ma...@apache.org>
    (cherry picked from commit fabffced8abf2ad10280c2f1a765505d363659cb)
---
 .../security/web/filter/RangerMDCFilter.java       | 109 +++++++++++++++++++++
 .../conf.dist/security-applicationContext.xml      |   3 +
 .../security/web/filter/TestRangerMDCFilter.java   |  61 ++++++++++++
 3 files changed, 173 insertions(+)

diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerMDCFilter.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerMDCFilter.java
new file mode 100644
index 000000000..46ecd9491
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerMDCFilter.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.security.web.filter;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.ranger.common.PropertiesUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+/**
+ * RangerMDCFilter filter that captures the HTTP request and insert request-id
+ * as part of MDC context which will be captured in the log file for every request
+ */
+
+public class RangerMDCFilter implements Filter {
+    private static final Logger log = LoggerFactory.getLogger(RangerMDCFilter.class);
+
+    public  static final String  DEFAULT_MDC_KEY                        = "REQUEST_ID";
+    public  static final String  DEFAULT_REQUEST_ID_HEADER_NAME         = "request-id";
+    private static final boolean DEFAULT_MDC_FILTER_ENABLED             = false;
+    private static final String  PROP_MDC_FILTER_MDC_KEY                = "ranger.admin.mdc-filter.mdcKey";
+    private static final String  PROP_MDC_FILTER_REQUEST_ID_HEADER_NAME = "ranger.admin.mdc-filter.requestHeader.name";
+    private static final String  PROP_MDC_FILTER_ENABLED                = "ranger.admin.mdc-filter.enabled";
+
+    private String  mdcKey            = DEFAULT_MDC_KEY;
+    private String  requestHeaderName = DEFAULT_REQUEST_ID_HEADER_NAME;
+    private boolean mdcFilterEnabled  = DEFAULT_MDC_FILTER_ENABLED;
+
+
+    @Override
+    public void init(FilterConfig config) throws ServletException {
+        if (log.isDebugEnabled()) {
+            log.debug("==> RangerMDCFilter.initialize()");
+        }
+
+        mdcFilterEnabled = PropertiesUtil.getBooleanProperty(PROP_MDC_FILTER_ENABLED, DEFAULT_MDC_FILTER_ENABLED);
+
+        if (mdcFilterEnabled) {
+            requestHeaderName = PropertiesUtil.getProperty(PROP_MDC_FILTER_REQUEST_ID_HEADER_NAME, DEFAULT_REQUEST_ID_HEADER_NAME);
+            mdcKey            = PropertiesUtil.getProperty(PROP_MDC_FILTER_MDC_KEY, DEFAULT_MDC_KEY);
+
+            log.info(PROP_MDC_FILTER_REQUEST_ID_HEADER_NAME + "=" + requestHeaderName);
+            log.info(PROP_MDC_FILTER_MDC_KEY + "=" + mdcKey);
+        }
+
+        log.info(PROP_MDC_FILTER_ENABLED + "=" + mdcFilterEnabled);
+
+        if (log.isDebugEnabled()) {
+            log.debug("<== RangerMDCFilter.initialize()");
+        }
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        if (log.isDebugEnabled()) {
+            log.debug("==> RangerMDCFilter.doFilter()");
+        }
+
+        if (mdcFilterEnabled) {
+            HttpServletRequest httpRequest = (HttpServletRequest)request;
+            String             requestId   = httpRequest.getHeader(requestHeaderName);
+
+            if (requestId != null) {
+                MDC.put(mdcKey, requestId);
+            }
+
+            try {
+                chain.doFilter(request, response);
+            } finally {
+                MDC.clear();
+            }
+        } else {
+            chain.doFilter(request, response);
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("<== RangerMDCFilter.doFilter()");
+        }
+    }
+
+    @Override
+    public void destroy() {
+    }
+}
diff --git a/security-admin/src/main/resources/conf.dist/security-applicationContext.xml b/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
index 4ee80b98f..682760673 100644
--- a/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
+++ b/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
@@ -106,6 +106,9 @@ http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">
 	<beans:bean id="CSRFPreventionFilter" class="org.apache.ranger.security.web.filter.RangerCSRFPreventionFilter">
     </beans:bean>
 
+	<beans:bean id="mdcFilter" class="org.apache.ranger.security.web.filter.RangerMDCFilter">
+    </beans:bean>
+
     <beans:bean id="ssoAuthenticationFilter" class="org.apache.ranger.security.web.filter.RangerSSOAuthenticationFilter">
     </beans:bean>
 	
diff --git a/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerMDCFilter.java b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerMDCFilter.java
new file mode 100644
index 000000000..d89a1fd59
--- /dev/null
+++ b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerMDCFilter.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.security.web.filter;
+
+import java.io.IOException;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class TestRangerMDCFilter {
+
+    @Test
+    public void testRequestContainRequestIdHeader() throws ServletException, IOException {
+        HttpServletRequest  mockReq   = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse mockRes   = Mockito.mock(HttpServletResponse.class);
+        FilterChain         mockChain = Mockito.mock(FilterChain.class);
+        RangerMDCFilter     filter    = new RangerMDCFilter();
+
+        Mockito.when(mockReq.getHeader(RangerMDCFilter.DEFAULT_REQUEST_ID_HEADER_NAME)).thenReturn("test");
+        Mockito.when(mockReq.getMethod()).thenReturn("GET");
+
+        filter.doFilter(mockReq, mockRes, mockChain);
+
+        Mockito.verify(mockChain).doFilter(mockReq, mockRes);
+    }
+
+    @Test
+    public void testRequestNotContainRequestIdHeader() throws ServletException, IOException {
+        HttpServletRequest  mockReq   = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse mockRes   = Mockito.mock(HttpServletResponse.class);
+        FilterChain         mockChain = Mockito.mock(FilterChain.class);
+        RangerMDCFilter     filter    = new RangerMDCFilter();
+
+        Mockito.when(mockReq.getHeader(RangerMDCFilter.DEFAULT_REQUEST_ID_HEADER_NAME)).thenReturn(null);
+        Mockito.when(mockReq.getMethod()).thenReturn("GET");
+
+        filter.doFilter(mockReq, mockRes, mockChain);
+
+        Mockito.verify(mockChain).doFilter(mockReq, mockRes);
+    }
+}