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