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.ServerSocket;
22 import java.net.Socket;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Enumeration;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Vector;
31
32 import org.apache.log4j.plugins.Pauseable;
33 import org.apache.log4j.plugins.Plugin;
34 import org.apache.log4j.plugins.Receiver;
35 import org.apache.log4j.spi.LoggerRepository;
36 import org.apache.log4j.spi.LoggingEvent;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class SocketReceiver extends Receiver implements Runnable, PortBased,
53 Pauseable {
54
55
56
57 private Map socketMap = new HashMap();
58
59
60
61 private boolean paused;
62
63
64
65 private Thread rThread;
66
67
68
69 protected int port;
70
71
72
73 private ServerSocket serverSocket;
74
75
76
77 private Vector socketList = new Vector();
78
79
80
81
82 public static final String ZONE = "_log4j_obj_tcpaccept_receiver.local.";
83
84
85
86
87 private SocketNodeEventListener listener = null;
88
89
90
91 private List listenerList = Collections.synchronizedList(new ArrayList());
92 private boolean advertiseViaMulticastDNS;
93 private ZeroConfSupport zeroConf;
94
95
96
97
98 public SocketReceiver() {
99 super();
100 }
101
102
103
104
105
106 public SocketReceiver(final int p) {
107 super();
108 port = p;
109 }
110
111
112
113
114
115
116 public SocketReceiver(final int p, final LoggerRepository repo) {
117 super();
118 this.port = p;
119 repository = repo;
120 }
121
122
123 public int getPort() {
124 return port;
125 }
126
127
128 public void setPort(final int p) {
129 port = p;
130 }
131
132
133
134
135
136
137
138
139
140
141 public boolean isEquivalent(final Plugin testPlugin) {
142 if ((testPlugin != null) && testPlugin instanceof SocketReceiver) {
143 SocketReceiver sReceiver = (SocketReceiver) testPlugin;
144
145 return (port == sReceiver.getPort() && super.isEquivalent(testPlugin));
146 }
147
148 return false;
149 }
150
151
152
153 public void activateOptions() {
154 if (!isActive()) {
155
156 rThread = new Thread(this);
157 rThread.setDaemon(true);
158 rThread.start();
159 if (advertiseViaMulticastDNS) {
160 zeroConf = new ZeroConfSupport(ZONE, port, getName());
161 zeroConf.advertise();
162 }
163
164 active = true;
165 }
166 }
167
168
169
170
171
172 public synchronized void shutdown() {
173 getLogger().debug(getName() + " received shutdown request");
174
175
176 active = false;
177
178 if (rThread != null) {
179 rThread.interrupt();
180 rThread = null;
181 }
182 if (advertiseViaMulticastDNS) {
183 zeroConf.unadvertise();
184 }
185
186 doShutdown();
187 }
188
189
190
191
192
193 private synchronized void doShutdown() {
194 active = false;
195
196 getLogger().debug(getName() + " doShutdown called");
197
198
199 closeServerSocket();
200
201
202 closeAllAcceptedSockets();
203 }
204
205
206
207
208 private void closeServerSocket() {
209 getLogger().debug("{} closing server socket", getName());
210
211 try {
212 if (serverSocket != null) {
213 serverSocket.close();
214 }
215 } catch (Exception e) {
216
217 }
218
219 serverSocket = null;
220 }
221
222
223
224
225 private synchronized void closeAllAcceptedSockets() {
226 for (int x = 0; x < socketList.size(); x++) {
227 try {
228 ((Socket) socketList.get(x)).close();
229 } catch (Exception e) {
230
231 }
232 }
233
234
235 socketMap.clear();
236 socketList.clear();
237 }
238
239
240
241
242
243 protected synchronized void setActive(final boolean b) {
244 active = b;
245 }
246
247 public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
248 this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
249 }
250
251 public boolean isAdvertiseViaMulticastDNS() {
252 return advertiseViaMulticastDNS;
253 }
254
255
256
257 public void run() {
258
259
260
261 closeServerSocket();
262 closeAllAcceptedSockets();
263
264
265 try {
266 serverSocket = new ServerSocket(port);
267 } catch (Exception e) {
268 getLogger().error(
269 "error starting SocketReceiver (" + this.getName()
270 + "), receiver did not start", e);
271 active = false;
272
273 return;
274 }
275
276 Socket socket = null;
277
278 try {
279 getLogger().debug("in run-about to enter while not interrupted loop");
280
281 active = true;
282
283 while (!rThread.isInterrupted()) {
284
285 if (socket != null) {
286 getLogger().debug(
287 "socket not null - creating and starting socketnode");
288 socketList.add(socket);
289
290 SocketNode13 node = new SocketNode13(socket, this);
291 synchronized (listenerList) {
292 for (Iterator iter = listenerList.iterator();
293 iter.hasNext();) {
294 SocketNodeEventListener l =
295 (SocketNodeEventListener) iter.next();
296 node.addSocketNodeEventListener(l);
297 }
298 }
299 socketMap.put(socket, node);
300 new Thread(node).start();
301 socket = null;
302 }
303
304 getLogger().debug("waiting to accept socket");
305
306
307 socket = serverSocket.accept();
308 getLogger().debug("accepted socket");
309 }
310 } catch (Exception e) {
311 getLogger().warn(
312 "exception while watching socket server in SocketReceiver ("
313 + this.getName() + "), stopping");
314 }
315
316 getLogger().debug("{} has exited the not interrupted loop", getName());
317
318
319
320 if (socket != null) {
321 try {
322 socket.close();
323 } catch (IOException e1) {
324 getLogger().warn("socket exception caught - socket closed");
325 }
326 }
327
328 getLogger().debug("{} is exiting main run loop", getName());
329 }
330
331
332
333
334
335
336
337 public Vector getConnectedSocketDetails() {
338 Vector details = new Vector(socketList.size());
339
340 for (Enumeration enumeration = socketList.elements();
341 enumeration.hasMoreElements();
342 ) {
343 Socket socket = (Socket) enumeration.nextElement();
344 details.add(
345 new SocketDetail(socket, (SocketNode13) socketMap.get(socket)));
346 }
347
348 return details;
349 }
350
351
352
353
354
355
356
357
358 public SocketNodeEventListener getListener() {
359 return listener;
360 }
361
362
363
364
365
366
367 public void addSocketNodeEventListener(
368 final SocketNodeEventListener l) {
369 listenerList.add(l);
370 }
371
372
373
374
375
376
377
378
379 public void removeSocketNodeEventListener(
380 final SocketNodeEventListener l) {
381 listenerList.remove(l);
382 }
383
384
385
386
387
388
389
390
391
392
393
394
395 public void setListener(final SocketNodeEventListener l) {
396 removeSocketNodeEventListener(l);
397 addSocketNodeEventListener(l);
398 this.listener = l;
399 }
400
401
402 public boolean isPaused() {
403 return paused;
404 }
405
406
407 public void setPaused(final boolean b) {
408 paused = b;
409 }
410
411
412
413
414 private static final class SocketDetail implements AddressBased, PortBased,
415 Pauseable {
416
417
418
419 private String address;
420
421
422
423 private int port;
424
425
426
427 private SocketNode13 socketNode;
428
429
430
431
432
433
434 private SocketDetail(final Socket socket,
435 final SocketNode13 node) {
436 super();
437 this.address = socket.getInetAddress().getHostName();
438 this.port = socket.getPort();
439 this.socketNode = node;
440 }
441
442
443 public String getAddress() {
444 return address;
445 }
446
447
448 public int getPort() {
449 return port;
450 }
451
452
453 public String getName() {
454 return "Socket";
455 }
456
457
458 public boolean isActive() {
459 return true;
460 }
461
462
463 public boolean isPaused() {
464 return socketNode.isPaused();
465 }
466
467
468 public void setPaused(final boolean b) {
469 socketNode.setPaused(b);
470 }
471 }
472
473 public void doPost(final LoggingEvent event) {
474 if (!isPaused()) {
475 super.doPost(event);
476 }
477 }
478
479 }