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.core.async;
018
019import java.net.URI;
020
021import org.apache.logging.log4j.core.Logger;
022import org.apache.logging.log4j.core.LoggerContext;
023import org.apache.logging.log4j.core.config.Configuration;
024import org.apache.logging.log4j.core.config.DefaultConfiguration;
025import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
026import org.apache.logging.log4j.message.MessageFactory;
027import org.apache.logging.log4j.status.StatusLogger;
028
029/**
030 * {@code LoggerContext} that creates {@code AsyncLogger} objects.
031 */
032public class AsyncLoggerContext extends LoggerContext {
033
034    private final AsyncLoggerDisruptor loggerDisruptor;
035
036    public AsyncLoggerContext(final String name) {
037        super(name);
038        loggerDisruptor = new AsyncLoggerDisruptor(name);
039    }
040
041    public AsyncLoggerContext(final String name, final Object externalContext) {
042        super(name, externalContext);
043        loggerDisruptor = new AsyncLoggerDisruptor(name);
044    }
045
046    public AsyncLoggerContext(final String name, final Object externalContext, final URI configLocn) {
047        super(name, externalContext, configLocn);
048        loggerDisruptor = new AsyncLoggerDisruptor(name);
049    }
050
051    public AsyncLoggerContext(final String name, final Object externalContext, final String configLocn) {
052        super(name, externalContext, configLocn);
053        loggerDisruptor = new AsyncLoggerDisruptor(name);
054    }
055
056    @Override
057    protected Logger newInstance(final LoggerContext ctx, final String name, final MessageFactory messageFactory) {
058        return new AsyncLogger(ctx, name, messageFactory, loggerDisruptor);
059    }
060    
061    @Override
062    public void setName(final String name) {
063        super.setName("AsyncContext[" + name + "]");
064        loggerDisruptor.setContextName(name);
065    }
066
067    /*
068     * (non-Javadoc)
069     * 
070     * @see org.apache.logging.log4j.core.LoggerContext#start()
071     */
072    @Override
073    public void start() {
074        loggerDisruptor.start();
075        super.start();
076    }
077
078    /*
079     * (non-Javadoc)
080     * 
081     * @see org.apache.logging.log4j.core.LoggerContext#start(org.apache.logging.log4j.core.config.Configuration)
082     */
083    @Override
084    public void start(final Configuration config) {
085        maybeStartHelper(config);
086        super.start(config);
087    }
088
089    private void maybeStartHelper(final Configuration config) {
090        // If no log4j configuration was found, there are no loggers
091        // and there is no point in starting the disruptor (which takes up
092        // significant memory and starts a thread).
093        if (config instanceof DefaultConfiguration) {
094            StatusLogger.getLogger().debug("[{}] Not starting Disruptor for DefaultConfiguration.", getName());
095        } else {
096            loggerDisruptor.start();
097        }
098    }
099
100    @Override
101    public void stop() {
102        loggerDisruptor.stop(); // first stop Disruptor
103        super.stop();
104    }
105
106    /**
107     * Creates and returns a new {@code RingBufferAdmin} that instruments the ringbuffer of the {@code AsyncLogger}
108     * objects in this {@code LoggerContext}.
109     *
110     * @return a new {@code RingBufferAdmin} that instruments the ringbuffer
111     */
112    public RingBufferAdmin createRingBufferAdmin() {
113        return loggerDisruptor.createRingBufferAdmin(getName());
114    }
115
116    /**
117     * Signals this context whether it is allowed to use ThreadLocal objects for efficiency.
118     * @param useThreadLocals whether this context is allowed to use ThreadLocal objects
119     */
120    public void setUseThreadLocals(final boolean useThreadLocals) {
121        loggerDisruptor.setUseThreadLocals(useThreadLocals);
122    }
123}