View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.sift;
15  
16  import ch.qos.logback.core.Appender;
17  import ch.qos.logback.core.Context;
18  import ch.qos.logback.core.CoreConstants;
19  import ch.qos.logback.core.helpers.NOPAppender;
20  import ch.qos.logback.core.joran.spi.JoranException;
21  import ch.qos.logback.core.spi.AbstractComponentTracker;
22  import ch.qos.logback.core.spi.ContextAwareImpl;
23  
24  /**
25   * Track appenders by key. When an appender is not used for longer than
26   * {@link #DEFAULT_TIMEOUT} it is stopped and removed.
27   *
28   * @author Tommy Becker
29   * @author Ceki Gulcu
30   * @author David Roussel
31   */
32  public class AppenderTracker<E> extends AbstractComponentTracker<Appender<E>> {
33  
34      int nopaWarningCount = 0;
35  
36      final Context context;
37      final AppenderFactory<E> appenderFactory;
38      final ContextAwareImpl contextAware;
39  
40      public AppenderTracker(Context context, AppenderFactory<E> appenderFactory) {
41          super();
42          this.context = context;
43          this.appenderFactory = appenderFactory;
44          this.contextAware = new ContextAwareImpl(context, this);
45      }
46  
47      @Override
48      protected void processPriorToRemoval(Appender<E> component) {
49          component.stop();
50      }
51  
52      @Override
53      protected Appender<E> buildComponent(String key) {
54          Appender<E> appender = null;
55          try {
56              appender = appenderFactory.buildAppender(context, key);
57          } catch (JoranException je) {
58              contextAware.addError("Error while building appender with discriminating value [" + key + "]");
59          }
60          if (appender == null) {
61              appender = buildNOPAppender(key);
62          }
63  
64          return appender;
65      }
66  
67      private NOPAppender<E> buildNOPAppender(String key) {
68          if (nopaWarningCount < CoreConstants.MAX_ERROR_COUNT) {
69              nopaWarningCount++;
70              contextAware.addError("Building NOPAppender for discriminating value [" + key + "]");
71          }
72          NOPAppender<E> nopa = new NOPAppender<E>();
73          nopa.setContext(context);
74          nopa.start();
75          return nopa;
76      }
77  
78      @Override
79      protected boolean isComponentStale(Appender<E> appender) {
80          return !appender.isStarted();
81      }
82  
83  }