View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.web;
18  
19  import org.apache.logging.log4j.LogManager;
20  import org.apache.logging.log4j.core.impl.ContextAnchor;
21  import org.apache.logging.log4j.core.impl.Log4jContextFactory;
22  import org.apache.logging.log4j.core.selector.ContextSelector;
23  import org.apache.logging.log4j.core.LoggerContext;
24  import org.apache.logging.log4j.core.selector.NamedContextSelector;
25  import org.apache.logging.log4j.spi.LoggerContextFactory;
26  
27  import javax.servlet.Filter;
28  import javax.servlet.FilterChain;
29  import javax.servlet.FilterConfig;
30  import javax.servlet.ServletContext;
31  import javax.servlet.ServletException;
32  import javax.servlet.ServletRequest;
33  import javax.servlet.ServletResponse;
34  import javax.servlet.UnavailableException;
35  import java.io.IOException;
36  
37  /**
38   * ServletFilter than may be used to set up a LoggerContext for each web application.
39   */
40  public class JNDIContextFilter implements Filter {
41      /**
42       * The Filter init parameter that defines the name of the LoggerContext.
43       */
44      public static final String CONTEXT_NAME = "context-name";
45      /**
46       * The Filter init parameter that defines the configuration location for the LoggerContext.
47       */
48      public static final String CONFIG_LOCATION = "config-location";
49      private ServletContext context;
50      private boolean created = false;
51      private String name;
52      private NamedContextSelector selector = null;
53  
54      public void init(FilterConfig filterConfig) throws ServletException {
55          context = filterConfig.getServletContext();
56          name = filterConfig.getInitParameter(CONTEXT_NAME);
57          String configLocn = filterConfig.getInitParameter(CONFIG_LOCATION);
58          if (name == null) {
59              throw new UnavailableException("A context-name attribute is required");
60          }
61          if (context.getAttribute(Log4jContextListener.LOG4J_CONTEXT_ATTRIBUTE) == null) {
62              LoggerContext ctx;
63              LoggerContextFactory factory = LogManager.getFactory();
64              if (factory instanceof Log4jContextFactory) {
65                  ContextSelector sel = ((Log4jContextFactory) factory).getSelector();
66                  if (sel instanceof NamedContextSelector) {
67                      selector = (NamedContextSelector) sel;
68                      ctx = selector.locateContext(name, configLocn);
69                  } else {
70                      return;
71                  }
72              } else {
73                  return;
74              }
75              context.setAttribute(Log4jContextListener.LOG4J_CONTEXT_ATTRIBUTE, ctx);
76              created = true;
77              context.log("Created context for " + name + " using " + ctx.getClass().getClassLoader());
78          }
79      }
80  
81      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
82          throws IOException, ServletException {
83          LoggerContext ctx = (LoggerContext) context.getAttribute(Log4jContextListener.LOG4J_CONTEXT_ATTRIBUTE);
84          if (ctx != null) {
85              ContextAnchor.THREAD_CONTEXT.set(ctx);
86              try {
87                  filterChain.doFilter(servletRequest, servletResponse);
88              } finally {
89                  ContextAnchor.THREAD_CONTEXT.remove();
90              }
91          } else {
92              filterChain.doFilter(servletRequest, servletResponse);
93          }
94      }
95  
96      public void destroy() {
97          LoggerContext ctx = (LoggerContext) context.getAttribute(Log4jContextListener.LOG4J_CONTEXT_ATTRIBUTE);
98          if (ctx != null && created) {
99              context.log("Removing context for " + name);
100             context.removeAttribute(Log4jContextListener.LOG4J_CONTEXT_ATTRIBUTE);
101             if (selector != null) {
102                 selector.removeContext(name);
103             }
104             ctx.stop();
105         }
106     }
107 }