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