Return-Path: X-Original-To: apmail-sling-commits-archive@www.apache.org Delivered-To: apmail-sling-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0FD9ECCA8 for ; Mon, 9 Sep 2013 12:28:32 +0000 (UTC) Received: (qmail 34046 invoked by uid 500); 9 Sep 2013 12:28:31 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 33985 invoked by uid 500); 9 Sep 2013 12:28:30 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 33975 invoked by uid 99); 9 Sep 2013 12:28:30 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Sep 2013 12:28:30 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Sep 2013 12:28:24 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 41B7323889ED; Mon, 9 Sep 2013 12:28:03 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1521071 - in /sling/trunk/contrib/extensions/slf4j-mdc: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/extensions/ src/main/java/org/apache/sling... Date: Mon, 09 Sep 2013 12:28:03 -0000 To: commits@sling.apache.org From: bdelacretaz@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130909122803.41B7323889ED@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: bdelacretaz Date: Mon Sep 9 12:28:01 2013 New Revision: 1521071 URL: http://svn.apache.org/r1521071 Log: SLING-3048 - Filter that populates an slf4j MDC with request info - contributed by Chetan Mehrotra, thanks! Added: sling/trunk/contrib/extensions/slf4j-mdc/ (with props) sling/trunk/contrib/extensions/slf4j-mdc/README.md sling/trunk/contrib/extensions/slf4j-mdc/pom.xml sling/trunk/contrib/extensions/slf4j-mdc/src/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/MDCInsertingFilter.java sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/SlingMDCFilter.java sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/OSGI-INF/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/OSGI-INF/metatype/ sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/OSGI-INF/metatype/metatype.properties Propchange: sling/trunk/contrib/extensions/slf4j-mdc/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Sep 9 12:28:01 2013 @@ -0,0 +1,14 @@ +target +bin +derby.log +*.iml +*.ipr +*.iws +.settings +.project +.classpath +.externalToolBuilders +maven-eclipse.xml + + + Added: sling/trunk/contrib/extensions/slf4j-mdc/README.md URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/slf4j-mdc/README.md?rev=1521071&view=auto ============================================================================== --- sling/trunk/contrib/extensions/slf4j-mdc/README.md (added) +++ sling/trunk/contrib/extensions/slf4j-mdc/README.md Mon Sep 9 12:28:01 2013 @@ -0,0 +1,21 @@ +Apache Sling MDC Inserting Filter +================================ + +This filter exposes various request details as part of [MDC][1]. + +Currently it exposes following variables: + +1. `req.remoteHost` - Request remote host +2. `req.userAgent` - User Agent Header +3. `req.requestURI` - Request URI +4. `req.queryString` - Query String from request +5. `req.requestURL` - +6. `req.xForwardedFor` - +7. `sling.userId` - UserID associated with the request. Obtained from ResourceResolver +8. `jcr.sessionId` - Session ID of the JCR Session associated with current request. + +The filter also allow configuration to extract data from request cookie, header and parameters. Look for +configuration with name 'Apache Sling Logging MDC Inserting Filter' for details on specifying header, cookie, +param names. + +[1] http://www.slf4j.org/manual.html#mdc \ No newline at end of file Added: sling/trunk/contrib/extensions/slf4j-mdc/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/slf4j-mdc/pom.xml?rev=1521071&view=auto ============================================================================== --- sling/trunk/contrib/extensions/slf4j-mdc/pom.xml (added) +++ sling/trunk/contrib/extensions/slf4j-mdc/pom.xml Mon Sep 9 12:28:01 2013 @@ -0,0 +1,105 @@ + + + + + 4.0.0 + + org.apache.sling + sling + 18 + ../../../parent/pom.xml + + + org.apache.sling.extensions.slf4j.mdc + 0.0.1-SNAPSHOT + bundle + + Apache Sling SLF4J MDC Filter + + SLF4J Message Diagnostic Context (MDC) Filter which extracts various details + from requests and adds them to the MDC + + + + + + org.apache.felix + maven-bundle-plugin + true + + + + org.apache.sling.commons.osgi;inline=org/apache/sling/commons/osgi/PropertiesUtil.class + + + + + + org.apache.felix + maven-scr-plugin + + + + + + + org.slf4j + slf4j-api + provided + + + org.osgi + org.osgi.core + 4.2.0 + + + org.osgi + org.osgi.compendium + 4.2.0 + + + org.apache.sling + org.apache.sling.commons.osgi + 2.2.0 + + + org.apache.sling + org.apache.sling.api + 2.1.0 + true + + + javax.servlet + servlet-api + 2.3 + + + javax.jcr + jcr + 2.0 + true + + + org.apache.felix + org.apache.felix.scr.annotations + + + Added: sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/MDCInsertingFilter.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/MDCInsertingFilter.java?rev=1521071&view=auto ============================================================================== --- sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/MDCInsertingFilter.java (added) +++ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/MDCInsertingFilter.java Mon Sep 9 12:28:01 2013 @@ -0,0 +1,224 @@ +/* + * 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.sling.extensions.mdc.internal; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceFactory; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.MDC; + +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.Cookie; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +@Service +@Component(metatype = true, + label="%mdc.label", + description = "%mdc.description") +@Property(name = "pattern",value = "/.*", propertyPrivate = true) +/** + * Filter is based on ch.qos.logback.classic.helpers.MDCInsertingServletFilter + */ +public class MDCInsertingFilter implements Filter { + public static final String REQUEST_REMOTE_HOST_MDC_KEY = "req.remoteHost"; + public static final String REQUEST_USER_AGENT_MDC_KEY = "req.userAgent"; + public static final String REQUEST_REQUEST_URI = "req.requestURI"; + public static final String REQUEST_QUERY_STRING = "req.queryString"; + public static final String REQUEST_REQUEST_URL = "req.requestURL"; + public static final String REQUEST_X_FORWARDED_FOR = "req.xForwardedFor"; + + private static final String[] DEFAULT_KEY_NAMES = { + REQUEST_REMOTE_HOST_MDC_KEY, + REQUEST_USER_AGENT_MDC_KEY, + REQUEST_REQUEST_URI, + REQUEST_QUERY_STRING, + REQUEST_REQUEST_URL, + REQUEST_X_FORWARDED_FOR + }; + + private static final String[] EMPTY_VALUE = new String[0]; + + @Property + private static final String PROP_HEADERS = "headers"; + + @Property + private static final String PROP_PARAMS = "parameters"; + + @Property + private static final String PROP_COOKIES = "cookies"; + + + private Set keyNames = new CopyOnWriteArraySet(); + + private Set headerNames = new CopyOnWriteArraySet(); + + private Set parameterNames = new CopyOnWriteArraySet(); + + private Set cookieNames = new CopyOnWriteArraySet(); + + private ServiceRegistration filterReg; + + + public void init(FilterConfig filterConfig) throws ServletException { + + } + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + insertIntoMDC(request); + try { + chain.doFilter(request, response); + } finally { + clearMDC(); + } + } + + public void destroy() { + + } + + private void insertIntoMDC(ServletRequest request) { + MDC.put(REQUEST_REMOTE_HOST_MDC_KEY, request.getRemoteHost()); + + if (request instanceof HttpServletRequest) { + HttpServletRequest httpRequest = (HttpServletRequest) request; + MDC.put(REQUEST_REQUEST_URI, httpRequest.getRequestURI()); + + StringBuffer requestURL = httpRequest.getRequestURL(); + if (requestURL != null) { + MDC.put(REQUEST_REQUEST_URL, requestURL.toString()); + } + + MDC.put(REQUEST_QUERY_STRING, httpRequest.getQueryString()); + MDC.put(REQUEST_USER_AGENT_MDC_KEY, httpRequest.getHeader("User-Agent")); + MDC.put(REQUEST_X_FORWARDED_FOR, httpRequest.getHeader("X-Forwarded-For")); + + for(String paramName : parameterNames){ + MDC.put(paramName,httpRequest.getParameter(paramName)); + } + + for(String headerName :headerNames){ + MDC.put(headerName, httpRequest.getHeader(headerName)); + } + + Cookie[] cookies = httpRequest.getCookies(); + if(cookies != null){ + for(Cookie c : cookies){ + if(cookieNames.contains(c.getName())){ + MDC.put(c.getName(),c.getValue()); + } + } + } + } + } + + private void clearMDC() { + for (String key : keyNames) { + MDC.remove(key); + } + } + + @Activate + private void activate(BundleContext context,Map config) { + Properties p = new Properties(); + p.setProperty("filter.scope","REQUEST"); + //The MDC Filter might be running in a non Sling container. Hence to avoid + //direct dependency on Sling we use a ServiceFactory + filterReg = context.registerService(Filter.class.getName(),new ServiceFactory() { + private Object instance; + + public synchronized Object getService(Bundle bundle, ServiceRegistration serviceRegistration) { + if(instance == null){ + instance = new SlingMDCFilter(); + } + return instance; + } + + public void ungetService(Bundle bundle, ServiceRegistration serviceRegistration, Object o) { + + } + },p); + + modified(config); + } + + @Modified + private void modified(Map config){ + Set headers = toTrimmedValues(config, PROP_HEADERS); + headerNames.clear(); + headerNames.addAll(headers); + + Set cookies = toTrimmedValues(config,PROP_COOKIES); + cookieNames.clear(); + cookieNames.addAll(cookies); + + Set params = toTrimmedValues(config,PROP_PARAMS); + parameterNames.clear(); + parameterNames.addAll(params); + + List keyNames = new ArrayList(); + keyNames.addAll(headerNames); + keyNames.addAll(cookieNames); + keyNames.addAll(parameterNames); + keyNames.addAll(Arrays.asList(DEFAULT_KEY_NAMES)); + + this.keyNames.clear(); + this.keyNames.addAll(keyNames); + } + + @Deactivate + private void deactivate(){ + if(filterReg != null){ + filterReg.unregister(); + } + } + + private static Set toTrimmedValues(Map config,String propName){ + String[] values = PropertiesUtil.toStringArray(config.get(propName),EMPTY_VALUE); + Set result = new HashSet(values.length); + for(String value : values){ + if(value != null && value.trim().length() > 0){ + result.add(value.trim()); + } + } + return result; + } +} Added: sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/SlingMDCFilter.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/SlingMDCFilter.java?rev=1521071&view=auto ============================================================================== --- sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/SlingMDCFilter.java (added) +++ sling/trunk/contrib/extensions/slf4j-mdc/src/main/java/org/apache/sling/extensions/mdc/internal/SlingMDCFilter.java Mon Sep 9 12:28:01 2013 @@ -0,0 +1,80 @@ +/* + * 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.sling.extensions.mdc.internal; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.ResourceResolver; +import org.slf4j.MDC; + +import javax.jcr.Session; +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 java.io.IOException; + +class SlingMDCFilter implements Filter { + public static final String SLING_USER = "sling.userId"; + public static final String JCR_SESSION_ID = "jcr.sessionId"; + + private static final String[] DEFAULT_KEY_NAMES = { + SLING_USER, + JCR_SESSION_ID + }; + + public void init(FilterConfig filterConfig) throws ServletException { + + } + + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, + FilterChain filterChain) throws IOException, ServletException { + final SlingHttpServletRequest request = (SlingHttpServletRequest) servletRequest; + + try { + insertIntoMDC(request); + filterChain.doFilter(request, servletResponse); + } finally { + clearMDC(); + } + } + + private void clearMDC() { + for (String key : DEFAULT_KEY_NAMES) { + MDC.remove(key); + } + } + + private void insertIntoMDC(SlingHttpServletRequest request) { + ResourceResolver rr = request.getResourceResolver(); + if(rr.getUserID() != null){ + MDC.put(SLING_USER,rr.getUserID()); + } + + Session session = rr.adaptTo(Session.class); + if(session != null){ + MDC.put(JCR_SESSION_ID,session.toString()); + } + } + + public void destroy() { + + } +} \ No newline at end of file Added: sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/OSGI-INF/metatype/metatype.properties URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=1521071&view=auto ============================================================================== --- sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/OSGI-INF/metatype/metatype.properties (added) +++ sling/trunk/contrib/extensions/slf4j-mdc/src/main/resources/OSGI-INF/metatype/metatype.properties Mon Sep 9 12:28:01 2013 @@ -0,0 +1,13 @@ +mdc.label=Apache Sling Logging MDC Inserting Filter +mdc.description= Servlet filter which extracts various request details and expose it \ + as part of MDC (http://www.slf4j.org/manual.html#mdc). These details can be accessed \ + as part of Logger configuration + +headers.name=Headers +headers.description=One or more HTTP Headers which need to be added to MDC + +parameters.name=Parameters +parameters.description=One or more names of Request Parameters which need to be added to MDC + +cookies.name=Cookies +cookies.description=One or more names of Cookies which need to be added to MDC