001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.appserver.tomcat;
018
019import java.net.URI;
020import java.net.URISyntaxException;
021import java.net.URL;
022
023import org.apache.juli.logging.Log;
024import org.apache.logging.log4j.Level;
025import org.apache.logging.log4j.LogManager;
026import org.apache.logging.log4j.spi.ExtendedLogger;
027import org.apache.logging.log4j.spi.LoggerContext;
028
029/**
030 * Implements the Log interface from Tomcat 8.5 and greater.
031 *
032 * In order to use this class to cause Tomcat to use Log4j for logging, the jar containing this class as well as the
033 * log4j-api and log4j-core jars must be added to Tomcat's boot classpath. This is most easily accomplished by
034 * placing these jars in a directory and then adding the contents of that directory to the CLASSPATH
035 * environment variable in setenv.sh in Tomcat's bin directory.
036 *
037 * The Log4j configuration file must also be present on the classpath. This implementation will use the
038 * first file it finds with one of the following file names: log4j2-tomcat.xml, log4j2-tomcat.json,
039 * log4j2-tomcat.yaml, log4j2-tomcat.yml, log4j2-tomcat.properties. Again, this can be accomplished by adding
040 * this file to a directory and then adding that directory to the CLASSPATH environment variable in setenv.sh.
041 *
042 * @since 2.10.0
043 */
044public class TomcatLogger implements Log {
045
046    private static final long serialVersionUID = 1L;
047    private static final String FQCN = TomcatLogger.class.getName();
048    private static final String[] FILE_NAMES = {
049        "log4j2-tomcat.xml", "log4j2-tomcat.json", "log4j2-tomcat.yaml", "log4j2-tomcat.yml",
050        "log4j2-tomcat.properties"
051    };
052
053    private final ExtendedLogger logger;
054
055    /**
056     * This constructor is used by ServiceLoader to load an instance of the class.
057     */
058    public TomcatLogger() {
059        logger = null;
060    }
061
062    /**
063     * This constructor is used by LogFactory to create a new Logger.
064     * @param name The name of the Logger.
065     */
066    public TomcatLogger(final String name) {
067        this.logger = PrivateManager.getLogger(name);
068    }
069
070    @Override
071    public boolean isDebugEnabled() {
072        return logger.isDebugEnabled();
073    }
074
075    @Override
076    public boolean isErrorEnabled() {
077        return logger.isErrorEnabled();
078    }
079
080    @Override
081    public boolean isFatalEnabled() {
082        return logger.isFatalEnabled();
083    }
084
085    @Override
086    public boolean isInfoEnabled() {
087        return logger.isInfoEnabled();
088    }
089
090    @Override
091    public boolean isTraceEnabled() {
092        return logger.isTraceEnabled();
093    }
094
095    @Override
096    public boolean isWarnEnabled() {
097        return logger.isWarnEnabled();
098    }
099
100    @Override
101    public void trace(final Object o) {
102        logger.logIfEnabled(FQCN, Level.TRACE, null, o, null);
103    }
104
105    @Override
106    public void trace(final Object o, final Throwable throwable) {
107        logger.logIfEnabled(FQCN, Level.TRACE, null, o, throwable);
108    }
109
110    @Override
111    public void debug(final Object o) {
112        logger.logIfEnabled(FQCN, Level.DEBUG, null, o, null);
113    }
114
115    @Override
116    public void debug(final Object o, final Throwable throwable) {
117        logger.logIfEnabled(FQCN, Level.DEBUG, null, o, throwable);
118    }
119
120    @Override
121    public void info(final Object o) {
122        logger.logIfEnabled(FQCN, Level.INFO, null, o, null);
123    }
124
125    @Override
126    public void info(final Object o, final Throwable throwable) {
127        logger.logIfEnabled(FQCN, Level.INFO, null, o, throwable);
128    }
129
130    @Override
131    public void warn(final Object o) {
132        logger.logIfEnabled(FQCN, Level.WARN, null, o, null);
133    }
134
135    @Override
136    public void warn(final Object o, final Throwable throwable) {
137        logger.logIfEnabled(FQCN, Level.WARN, null, o, throwable);
138    }
139
140    @Override
141    public void error(final Object o) {
142        logger.logIfEnabled(FQCN, Level.ERROR, null, o, null);
143    }
144
145    @Override
146    public void error(final Object o, final Throwable throwable) {
147        logger.logIfEnabled(FQCN, Level.ERROR, null, o, throwable);
148    }
149
150    @Override
151    public void fatal(final Object o) {
152        logger.logIfEnabled(FQCN, Level.FATAL, null, o, null);
153    }
154
155    @Override
156    public void fatal(final Object o, final Throwable throwable) {
157        logger.logIfEnabled(FQCN, Level.FATAL, null, o, throwable);
158    }
159
160    /**
161     * Internal LogManager.
162     */
163    private static class PrivateManager extends LogManager {
164
165        public static LoggerContext getContext() {
166            final ClassLoader cl = TomcatLogger.class.getClassLoader();
167            URI uri = null;
168            for (final String fileName : FILE_NAMES) {
169                try {
170                    final URL url = cl.getResource(fileName);
171                    if (url != null) {
172                        uri = url.toURI();
173                        break;
174                    }
175                } catch (final URISyntaxException ex) {
176                    // Ignore the exception.
177                }
178            }
179            if (uri == null) {
180                return getContext(FQCN, cl, false);
181            }
182            return getContext(FQCN, cl, false, uri, "Tomcat");
183        }
184
185        public static ExtendedLogger getLogger(final String name) {
186            return getContext().getLogger(name);
187        }
188    }
189}