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  
18  package org.apache.logging.log4j.core.config;
19  
20  import java.util.Objects;
21  import java.util.concurrent.locks.ReadWriteLock;
22  import java.util.concurrent.locks.ReentrantReadWriteLock;
23  
24  import org.apache.logging.log4j.Level;
25  import org.apache.logging.log4j.Marker;
26  import org.apache.logging.log4j.core.LogEvent;
27  import org.apache.logging.log4j.message.Message;
28  import org.apache.logging.log4j.util.Supplier;
29  
30  /**
31   * ReliabilityStrategy that uses read/write locks to prevent the LoggerConfig from stopping while it is in use.
32   */
33  public class LockingReliabilityStrategy implements ReliabilityStrategy {
34      private final LoggerConfig loggerConfig;
35      private final ReadWriteLock reconfigureLock = new ReentrantReadWriteLock();
36      private volatile boolean isStopping = false;
37  
38      public LockingReliabilityStrategy(final LoggerConfig loggerConfig) {
39          this.loggerConfig = Objects.requireNonNull(loggerConfig, "loggerConfig was null");
40      }
41  
42      /*
43       * (non-Javadoc)
44       *
45       * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
46       * java.lang.String, java.lang.String, org.apache.logging.log4j.Marker, org.apache.logging.log4j.Level,
47       * org.apache.logging.log4j.message.Message, java.lang.Throwable)
48       */
49      @Override
50      public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
51              final Marker marker, final Level level, final Message data, final Throwable t) {
52  
53          final LoggerConfig config = getActiveLoggerConfig(reconfigured);
54          try {
55              config.log(loggerName, fqcn, marker, level, data, t);
56          } finally {
57              config.getReliabilityStrategy().afterLogEvent();
58          }
59      }
60  
61      /*
62       * (non-Javadoc)
63       *
64       * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
65       * org.apache.logging.log4j.core.LogEvent)
66       */
67      @Override
68      public void log(final Supplier<LoggerConfig> reconfigured, final LogEvent event) {
69          final LoggerConfig config = getActiveLoggerConfig(reconfigured);
70          try {
71              config.log(event);
72          } finally {
73              config.getReliabilityStrategy().afterLogEvent();
74          }
75      }
76  
77      /*
78       * (non-Javadoc)
79       *
80       * @see
81       * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeLogEvent(org.apache.logging.log4j.core.config.
82       * LoggerConfig, org.apache.logging.log4j.util.Supplier)
83       */
84      @Override
85      public LoggerConfig getActiveLoggerConfig(final Supplier<LoggerConfig> next) {
86          LoggerConfig result = this.loggerConfig;
87          if (!beforeLogEvent()) {
88              result = next.get();
89              return result == this.loggerConfig ? result : result.getReliabilityStrategy().getActiveLoggerConfig(next);
90          }
91          return result;
92      }
93  
94      private boolean beforeLogEvent() {
95          reconfigureLock.readLock().lock();
96          if (isStopping) {
97              reconfigureLock.readLock().unlock();
98              return false;
99          }
100         return true;
101     }
102 
103     @Override
104     public void afterLogEvent() {
105         reconfigureLock.readLock().unlock();
106     }
107 
108     /*
109      * (non-Javadoc)
110      *
111      * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopAppenders()
112      */
113     @Override
114     public void beforeStopAppenders() {
115         reconfigureLock.writeLock().lock();
116         try {
117             isStopping = true;
118         } finally {
119             reconfigureLock.writeLock().unlock();
120         }
121     }
122 
123     /*
124      * (non-Javadoc)
125      *
126      * @see
127      * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopConfiguration(org.apache.logging.log4j.core
128      * .config.Configuration)
129      */
130     @Override
131     public void beforeStopConfiguration(final Configuration configuration) {
132         // no action
133     }
134 
135 }