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      /* (non-Javadoc)
43       * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier, java.lang.String, java.lang.String, org.apache.logging.log4j.Marker, org.apache.logging.log4j.Level, org.apache.logging.log4j.message.Message, java.lang.Throwable)
44       */
45      @Override
46      public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
47              final Marker marker, final Level level, final Message data, final Throwable t) {
48  
49          final LoggerConfig config = getActiveLoggerConfig(reconfigured);
50          try {
51              config.log(loggerName, fqcn, marker, level, data, t);
52          } finally {
53              config.getReliabilityStrategy().afterLogEvent();
54          }
55      }
56  
57      /* (non-Javadoc)
58       * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier, org.apache.logging.log4j.core.LogEvent)
59       */
60      @Override
61      public void log(final Supplier<LoggerConfig> reconfigured, final LogEvent event) {
62          final LoggerConfig config = getActiveLoggerConfig(reconfigured);
63          try {
64              config.log(event);
65          } finally {
66              config.getReliabilityStrategy().afterLogEvent();
67          }
68      }
69  
70      /* (non-Javadoc)
71       * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeLogEvent(org.apache.logging.log4j.core.config.LoggerConfig, org.apache.logging.log4j.util.Supplier)
72       */
73      @Override
74      public LoggerConfig getActiveLoggerConfig(final Supplier<LoggerConfig> next) {
75          LoggerConfig result = this.loggerConfig;
76          if (!beforeLogEvent()) {
77              result = next.get();
78              return result.getReliabilityStrategy().getActiveLoggerConfig(next);
79          }
80          return result;
81      }
82  
83      private boolean beforeLogEvent() {
84          reconfigureLock.readLock().lock();
85          if (isStopping) {
86              reconfigureLock.readLock().unlock();
87              return false;
88          }
89          return true;
90      }
91  
92      public void afterLogEvent() {
93          reconfigureLock.readLock().unlock();
94      }
95  
96      /* (non-Javadoc)
97       * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopAppenders()
98       */
99      @Override
100     public void beforeStopAppenders() {
101         reconfigureLock.writeLock().lock();
102         try {
103             isStopping = true;
104         } finally {
105             reconfigureLock.writeLock().unlock();
106         }
107     }
108 
109     /* (non-Javadoc)
110      * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopConfiguration(org.apache.logging.log4j.core.config.Configuration)
111      */
112     @Override
113     public void beforeStopConfiguration(Configuration configuration) {
114         // no action
115     }
116 
117 }