1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.net;
19
20 import org.apache.log4j.AppenderSkeleton;
21 import org.apache.log4j.helpers.Constants;
22 import org.apache.log4j.helpers.LogLog;
23 import org.apache.log4j.spi.LoggingEvent;
24 import org.apache.log4j.xml.XMLLayout;
25
26 import java.io.IOException;
27 import java.net.DatagramPacket;
28 import java.net.DatagramSocket;
29 import java.net.InetAddress;
30 import java.net.UnknownHostException;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class UDPAppender extends AppenderSkeleton implements PortBased {
53
54
55
56 public static final int DEFAULT_PORT = 9991;
57
58
59
60
61
62 String hostname;
63 String remoteHost;
64 String application;
65 String encoding;
66 InetAddress address;
67 int port = DEFAULT_PORT;
68 DatagramSocket outSocket;
69
70
71
72
73 public static final String ZONE = "_log4j_xml_udp_appender.local.";
74
75
76
77 boolean inError = false;
78 private boolean advertiseViaMulticastDNS;
79 private ZeroConfSupport zeroConf;
80
81 public UDPAppender() {
82 super(false);
83 }
84
85
86
87
88 public UDPAppender(final InetAddress address, final int port) {
89 super(false);
90 this.address = address;
91 this.remoteHost = address.getHostName();
92 this.port = port;
93 activateOptions();
94 }
95
96
97
98
99 public UDPAppender(final String host, final int port) {
100 super(false);
101 this.port = port;
102 this.address = getAddressByName(host);
103 this.remoteHost = host;
104 activateOptions();
105 }
106
107
108
109
110 public void activateOptions() {
111 try {
112 hostname = InetAddress.getLocalHost().getHostName();
113 } catch (UnknownHostException uhe) {
114 try {
115 hostname = InetAddress.getLocalHost().getHostAddress();
116 } catch (UnknownHostException uhe2) {
117 hostname = "unknown";
118 }
119 }
120
121
122 if (application == null) {
123 application = System.getProperty(Constants.APPLICATION_KEY);
124 } else {
125 if (System.getProperty(Constants.APPLICATION_KEY) != null) {
126 application = application + "-" + System.getProperty(Constants.APPLICATION_KEY);
127 }
128 }
129
130 if (remoteHost != null) {
131 address = getAddressByName(remoteHost);
132 connect(address, port);
133 } else {
134 String err = "The RemoteHost property is required for SocketAppender named " + name;
135 LogLog.error(err);
136 throw new IllegalStateException(err);
137 }
138
139 if (layout == null) {
140 layout = new XMLLayout();
141 }
142
143 if (advertiseViaMulticastDNS) {
144 zeroConf = new ZeroConfSupport(ZONE, port, getName());
145 zeroConf.advertise();
146 }
147
148 super.activateOptions();
149 }
150
151
152
153
154
155
156 public synchronized void close() {
157 if (closed) {
158 return;
159 }
160
161 if (advertiseViaMulticastDNS) {
162 zeroConf.unadvertise();
163 }
164
165 this.closed = true;
166 cleanUp();
167 }
168
169
170
171
172
173 public void cleanUp() {
174 if (outSocket != null) {
175 try {
176 outSocket.close();
177 } catch (Exception e) {
178 LogLog.error("Could not close outSocket.", e);
179 }
180
181 outSocket = null;
182 }
183 }
184
185 void connect(InetAddress address, int port) {
186 if (this.address == null) {
187 return;
188 }
189
190 try {
191
192 cleanUp();
193 outSocket = new DatagramSocket();
194 outSocket.connect(address, port);
195 } catch (IOException e) {
196 LogLog.error(
197 "Could not open UDP Socket for sending.", e);
198 inError = true;
199 }
200 }
201
202 public void append(LoggingEvent event) {
203 if (inError) {
204 return;
205 }
206
207 if (event == null) {
208 return;
209 }
210
211 if (address == null) {
212 return;
213 }
214
215 if (outSocket != null) {
216 event.setProperty(Constants.HOSTNAME_KEY, hostname);
217 if (application != null) {
218 event.setProperty(Constants.APPLICATION_KEY, application);
219 }
220
221 try {
222 StringBuilder buf = new StringBuilder(layout.format(event));
223
224 byte[] payload;
225 if (encoding == null) {
226 payload = buf.toString().getBytes();
227 } else {
228 payload = buf.toString().getBytes(encoding);
229 }
230
231 DatagramPacket dp =
232 new DatagramPacket(payload, payload.length, address, port);
233 outSocket.send(dp);
234 } catch (IOException e) {
235 outSocket = null;
236 LogLog.warn("Detected problem with UDP connection: " + e);
237 }
238 }
239 }
240
241 public boolean isActive() {
242 return !inError;
243 }
244
245 InetAddress getAddressByName(String host) {
246 try {
247 return InetAddress.getByName(host);
248 } catch (Exception e) {
249 LogLog.error("Could not find address of [" + host + "].", e);
250 return null;
251 }
252 }
253
254
255
256
257
258 public boolean requiresLayout() {
259 return true;
260 }
261
262
263
264
265
266 public void setRemoteHost(String host) {
267 remoteHost = host;
268 }
269
270
271
272
273 public String getRemoteHost() {
274 return remoteHost;
275 }
276
277
278
279
280
281 public void setApplication(String app) {
282 this.application = app;
283 }
284
285
286
287
288 public String getApplication() {
289 return application;
290 }
291
292
293
294
295
296 public void setEncoding(String encoding) {
297 this.encoding = encoding;
298 }
299
300
301
302
303 public String getEncoding() {
304 return encoding;
305 }
306
307
308
309
310
311 public void setPort(int port) {
312 this.port = port;
313 }
314
315
316
317
318 public int getPort() {
319 return port;
320 }
321
322 public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
323 this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
324 }
325
326 public boolean isAdvertiseViaMulticastDNS() {
327 return advertiseViaMulticastDNS;
328 }
329 }