Source Code for Apache Log4j Core Implementation

Apache Log4j Core Implementation provides the functional components of the logging system. Users are free to create their own plugins and include them in the logging configuration. Apache Log4j Core is a required module to use Apache Log4j.

Bytecode (Java 8) for Apache Log4j Core Implementation is provided in a separate JAR file like log4j-core-2.14.1.jar.

Source Code files for Apache Log4j API are provided in both binary packge like apache-log4j-2.14.1-bin.zip and source package like apache-log4j-2.14.1-src.zip. You can download them at Apache Log4j Website.

You can also browse Source Code files for Apache Log4j Core Implementation 2.14.1 below.

✍: FYIcenter.com

org/apache/logging/log4j/core/selector/JndiContextSelector.java

/*
 * 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.core.selector;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import javax.naming.NamingException;

import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.impl.ContextAnchor;
import org.apache.logging.log4j.core.net.JndiManager;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.status.StatusLogger;

/**
 * This class can be used to define a custom logger repository. It makes use of the fact that in J2EE environments, each
 * web-application is guaranteed to have its own JNDI context relative to the <code>java:comp/env</code> context. In
 * EJBs, each enterprise bean (albeit not each application) has its own context relative to the
 * <code>java:comp/env</code> context. An <code>env-entry</code> in a deployment descriptor provides the information to
 * the JNDI context. Once the <code>env-entry</code> is set, a repository selector can query the JNDI application
 * context to look up the value of the entry. The logging context of the web-application will depend on the value the
 * env-entry. The JNDI context which is looked up by this class is <code>java:comp/env/log4j/context-name</code>.
 *
 * <p>
 * Here is an example of an <code>env-entry</code>:
 * </p>
 * <blockquote>
 *
 * <pre>
 * &lt;env-entry&gt;
 *   &lt;description&gt;JNDI logging context name for this app&lt;/description&gt;
 *   &lt;env-entry-name&gt;log4j/context-name&lt;/env-entry-name&gt;
 *   &lt;env-entry-value&gt;aDistinctiveLoggingContextName&lt;/env-entry-value&gt;
 *   &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
 * &lt;/env-entry&gt;
 * </pre>
 *
 * </blockquote>
 *
 * <p>
 * <em>If multiple applications use the same logging context name, then they
 * will share the same logging context.</em>
 * </p>
 *
 * <p>
 * You can also specify the URL for this context's configuration resource. This repository selector
 * (ContextJNDISelector) will use this resource to automatically configure the log4j repository.
 * </p>
 ** <blockquote>
 *
 * <pre>
 * &lt;env-entry&gt;
 *   &lt;description&gt;URL for configuring log4j context&lt;/description&gt;
 *   &lt;env-entry-name&gt;log4j/configuration-resource&lt;/env-entry-name&gt;
 *   &lt;env-entry-value&gt;urlOfConfigurationResource&lt;/env-entry-value&gt;
 *   &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
 * &lt;/env-entry&gt;
 * </pre>
 *
 * </blockquote>
 *
 * <p>
 * It usually good practice for configuration resources of distinct applications to have distinct names. However, if
 * this is not possible Naming
 * </p>
 */
public class JndiContextSelector implements NamedContextSelector {

    private static final LoggerContext CONTEXT = new LoggerContext("Default");

    private static final ConcurrentMap<String, LoggerContext> CONTEXT_MAP =
        new ConcurrentHashMap<>();

    private static final StatusLogger LOGGER = StatusLogger.getLogger();

    @Override
    public void shutdown(String fqcn, ClassLoader loader, boolean currentContext, boolean allContexts) {
        LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
        if (ctx == null) {
            String loggingContextName = getContextName();
            if (loggingContextName != null) {
                ctx = CONTEXT_MAP.get(loggingContextName);
            }
        }
        if (ctx != null) {
            ctx.stop(DEFAULT_STOP_TIMEOUT, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public boolean hasContext(String fqcn, ClassLoader loader, boolean currentContext) {
        LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
        if (ctx == null) {
            String loggingContextName = getContextName();
            if (loggingContextName == null) {
                return false;
            }
            ctx = CONTEXT_MAP.get(loggingContextName);
        }
        return ctx != null && ctx.isStarted();
    }

    @Override
    public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext) {
        return getContext(fqcn, loader, currentContext, null);
    }

    @Override
    public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext,
                                    final URI configLocation) {

        final LoggerContext lc = ContextAnchor.THREAD_CONTEXT.get();
        if (lc != null) {
            return lc;
        }

        String loggingContextName = null;

        try (final JndiManager jndiManager = JndiManager.getDefaultManager()) {
            loggingContextName = jndiManager.lookup(Constants.JNDI_CONTEXT_NAME);
        } catch (final NamingException ne) {
            LOGGER.error("Unable to lookup {}", Constants.JNDI_CONTEXT_NAME, ne);
        }

        return loggingContextName == null ? CONTEXT : locateContext(loggingContextName, null, configLocation);
    }

    private String getContextName() {
        String loggingContextName = null;

        try (final JndiManager jndiManager = JndiManager.getDefaultManager()) {
            loggingContextName = jndiManager.lookup(Constants.JNDI_CONTEXT_NAME);
        } catch (final NamingException ne) {
            LOGGER.error("Unable to lookup {}", Constants.JNDI_CONTEXT_NAME, ne);
        }
        return loggingContextName;
    }

    @Override
    public LoggerContext locateContext(final String name, final Object externalContext, final URI configLocation) {
        if (name == null) {
            LOGGER.error("A context name is required to locate a LoggerContext");
            return null;
        }
        if (!CONTEXT_MAP.containsKey(name)) {
            final LoggerContext ctx = new LoggerContext(name, externalContext, configLocation);
            CONTEXT_MAP.putIfAbsent(name, ctx);
        }
        return CONTEXT_MAP.get(name);
    }

    @Override
    public void removeContext(final LoggerContext context) {

        for (final Map.Entry<String, LoggerContext> entry : CONTEXT_MAP.entrySet()) {
            if (entry.getValue().equals(context)) {
                CONTEXT_MAP.remove(entry.getKey());
            }
        }
    }

    @Override
    public LoggerContext removeContext(final String name) {
        return CONTEXT_MAP.remove(name);
    }

    @Override
    public List<LoggerContext> getLoggerContexts() {
        return Collections.unmodifiableList(new ArrayList<>(CONTEXT_MAP.values()));
    }

}

org/apache/logging/log4j/core/selector/JndiContextSelector.java

 

⇒ Source Code for Apache Log4j JDK Logging Adapter

⇐ Source Code for Apache Log4j API

⇑ Downloading and Reviewing Apache Log4j Packages

⇑⇑ FAQ for Apache Log4j

2015-11-03, 51401👍, 0💬