1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.logging.log4j.core.config;
19
20 import java.util.Objects;
21 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.atomic.AtomicBoolean;
23 import java.util.concurrent.atomic.AtomicInteger;
24 import java.util.concurrent.locks.Condition;
25 import java.util.concurrent.locks.Lock;
26 import java.util.concurrent.locks.ReentrantLock;
27
28 import org.apache.logging.log4j.Level;
29 import org.apache.logging.log4j.Marker;
30 import org.apache.logging.log4j.core.LogEvent;
31 import org.apache.logging.log4j.message.Message;
32 import org.apache.logging.log4j.util.Supplier;
33
34
35
36
37
38 public class AwaitCompletionReliabilityStrategy implements ReliabilityStrategy, LocationAwareReliabilityStrategy {
39 private static final int MAX_RETRIES = 3;
40 private final AtomicInteger counter = new AtomicInteger();
41 private final AtomicBoolean shutdown = new AtomicBoolean(false);
42 private final Lock shutdownLock = new ReentrantLock();
43 private final Condition noLogEvents = shutdownLock.newCondition();
44 private final LoggerConfig loggerConfig;
45
46 public AwaitCompletionReliabilityStrategy(final LoggerConfig loggerConfig) {
47 this.loggerConfig = Objects.requireNonNull(loggerConfig, "loggerConfig is null");
48 }
49
50
51
52
53
54
55
56
57 @Override
58 public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
59 final Marker marker, final Level level, final Message data, final Throwable t) {
60
61 final LoggerConfig config = getActiveLoggerConfig(reconfigured);
62 try {
63 config.log(loggerName, fqcn, marker, level, data, t);
64 } finally {
65 config.getReliabilityStrategy().afterLogEvent();
66 }
67 }
68
69
70
71
72
73
74
75
76 @Override
77 public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
78 final StackTraceElement location, final Marker marker, final Level level, final Message data,
79 final Throwable t) {
80 final LoggerConfig config = getActiveLoggerConfig(reconfigured);
81 try {
82 config.log(loggerName, fqcn, location, marker, level, data, t);
83 } finally {
84 config.getReliabilityStrategy().afterLogEvent();
85 }
86 }
87
88
89
90
91
92
93
94 @Override
95 public void log(final Supplier<LoggerConfig> reconfigured, final LogEvent event) {
96 final LoggerConfig config = getActiveLoggerConfig(reconfigured);
97 try {
98 config.log(event);
99 } finally {
100 config.getReliabilityStrategy().afterLogEvent();
101 }
102 }
103
104
105
106
107
108
109
110
111 @Override
112 public LoggerConfig getActiveLoggerConfig(final Supplier<LoggerConfig> next) {
113 LoggerConfig result = this.loggerConfig;
114 if (!beforeLogEvent()) {
115 result = next.get();
116 return result == this.loggerConfig ? result : result.getReliabilityStrategy().getActiveLoggerConfig(next);
117 }
118 return result;
119 }
120
121 private boolean beforeLogEvent() {
122 return counter.incrementAndGet() > 0;
123 }
124
125 @Override
126 public void afterLogEvent() {
127 if (counter.decrementAndGet() == 0 && shutdown.get()) {
128 signalCompletionIfShutdown();
129 }
130 }
131
132 private void signalCompletionIfShutdown() {
133 final Lock lock = shutdownLock;
134 lock.lock();
135 try {
136 noLogEvents.signalAll();
137 } finally {
138 lock.unlock();
139 }
140 }
141
142
143
144
145
146
147 @Override
148 public void beforeStopAppenders() {
149 waitForCompletion();
150 }
151
152
153
154
155 private void waitForCompletion() {
156 shutdownLock.lock();
157 try {
158 if (shutdown.compareAndSet(false, true)) {
159 int retries = 0;
160
161 while (!counter.compareAndSet(0, Integer.MIN_VALUE)) {
162
163
164 if (counter.get() < 0) {
165 return;
166 }
167
168 try {
169 noLogEvents.await(retries + 1, TimeUnit.SECONDS);
170 } catch (final InterruptedException ie) {
171 if (++retries > MAX_RETRIES) {
172 break;
173 }
174 }
175 }
176 }
177 } finally {
178 shutdownLock.unlock();
179 }
180 }
181
182
183
184
185
186
187
188
189 @Override
190 public void beforeStopConfiguration(final Configuration configuration) {
191
192 }
193
194 }