View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.async;
18  
19  import java.net.URI;
20  import java.util.concurrent.TimeUnit;
21  
22  import org.apache.logging.log4j.core.Logger;
23  import org.apache.logging.log4j.core.LoggerContext;
24  import org.apache.logging.log4j.core.config.Configuration;
25  import org.apache.logging.log4j.core.config.DefaultConfiguration;
26  import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
27  import org.apache.logging.log4j.message.MessageFactory;
28  import org.apache.logging.log4j.status.StatusLogger;
29  
30  /**
31   * {@code LoggerContext} that creates {@code AsyncLogger} objects.
32   */
33  public class AsyncLoggerContext extends LoggerContext {
34  
35      private final AsyncLoggerDisruptor loggerDisruptor;
36  
37      public AsyncLoggerContext(final String name) {
38          super(name);
39          loggerDisruptor = new AsyncLoggerDisruptor(name);
40      }
41  
42      public AsyncLoggerContext(final String name, final Object externalContext) {
43          super(name, externalContext);
44          loggerDisruptor = new AsyncLoggerDisruptor(name);
45      }
46  
47      public AsyncLoggerContext(final String name, final Object externalContext, final URI configLocn) {
48          super(name, externalContext, configLocn);
49          loggerDisruptor = new AsyncLoggerDisruptor(name);
50      }
51  
52      public AsyncLoggerContext(final String name, final Object externalContext, final String configLocn) {
53          super(name, externalContext, configLocn);
54          loggerDisruptor = new AsyncLoggerDisruptor(name);
55      }
56  
57      @Override
58      protected Logger newInstance(final LoggerContext ctx, final String name, final MessageFactory messageFactory) {
59          return new AsyncLogger(ctx, name, messageFactory, loggerDisruptor);
60      }
61  
62      @Override
63      public void setName(final String name) {
64          super.setName("AsyncContext[" + name + "]");
65          loggerDisruptor.setContextName(name);
66      }
67  
68      /*
69       * (non-Javadoc)
70       *
71       * @see org.apache.logging.log4j.core.LoggerContext#start()
72       */
73      @Override
74      public void start() {
75          loggerDisruptor.start();
76          super.start();
77      }
78  
79      /*
80       * (non-Javadoc)
81       *
82       * @see org.apache.logging.log4j.core.LoggerContext#start(org.apache.logging.log4j.core.config.Configuration)
83       */
84      @Override
85      public void start(final Configuration config) {
86          maybeStartHelper(config);
87          super.start(config);
88      }
89  
90      private void maybeStartHelper(final Configuration config) {
91          // If no log4j configuration was found, there are no loggers
92          // and there is no point in starting the disruptor (which takes up
93          // significant memory and starts a thread).
94          if (config instanceof DefaultConfiguration) {
95              StatusLogger.getLogger().debug("[{}] Not starting Disruptor for DefaultConfiguration.", getName());
96          } else {
97              loggerDisruptor.start();
98          }
99      }
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 }