1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.db;
18
19 import java.io.Serializable;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.locks.Lock;
22 import java.util.concurrent.locks.ReadWriteLock;
23 import java.util.concurrent.locks.ReentrantReadWriteLock;
24
25 import org.apache.logging.log4j.LoggingException;
26 import org.apache.logging.log4j.core.Filter;
27 import org.apache.logging.log4j.core.Layout;
28 import org.apache.logging.log4j.core.LogEvent;
29 import org.apache.logging.log4j.core.appender.AbstractAppender;
30 import org.apache.logging.log4j.core.appender.AppenderLoggingException;
31 import org.apache.logging.log4j.core.config.Property;
32
33
34
35
36
37
38
39
40
41 public abstract class AbstractDatabaseAppender<T extends AbstractDatabaseManager> extends AbstractAppender {
42
43 public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B> {
44
45 }
46
47 public static final int DEFAULT_RECONNECT_INTERVAL_MILLIS = 5000;
48
49 private final ReadWriteLock lock = new ReentrantReadWriteLock();
50 private final Lock readLock = lock.readLock();
51 private final Lock writeLock = lock.writeLock();
52 private T manager;
53
54
55
56
57
58
59
60
61
62
63
64 @Deprecated
65 protected AbstractDatabaseAppender(final String name, final Filter filter, final boolean ignoreExceptions,
66 final T manager) {
67 super(name, filter, null, ignoreExceptions, Property.EMPTY_ARRAY);
68 this.manager = manager;
69 }
70
71
72
73
74
75
76
77
78
79
80
81 protected AbstractDatabaseAppender(final String name, final Filter filter,
82 final Layout<? extends Serializable> layout, final boolean ignoreExceptions,
83 final Property[] properties, final T manager) {
84 super(name, filter, layout, ignoreExceptions, properties);
85 this.manager = manager;
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99 @Deprecated
100 protected AbstractDatabaseAppender(final String name, final Filter filter,
101 final Layout<? extends Serializable> layout, final boolean ignoreExceptions, final T manager) {
102 super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
103 this.manager = manager;
104 }
105
106 @Override
107 public final void append(final LogEvent event) {
108 this.readLock.lock();
109 try {
110 this.getManager().write(event, toSerializable(event));
111 } catch (final LoggingException e) {
112 LOGGER.error("Unable to write to database [{}] for appender [{}].", this.getManager().getName(),
113 this.getName(), e);
114 throw e;
115 } catch (final Exception e) {
116 LOGGER.error("Unable to write to database [{}] for appender [{}].", this.getManager().getName(),
117 this.getName(), e);
118 throw new AppenderLoggingException("Unable to write to database in appender: " + e.getMessage(), e);
119 } finally {
120 this.readLock.unlock();
121 }
122 }
123
124
125
126
127
128
129
130 @Override
131 public final Layout<LogEvent> getLayout() {
132 return null;
133 }
134
135
136
137
138
139
140 public final T getManager() {
141 return this.manager;
142 }
143
144
145
146
147
148
149
150
151 protected final void replaceManager(final T manager) {
152 this.writeLock.lock();
153 try {
154 final T old = this.getManager();
155 if (!manager.isRunning()) {
156 manager.startup();
157 }
158 this.manager = manager;
159 old.close();
160 } finally {
161 this.writeLock.unlock();
162 }
163 }
164
165 @Override
166 public final void start() {
167 if (this.getManager() == null) {
168 LOGGER.error("No AbstractDatabaseManager set for the appender named [{}].", this.getName());
169 }
170 super.start();
171 if (this.getManager() != null) {
172 this.getManager().startup();
173 }
174 }
175
176 @Override
177 public boolean stop(final long timeout, final TimeUnit timeUnit) {
178 setStopping();
179 boolean stopped = super.stop(timeout, timeUnit, false);
180 if (this.getManager() != null) {
181 stopped &= this.getManager().stop(timeout, timeUnit);
182 }
183 setStopped();
184 return stopped;
185 }
186 }