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.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 public void afterLogEvent() {
104 reconfigureLock.readLock().unlock();
105 }
106
107 /*
108 * (non-Javadoc)
109 *
110 * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopAppenders()
111 */
112 @Override
113 public void beforeStopAppenders() {
114 reconfigureLock.writeLock().lock();
115 try {
116 isStopping = true;
117 } finally {
118 reconfigureLock.writeLock().unlock();
119 }
120 }
121
122 /*
123 * (non-Javadoc)
124 *
125 * @see
126 * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopConfiguration(org.apache.logging.log4j.core
127 * .config.Configuration)
128 */
129 @Override
130 public void beforeStopConfiguration(Configuration configuration) {
131 // no action
132 }
133
134 }