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