Yes, good one! I was wondering about that just a couple of weeks ago! Gary
---------- Forwarded message ---------- From: <rgo...@apache.org> Date: Tue, Jun 10, 2014 at 7:19 PM Subject: svn commit: r1601789 - in /logging/log4j/log4j2/trunk: log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ log4j-web/src/test/java/org/apache/logging/log4j/web/ log4j-web/src/test/resources/ src/changes/ To: comm...@logging.apache.org Author: rgoers Date: Tue Jun 10 23:19:32 2014 New Revision: 1601789 URL: http://svn.apache.org/r1601789 Log: LOG4J2-42 - Create an appender to route log events to the ServletContext log. Added: logging/log4j/log4j2/trunk/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ logging/log4j/log4j2/trunk/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java logging/log4j/log4j2/trunk/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java logging/log4j/log4j2/trunk/log4j-web/src/test/resources/ logging/log4j/log4j2/trunk/log4j-web/src/test/resources/log4j-servlet.xml Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml Added: logging/log4j/log4j2/trunk/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java?rev=1601789&view=auto ============================================================================== --- logging/log4j/log4j2/trunk/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java (added) +++ logging/log4j/log4j2/trunk/log4j-web/src/main/java/org/apache/logging/log4j/web/appender/ServletAppender.java Tue Jun 10 23:19:32 2014 @@ -0,0 +1,101 @@ +/* + * 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.logging.log4j.web.appender; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.Layout; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.AbstractAppender; +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.PluginConfiguration; +import org.apache.logging.log4j.core.config.plugins.PluginElement; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; +import org.apache.logging.log4j.core.impl.ContextAnchor; +import org.apache.logging.log4j.core.layout.AbstractStringLayout; +import org.apache.logging.log4j.core.layout.PatternLayout; +import org.apache.logging.log4j.core.util.Booleans; + +import javax.servlet.ServletContext; +import java.io.Serializable; + +/** + * Logs using the ServletContext's log method + */ +@Plugin(name = "Servlet", category = "Core", elementType = "appender", printObject = true) +public class ServletAppender extends AbstractAppender { + private final ServletContext servletContext; + + private ServletAppender(final String name, final AbstractStringLayout layout, final Filter filter, + ServletContext servletContext, boolean ignoreExceptions) { + super(name, filter, layout, ignoreExceptions); + this.servletContext = servletContext; + } + + @Override + public void append(LogEvent event) { + servletContext.log(((AbstractStringLayout) getLayout()).toSerializable(event)); + } + + /** + * Create a Console Appender. + * @param layout The layout to use (required). + * @param filter The Filter or null. + * @param name The name of the Appender (required). + * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise + * they are propagated to the caller. + * @return The ServletAppender. + */ + @PluginFactory + public static ServletAppender createAppender( + @PluginElement("Layout") Layout<? extends Serializable> layout, + @PluginElement("Filters") final Filter filter, + @PluginAttribute("name") final String name, + @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final String ignore) { + if (name == null) { + LOGGER.error("No name provided for ConsoleAppender"); + return null; + } + ServletContext servletContext = getServletContext(); + if (servletContext == null) { + LOGGER.error("No servlet context is available"); + return null; + } + if (layout == null) { + layout = PatternLayout.createDefaultLayout(); + } else if (!(layout instanceof AbstractStringLayout)) { + LOGGER.error("Layout must be a StringLayout to log to ServletContext"); + return null; + } + final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); + return new ServletAppender(name, (AbstractStringLayout) layout, filter, servletContext, ignoreExceptions); + } + + private static ServletContext getServletContext() { + LoggerContext lc = ContextAnchor.THREAD_CONTEXT.get(); + if (lc == null) { + lc = (LoggerContext) LogManager.getContext(false); + } + if (lc != null) { + Object obj = lc.getExternalContext(); + return obj != null && obj instanceof ServletContext ? (ServletContext) obj : null; + } + return null; + } +} Added: logging/log4j/log4j2/trunk/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java?rev=1601789&view=auto ============================================================================== --- logging/log4j/log4j2/trunk/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java (added) +++ logging/log4j/log4j2/trunk/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java Tue Jun 10 23:19:32 2014 @@ -0,0 +1,69 @@ +/* +* 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.logging.log4j.web; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.impl.ContextAnchor; +import org.junit.Test; +import org.springframework.mock.web.MockServletContext; + +import javax.servlet.ServletContext; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +/** + * + */ +public class ServletAppenderTest { + + private static final String CONFIG = "log4j-servlet.xml"; + + @Test + public void testAppender() throws Exception { + ContextAnchor.THREAD_CONTEXT.remove(); + ServletContext servletContext = new MockServletContext(); + servletContext.setAttribute("TestAttr", "AttrValue"); + servletContext.setInitParameter("TestParam", "ParamValue"); + servletContext.setAttribute("Name1", "Ben"); + servletContext.setInitParameter("Name2", "Jerry"); + servletContext.setInitParameter(Log4jWebSupport.LOG4J_CONFIG_LOCATION, CONFIG); + Log4jWebLifeCycle initializer = Log4jWebInitializerImpl.getLog4jWebInitializer(servletContext); + try { + initializer.start(); + initializer.setLoggerContext(); + LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get(); + assertNotNull("No LoggerContext", ctx); + assertNotNull("No ServletContext", ctx.getExternalContext()); + Configuration configuration = ctx.getConfiguration(); + assertNotNull("No configuration", configuration); + Appender appender = configuration.getAppender("Servlet"); + assertNotNull("No ServletAppender", appender); + Logger logger = LogManager.getLogger("Test"); + logger.info("This is a test"); + + } catch (final IllegalStateException e) { + fail("Failed to initialize Log4j properly." + e.getMessage()); + } + initializer.stop(); + ContextAnchor.THREAD_CONTEXT.remove(); + } +} Added: logging/log4j/log4j2/trunk/log4j-web/src/test/resources/log4j-servlet.xml URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-web/src/test/resources/log4j-servlet.xml?rev=1601789&view=auto ============================================================================== --- logging/log4j/log4j2/trunk/log4j-web/src/test/resources/log4j-servlet.xml (added) +++ logging/log4j/log4j2/trunk/log4j-web/src/test/resources/log4j-servlet.xml Tue Jun 10 23:19:32 2014 @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. + +--> +<Configuration status="debug" name="ServletTest"> + + <Appenders> + <Servlet name="Servlet"> + <PatternLayout pattern="%m%n"/> + </Servlet> + </Appenders> + + <Loggers> + <Root level="debug"> + <AppenderRef ref="Servlet"/> + </Root> + </Loggers> + +</Configuration> \ No newline at end of file Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1601789&r1=1601788&r2=1601789&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/src/changes/changes.xml (original) +++ logging/log4j/log4j2/trunk/src/changes/changes.xml Tue Jun 10 23:19:32 2014 @@ -22,8 +22,11 @@ </properties> <body> <release version="2.0-rc2" date="2014-MM-DD" description="Bug fixes and enhancements"> + <action issue="LOG4J2-42" dev="rgoers" type="add"> + Create an appender to route log events to the ServletContext log. + </action> <action issue="LOG4J2-419" dev="rgoers" type="update" due-to="Woonsan Ko"> - Support default value for missing key in look ups with fallbacking to looking in the properties map. + Support default value for missing key in look ups with fallbacking to looking in the properties map. </action> <action issue="LOG4J2-563" dev="rgoers" type="fix" due-to="Michael Friedmann"> FlumeAvroManager now always uses a client type of default_failover. -- E-Mail: garydgreg...@gmail.com | ggreg...@apache.org Java Persistence with Hibernate, Second Edition <http://www.manning.com/bauer3/> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> Spring Batch in Action <http://www.manning.com/templier/> Blog: http://garygregory.wordpress.com Home: http://garygregory.com/ Tweet! http://twitter.com/GaryGregory