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 java.io.IOException;
21 import java.net.DatagramPacket;
22 import java.net.InetAddress;
23 import java.net.MulticastSocket;
24 import java.net.UnknownHostException;
25 import java.util.HashMap;
26 import java.util.Hashtable;
27 import java.util.Map;
28
29 import org.apache.log4j.AppenderSkeleton;
30 import org.apache.log4j.helpers.Constants;
31 import org.apache.log4j.spi.LoggingEvent;
32 import org.apache.log4j.helpers.LogLog;
33 import org.apache.log4j.xml.XMLLayout;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class MulticastAppender extends AppenderSkeleton implements PortBased {
57
58
59
60 static final int DEFAULT_PORT = 9991;
61
62
63
64
65
66 public static final String ZONE = "_log4j_xml_mcast_appender.local.";
67
68
69
70
71
72 String hostname;
73 String remoteHost;
74 String application;
75 int timeToLive;
76 InetAddress address;
77 int port = DEFAULT_PORT;
78 MulticastSocket outSocket;
79 private String encoding;
80
81 private boolean locationInfo = false;
82 private boolean advertiseViaMulticastDNS;
83 private ZeroConfSupport zeroConf;
84
85 public MulticastAppender() {
86 super(false);
87 }
88
89
90
91
92 public void activateOptions() {
93 try {
94 hostname = InetAddress.getLocalHost().getHostName();
95 } catch (UnknownHostException uhe) {
96 try {
97 hostname = InetAddress.getLocalHost().getHostAddress();
98 } catch (UnknownHostException uhe2) {
99 hostname = "unknown";
100 }
101 }
102
103
104 if (application == null) {
105 application = System.getProperty(Constants.APPLICATION_KEY);
106 } else {
107 if (System.getProperty(Constants.APPLICATION_KEY) != null) {
108 application = application + "-" + System.getProperty(Constants.APPLICATION_KEY);
109 }
110 }
111
112 if(remoteHost != null) {
113 address = getAddressByName(remoteHost);
114 } else {
115 String err = "The RemoteHost property is required for MulticastAppender named "+ name;
116 LogLog.error(err);
117 throw new IllegalStateException(err);
118 }
119
120 if (layout == null) {
121 layout = new XMLLayout();
122 }
123
124 if (advertiseViaMulticastDNS) {
125 Map properties = new HashMap();
126 properties.put("multicastAddress", remoteHost);
127 zeroConf = new ZeroConfSupport(ZONE, port, getName(), properties);
128 zeroConf.advertise();
129 }
130 connect();
131 super.activateOptions();
132 }
133
134
135
136
137
138
139 public synchronized void close() {
140 if (closed) {
141 return;
142 }
143
144 this.closed = true;
145 if (advertiseViaMulticastDNS) {
146 zeroConf.unadvertise();
147 }
148 cleanUp();
149 }
150
151
152
153
154
155 public void cleanUp() {
156 if (outSocket != null) {
157 try {
158 outSocket.close();
159 } catch (Exception e) {
160 LogLog.error("Could not close outSocket.", e);
161 }
162
163 outSocket = null;
164 }
165 }
166
167 void connect() {
168 if (this.address == null) {
169 return;
170 }
171
172 try {
173
174 cleanUp();
175 outSocket = new MulticastSocket();
176 outSocket.setTimeToLive(timeToLive);
177 } catch (IOException e) {
178 LogLog.error("Error in connect method of MulticastAppender named "+name, e);
179 }
180 }
181
182 public void append(LoggingEvent event) {
183 if (event == null) {
184 return;
185 }
186
187 if(locationInfo) {
188 event.getLocationInformation();
189 }
190
191 if (outSocket != null) {
192 event.setProperty(Constants.HOSTNAME_KEY, hostname);
193
194 if (application != null) {
195 event.setProperty(Constants.APPLICATION_KEY, application);
196 }
197
198 if(locationInfo) {
199 event.getLocationInformation();
200 }
201
202
203 try {
204 StringBuffer buf = new StringBuffer(layout.format(event));
205
206 byte[] payload;
207 if(encoding == null) {
208 payload = buf.toString().getBytes();
209 } else {
210 payload = buf.toString().getBytes(encoding);
211 }
212
213 DatagramPacket dp =
214 new DatagramPacket(payload, payload.length, address, port);
215 outSocket.send(dp);
216 } catch (IOException e) {
217 outSocket = null;
218 LogLog.warn("Detected problem with Multicast connection: " + e);
219 }
220 }
221 }
222
223 InetAddress getAddressByName(String host) {
224 try {
225 return InetAddress.getByName(host);
226 } catch (Exception e) {
227 LogLog.error("Could not find address of [" + host + "].", e);
228 return null;
229 }
230 }
231
232
233
234
235
236 public void setRemoteHost(String host) {
237 remoteHost = host;
238 }
239
240
241
242
243 public String getRemoteHost() {
244 return remoteHost;
245 }
246
247
248
249
250
251
252 public void setLocationInfo(boolean locationInfo) {
253 this.locationInfo = locationInfo;
254 }
255
256
257
258
259 public boolean getLocationInfo() {
260 return locationInfo;
261 }
262
263
264
265
266
267 public void setEncoding(String encoding) {
268 this.encoding = encoding;
269 }
270
271
272
273
274 public String getEncoding() {
275 return encoding;
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 setTimeToLive(int timeToLive) {
297 this.timeToLive = timeToLive;
298 }
299
300
301
302
303 public int getTimeToLive() {
304 return timeToLive;
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
323
324
325 public boolean isActive() {
326
327 return true;
328 }
329
330
331
332
333
334 public boolean requiresLayout() {
335 return true;
336 }
337
338 public boolean isAdvertiseViaMulticastDNS() {
339 return advertiseViaMulticastDNS;
340 }
341
342 public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
343 this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
344 }
345 }