1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender;
18
19 import java.io.Serializable;
20 import java.util.concurrent.locks.Lock;
21 import java.util.concurrent.locks.ReadWriteLock;
22 import java.util.concurrent.locks.ReentrantReadWriteLock;
23
24 import org.apache.logging.log4j.core.Filter;
25 import org.apache.logging.log4j.core.Layout;
26 import org.apache.logging.log4j.core.LogEvent;
27
28
29
30
31
32
33 public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager> extends AbstractAppender {
34
35
36
37
38
39
40
41
42
43
44 protected final boolean immediateFlush;
45
46 private volatile M manager;
47
48 private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
49 private final Lock readLock = rwLock.readLock();
50 private final Lock writeLock = rwLock.writeLock();
51
52
53
54
55
56
57
58
59
60 protected AbstractOutputStreamAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
61 final boolean ignoreExceptions, final boolean immediateFlush,
62 final M manager) {
63 super(name, filter, layout, ignoreExceptions);
64 this.manager = manager;
65 this.immediateFlush = immediateFlush;
66 }
67
68
69
70
71
72
73 public M getManager() {
74 return manager;
75 }
76
77 protected void replaceManager(final M newManager) {
78
79 writeLock.lock();
80 try {
81 final M old = manager;
82 manager = newManager;
83 old.release();
84 } finally {
85 writeLock.unlock();
86 }
87
88 }
89
90 @Override
91 public void start() {
92 if (getLayout() == null) {
93 LOGGER.error("No layout set for the appender named [" + getName() + "].");
94 }
95 if (manager == null) {
96 LOGGER.error("No OutputStreamManager set for the appender named [" + getName() + "].");
97 }
98 super.start();
99 }
100
101 @Override
102 public void stop() {
103 super.stop();
104 manager.release();
105 }
106
107
108
109
110
111
112
113
114 @Override
115 public void append(final LogEvent event) {
116 readLock.lock();
117 try {
118 final byte[] bytes = getLayout().toByteArray(event);
119 if (bytes.length > 0) {
120 manager.write(bytes);
121 if (this.immediateFlush || event.isEndOfBatch()) {
122 manager.flush();
123 }
124 }
125 } catch (final AppenderLoggingException ex) {
126 error("Unable to write to stream " + manager.getName() + " for appender " + getName());
127 throw ex;
128 } finally {
129 readLock.unlock();
130 }
131 }
132 }