package org.jboss.logging;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import org.apache.log4j.LogManager;
import org.apache.log4j.MDC;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.net.SocketNode;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.MissingAttributeException;
public class Log4jSocketServer
extends ServiceMBeanSupport
implements Log4jSocketServerMBean
{
protected int port = -1;
protected int backlog = 50;
protected InetAddress bindAddress;
protected boolean listenerEnabled = true;
protected SocketListenerThread listenerThread;
protected ServerSocket serverSocket;
protected LoggerRepositoryFactory loggerRepositoryFactory;
public Log4jSocketServer()
{
super();
}
public void setPort(final int port)
{
this.port = port;
}
public int getPort()
{
return port;
}
public void setBacklog(final int backlog)
{
this.backlog = backlog;
}
public int getBacklog()
{
return backlog;
}
public void setBindAddress(final InetAddress addr)
{
this.bindAddress = addr;
}
public InetAddress getBindAddress()
{
return bindAddress;
}
public void setListenerEnabled(final boolean enabled)
{
listenerEnabled = enabled;
}
public boolean setListenerEnabled()
{
return listenerEnabled;
}
public void setLoggerRepositoryFactoryType(final Class type)
throws InstantiationException, IllegalAccessException, ClassCastException
{
this.loggerRepositoryFactory = (LoggerRepositoryFactory)type.newInstance();
}
public Class getLoggerRepositoryFactoryType()
{
if (loggerRepositoryFactory == null)
return null;
return loggerRepositoryFactory.getClass();
}
public LoggerRepository getLoggerRepository(final InetAddress addr)
{
return loggerRepositoryFactory.create(addr);
}
protected class SocketListenerThread
extends Thread
{
protected Logger log = Logger.getLogger(SocketListenerThread.class);
protected boolean enabled;
protected boolean shuttingDown;
protected Object lock = new Object();
public SocketListenerThread(final boolean enabled)
{
super("SocketListenerThread");
this.enabled = enabled;
}
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
synchronized (lock)
{
lock.notifyAll();
}
if (log.isDebugEnabled())
{
log.debug("Notified that enabled: " + enabled);
}
}
public void shutdown()
{
enabled = false;
shuttingDown = true;
synchronized (lock)
{
lock.notifyAll();
}
if (log.isDebugEnabled())
{
log.debug("Notified to shutdown");
}
}
public void run()
{
while (!shuttingDown)
{
if (!enabled)
{
try
{
log.debug("Disabled, waiting for notification");
synchronized (lock)
{
lock.wait();
}
}
catch (InterruptedException ignore)
{
}
}
try
{
doRun();
}
catch (Throwable e)
{
log.error("Exception caught from main loop; ignoring", e);
}
}
}
protected void doRun() throws Exception
{
while (enabled)
{
Socket socket = serverSocket.accept();
InetAddress addr = socket.getInetAddress();
log.debug("Connected to client at " + addr);
LoggerRepository repo = getLoggerRepository(addr);
log.debug("Using repository: " + repo);
log.debug("Starting new socket node");
SocketNode node = new SocketNode(socket, repo);
String clientHost = addr.getHostName();
SocketThread thread = new SocketThread(node, clientHost);
thread.start();
log.debug("Socket node started");
}
}
}
static class SocketThread
extends Thread
{
String host;
SocketThread(Runnable target, String host)
{
super(target, host+" LoggingEvent Thread");
this.host = host;
}
public void run()
{
MDC.put("host", host);
super.run();
}
}
public static interface LoggerRepositoryFactory
{
public LoggerRepository create(InetAddress addr);
}
public static class DefaultLoggerRepositoryFactory
implements LoggerRepositoryFactory
{
private LoggerRepository repo;
public LoggerRepository create(final InetAddress addr)
{
if (repo == null)
repo = LogManager.getLoggerRepository();
return repo;
}
}
protected void createService() throws Exception
{
listenerThread = new SocketListenerThread(false);
listenerThread.setDaemon(true);
listenerThread.start();
log.debug("Socket listener thread started");
if (loggerRepositoryFactory == null)
{
log.debug("Using default logger repository factory");
loggerRepositoryFactory = new DefaultLoggerRepositoryFactory();
}
}
protected void startService() throws Exception
{
if (port == -1)
throw new MissingAttributeException("Port");
if (bindAddress == null)
{
serverSocket = new ServerSocket(port, backlog);
}
else
{
serverSocket = new ServerSocket(port, backlog, bindAddress);
}
log.info("Listening on " + serverSocket);
listenerThread.setEnabled(listenerEnabled);
}
protected void stopService() throws Exception
{
listenerThread.setEnabled(false);
}
protected void destroyService() throws Exception
{
listenerThread.shutdown();
listenerThread = null;
serverSocket = null;
}
}