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