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     */
017    package org.apache.logging.log4j.core.config;
018    
019    import java.net.URI;
020    import java.net.URISyntaxException;
021    
022    import org.apache.logging.log4j.LogManager;
023    import org.apache.logging.log4j.Logger;
024    import org.apache.logging.log4j.core.LoggerContext;
025    import org.apache.logging.log4j.core.impl.Log4jContextFactory;
026    import org.apache.logging.log4j.core.util.FileUtils;
027    import org.apache.logging.log4j.spi.LoggerContextFactory;
028    import org.apache.logging.log4j.status.StatusLogger;
029    
030    /**
031     * Initializes and configure the Logging system. This class provides several ways to construct a LoggerContext using
032     * the location of a configuration file, a context name, and various optional parameters.
033     */
034    public final class Configurator {
035    
036        private static final Logger LOGGER = StatusLogger.getLogger();
037    
038        private static final String FQCN = Configurator.class.getName();
039    
040        private Configurator() {
041        }
042    
043    
044        /**
045         * Initializes the Logging Context.
046         * @param name The Context name.
047         * @param loader The ClassLoader for the Context (or null).
048         * @param configLocation The configuration for the logging context.
049         * @return The LoggerContext.
050         */
051        public static LoggerContext initialize(final String name, final ClassLoader loader, final String configLocation) {
052            return initialize(name, loader, configLocation, null);
053    
054        }
055    
056        /**
057         * Initializes the Logging Context.
058         * @param name The Context name.
059         * @param loader The ClassLoader for the Context (or null).
060         * @param configLocation The configuration for the logging context.
061         * @param externalContext The external context to be attached to the LoggerContext
062         * @return The LoggerContext.
063         */
064        public static LoggerContext initialize(final String name, final ClassLoader loader, final String configLocation,
065                                               final Object externalContext) {
066    
067            try {
068                final URI uri = configLocation == null ? null : FileUtils.getCorrectedFilePathUri(configLocation);
069                return initialize(name, loader, uri, externalContext);
070            } catch (final URISyntaxException ex) {
071                LOGGER.error("There was a problem parsing the configuration location [{}].", configLocation, ex);
072            }
073            return null;
074        }
075    
076        /**
077         * Initializes the Logging Context.
078         * @param name The Context name.
079         * @param configLocation The configuration for the logging context.
080         * @return The LoggerContext.
081         */
082        public static LoggerContext initialize(final String name, final String configLocation) {
083            return initialize(name, null, configLocation);
084        }
085    
086        /**
087         * Initializes the Logging Context.
088         * @param name The Context name.
089         * @param loader The ClassLoader for the Context (or null).
090         * @param configLocation The configuration for the logging context.
091         * @return The LoggerContext.
092         */
093        public static LoggerContext initialize(final String name, final ClassLoader loader, final URI configLocation) {
094            return initialize(name, loader, configLocation, null);
095        }
096    
097        /**
098         * Initializes the Logging Context.
099         * @param name The Context name.
100         * @param loader The ClassLoader for the Context (or null).
101         * @param configLocation The configuration for the logging context.
102         * @param externalContext The external context to be attached to the LoggerContext
103         * @return The LoggerContext.
104         */
105        public static LoggerContext initialize(final String name, final ClassLoader loader, final URI configLocation,
106                                               final Object externalContext) {
107    
108            try {
109                final Log4jContextFactory factory = getFactory();
110                return factory == null ? null :
111                        factory.getContext(FQCN, loader, externalContext, false, configLocation, name);
112            } catch (final Exception ex) {
113                LOGGER.error("There was a problem initializing the LoggerContext [{}] using configuration at [{}].",
114                        name, configLocation, ex);
115            }
116            return null;
117        }
118    
119        /**
120         * Initializes the Logging Context.
121         * @param loader The ClassLoader for the Context (or null).
122         * @param source The InputSource for the configuration.
123         * @return The LoggerContext.
124         */
125        public static LoggerContext initialize(final ClassLoader loader,
126                                               final ConfigurationSource source) {
127            return initialize(loader, source, null);
128        }
129    
130        /**
131         * Initializes the Logging Context.
132         * @param loader The ClassLoader for the Context (or null).
133         * @param source The InputSource for the configuration.
134         * @param externalContext The external context to be attached to the LoggerContext.
135         * @return The LoggerContext.
136         */
137    
138        public static LoggerContext initialize(final ClassLoader loader,
139                                               final ConfigurationSource source,
140                                               final Object externalContext)
141        {
142    
143            try {
144                final Log4jContextFactory factory = getFactory();
145                return factory == null ? null :
146                        factory.getContext(FQCN, loader, externalContext, false, source);
147            } catch (final Exception ex) {
148                LOGGER.error("There was a problem obtaining a LoggerContext using the configuration source [{}]", source, ex);
149            }
150            return null;
151        }
152    
153        private static Log4jContextFactory getFactory() {
154            final LoggerContextFactory factory = LogManager.getFactory();
155            if (factory instanceof Log4jContextFactory) {
156                return (Log4jContextFactory) factory;
157            } else if (factory != null) {
158                LOGGER.error("LogManager returned an instance of {} which does not implement {}. Unable to initialize Log4j.",
159                        factory.getClass().getName(), Log4jContextFactory.class.getName());
160                return null;
161            } else {
162                LOGGER.fatal("LogManager did not return a LoggerContextFactory. This indicates something has gone terribly wrong!");
163                return null;
164            }
165        }
166    
167        /**
168         * Shuts down the given logging context.
169         * @param ctx the logging context to shut down, may be null.
170         */
171        public static void shutdown(final LoggerContext ctx) {
172            if (ctx != null) {
173                ctx.stop();
174            }
175        }
176    }