1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.net;
18
19 import java.io.IOException;
20 import java.lang.reflect.Method;
21
22 import javax.jmdns.JmDNS;
23 import javax.jmdns.ServiceInfo;
24
25 import org.apache.log4j.Level;
26
27
28 /***
29 * A sub-class of SocketHubAppender that broadcasts its configuration via Zeroconf.
30 *
31 * This allows Zeroconf aware applications such as Chainsaw to be able to detect them, and automatically configure
32 * themselves to be able to connect to them.
33 *
34 * @author psmith
35 *
36 */
37 public class ZeroConfSocketHubAppender extends SocketHubAppender {
38
39 public static final String DEFAULT_ZEROCONF_ZONE="_log4j._tcp.local.";
40 private String zeroConfZone = DEFAULT_ZEROCONF_ZONE;
41
42 private Object logger;
43 private Method logInfoMethod;
44 private Method logErrorMethod;
45
46 public ZeroConfSocketHubAppender() {
47 setName("SocketHubAppender");
48 try {
49 Method getLoggerMethod = this.getClass().getMethod("getLogger", new Class[0]);
50 logger = getLoggerMethod.invoke(this, new Object[0]);
51 logInfoMethod = logger.getClass().getMethod("info", new Class[] {Object.class});
52 logErrorMethod = logger.getClass().getMethod("error", new Class[] {Object.class});
53 }catch(Exception e) {
54
55 }
56 }
57 public void activateOptions() {
58 super.activateOptions();
59
60 try {
61 JmDNS jmDNS = Zeroconf4log4j.getInstance();
62 ServiceInfo info = buildServiceInfo();
63 logWithlog4j12Compatibility(Level.INFO,"Registering this SocketHubAppender as :" + info);
64 jmDNS.registerService(info);
65 } catch (IOException e) {
66 logWithlog4j12Compatibility(Level.ERROR,"Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode");
67 }
68 }
69 private ServiceInfo buildServiceInfo() {
70 return new ServiceInfo(zeroConfZone, getName(), getPort(), "SocketHubAppender on port " + getPort() );
71 }
72
73 private void logWithlog4j12Compatibility(Level level, String message) {
74 if(logger!=null && logInfoMethod!=null & logErrorMethod!=null) {
75 try {
76 switch (level.toInt()) {
77 case Level.INFO_INT:
78 logInfoMethod.invoke(logger, new Object[] { message });
79 break;
80 case Level.ERROR_INT:
81 logInfoMethod.invoke(logger, new Object[] { message });
82 break;
83 }
84 } catch (Exception e) {
85 e.printStackTrace();
86 }
87 }
88 }
89
90 /***
91 * Returns the ZeroConf domain that will be used to register this 'device'.
92 *
93 * @return String ZeroConf zone
94 */
95 public String getZeroConfZone() {
96 return zeroConfZone;
97 }
98
99
100 /***
101 * Sets the ZeroConf zone to register this device under, BE CAREFUL with this value
102 * as ZeroConf has some weird naming conventions, it should start with an "_" and end in a ".",
103 * if you're not sure about this value might I suggest that you leave it at the default value
104 * which is specified in {@link #DEFAULT_ZEROCONF_ZONE }.
105 *
106 * This method does NO(0, zero, pun not intended) checks on this value.
107 *
108 * @param zeroConfZone
109 */
110 public void setZeroConfZone(String zeroConfZone) {
111
112 this.zeroConfZone = zeroConfZone;
113 }
114 public synchronized void close() {
115 super.close();
116 try {
117 JmDNS jmDNS = Zeroconf4log4j.getInstance();
118 ServiceInfo info = buildServiceInfo();
119 logWithlog4j12Compatibility(Level.INFO,"Deregistering this SocketHubAppender (" + info + ")");
120 jmDNS.unregisterService(info);
121 } catch (Exception e) {
122 logWithlog4j12Compatibility(Level.ERROR,"Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode");
123 }
124 }
125
126
127 }