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.web.appender;
    18
    19  import java.io.Serializable;
    20  import javax.servlet.ServletContext;
    21
    22  import org.apache.logging.log4j.core.Filter;
    23  import org.apache.logging.log4j.core.Layout;
    24  import org.apache.logging.log4j.core.LogEvent;
    25  import org.apache.logging.log4j.core.appender.AbstractAppender;
    26  import org.apache.logging.log4j.core.config.plugins.Plugin;
    27  import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
    28  import org.apache.logging.log4j.core.config.plugins.PluginElement;
    29  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
    30  import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
    31  import org.apache.logging.log4j.core.layout.AbstractStringLayout;
    32  import org.apache.logging.log4j.core.layout.PatternLayout;
    33  import org.apache.logging.log4j.web.WebLoggerContextUtils;
    34
    35  /**
    36   * Logs using the ServletContext's log method
    37   */
    38  @Plugin(name = "Servlet", category = "Core", elementType = "appender", printObject = true)
    39  public class ServletAppender extends AbstractAppender {
    40
    41      private static final long serialVersionUID = 1L;
    42
    43      private final ServletContext servletContext;
    44
    45      private ServletAppender(final String name, final AbstractStringLayout layout, final Filter filter,
    46                              final ServletContext servletContext, final boolean ignoreExceptions) {
    47          super(name, filter, layout, ignoreExceptions);
    48          this.servletContext = servletContext;
    49      }
    50
    51      @Override
    52      public void append(final LogEvent event) {
    53          servletContext.log(((AbstractStringLayout) getLayout()).toSerializable(event));
    54      }
    55
    56      /**
    57       * Create a Servlet Appender.
    58       * @param layout The layout to use (required). Must extend {@link AbstractStringLayout}.
    59       * @param filter The Filter or null.
    60       * @param name The name of the Appender (required).
    61       * @param ignoreExceptions If {@code true} (default) exceptions encountered when appending events are logged;
    62       *                         otherwise they are propagated to the caller.
    63       * @return The ServletAppender.
    64       */
    65      @PluginFactory
    66      public static ServletAppender createAppender(
    67              @PluginElement("Layout") Layout<? extends Serializable> layout,
    68              @PluginElement("Filter") final Filter filter,
    69              @PluginAttribute("name")
    70              @Required(message = "No name provided for ServletAppender")
    71              final String name,
    72              @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final boolean ignoreExceptions) {
    73          final ServletContext servletContext = WebLoggerContextUtils.getServletContext();
    74          if (servletContext == null) {
    75              LOGGER.error("No servlet context is available");
    76              return null;
    77          }
    78          if (layout == null) {
    79              layout = PatternLayout.createDefaultLayout();
    80          } else if (!(layout instanceof AbstractStringLayout)) {
    81              LOGGER.error("Layout must be a StringLayout to log to ServletContext");
    82              return null;
    83          }
    84          return new ServletAppender(name, (AbstractStringLayout) layout, filter, servletContext, ignoreExceptions);
    85      }
    86
    87  }