blob: f6a06d2fe42d6eeb37d470263e99af8aab86677c [file] [log] [blame]
package org.apache.log4j.net;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;
import org.apache.log4j.Level;
/**
* A sub-class of SocketHubAppender that broadcasts its configuration via Zeroconf.
*
* This allows Zeroconf aware applications such as Chainsaw to be able to detect them, and automatically configure
* themselves to be able to connect to them.
*
* @author psmith
*
*/
public class ZeroConfSocketHubAppender extends SocketHubAppender {
public static final String DEFAULT_ZEROCONF_ZONE="_log4j._tcp.local.";
private String zeroConfZone = DEFAULT_ZEROCONF_ZONE;
private Object logger;
private Method logInfoMethod;
private Method logErrorMethod;
public ZeroConfSocketHubAppender() {
setName("SocketHubAppender");
try {
Method getLoggerMethod = this.getClass().getMethod("getLogger", new Class[0]);
logger = getLoggerMethod.invoke(this, new Object[0]);
logInfoMethod = logger.getClass().getMethod("info", new Class[] {Object.class});
logErrorMethod = logger.getClass().getMethod("error", new Class[] {Object.class});
}catch(Exception e) {
// we're not in log4j1.3 land
}
}
public void activateOptions() {
super.activateOptions();
try {
JmDNS jmDNS = Zeroconf4log4j.getInstance();
ServiceInfo info = buildServiceInfo();
logWithlog4j12Compatibility(Level.INFO,"Registering this SocketHubAppender as :" + info);
jmDNS.registerService(info);
} catch (IOException e) {
logWithlog4j12Compatibility(Level.ERROR,"Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode");
}
}
private ServiceInfo buildServiceInfo() {
return new ServiceInfo(zeroConfZone, getName(), getPort(), "SocketHubAppender on port " + getPort() );
}
private void logWithlog4j12Compatibility(Level level, String message) {
if(logger!=null && logInfoMethod!=null & logErrorMethod!=null) {
try {
switch (level.toInt()) {
case Level.INFO_INT:
logInfoMethod.invoke(logger, new Object[] { message });
break;
case Level.ERROR_INT:
logInfoMethod.invoke(logger, new Object[] { message });
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Returns the ZeroConf domain that will be used to register this 'device'.
*
* @return String ZeroConf zone
*/
public String getZeroConfZone() {
return zeroConfZone;
}
/**
* Sets the ZeroConf zone to register this device under, BE CAREFUL with this value
* as ZeroConf has some weird naming conventions, it should start with an "_" and end in a ".",
* if you're not sure about this value might I suggest that you leave it at the default value
* which is specified in {@link #DEFAULT_ZEROCONF_ZONE }.
*
* This method does NO(0, zero, pun not intended) checks on this value.
*
* @param zeroConfZone
*/
public void setZeroConfZone(String zeroConfZone) {
// TODO work out a sane checking mechanism that verifies the value is a correct ZeroConf zone
this.zeroConfZone = zeroConfZone;
}
public synchronized void close() {
super.close();
try {
JmDNS jmDNS = Zeroconf4log4j.getInstance();
ServiceInfo info = buildServiceInfo();
logWithlog4j12Compatibility(Level.INFO,"Deregistering this SocketHubAppender (" + info + ")");
jmDNS.unregisterService(info);
} catch (Exception e) {
logWithlog4j12Compatibility(Level.ERROR,"Failed to instantiate JmDNS to broadcast via ZeroConf, will now operate in simple SocketHubAppender mode");
}
}
}