    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    }