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