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 }