You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jd...@apache.org on 2003/09/01 22:53:33 UTC
cvs commit: incubator-geronimo/modules/core/src/java/org/apache/geronimo/core/logging/log4j Log4jSocketServer.java
jdillon 2003/09/01 13:53:33
Added: modules/core/src/java/org/apache/geronimo/core/logging/log4j
Log4jSocketServer.java
Log:
o Log4j SocketServer as an MBean for client repo isolation
Revision Changes Path
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/core/logging/log4j/Log4jSocketServer.java
Index: Log4jSocketServer.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.core.logging.log4j;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.net.SocketNode;
import org.apache.geronimo.management.AbstractManagedObject;
/**
* A Log4j SocketServer service. Listens for client connections on the
* specified port and creates a new thread and SocketNode to process the
* incoming client log messages.
*
* <p>
* The LoggerRepository can be changed based on the clients address
* by using a custom LoggerRepositoryFactory. The default factory
* will simply return the current repository.
*
* @jmx:mbean
* extends="org.apache.geronimo.management.StateManageable,org.apache.geronimo.management.ManagedObject"
*
* @version $Revision: 1.1 $ $Date: 2003/09/01 20:53:33 $
*/
public class Log4jSocketServer
extends AbstractManagedObject
implements Log4jSocketServerMBean
{
/** The port number where the server listens. */
protected int port = -1;
/** The listen backlog count. */
protected int backlog = 50;
/** The address to bind to. */
protected InetAddress bindAddress;
/** True if the socket listener is enabled. */
protected boolean listenerEnabled = true;
/** The socket listener thread. */
protected SocketListenerThread listenerThread;
/** The server socket which the listener listens on. */
protected ServerSocket serverSocket;
/** The factory to create LoggerRepository's for client connections. */
protected LoggerRepositoryFactory loggerRepositoryFactory;
/**
* @jmx:managed-constructor
*/
public Log4jSocketServer()
{
super();
}
/**
* @jmx:managed-attribute
*/
public void setPort(final int port)
{
this.port = port;
}
/**
* @jmx:managed-attribute
*/
public int getPort()
{
return port;
}
/**
* @jmx:managed-attribute
*/
public void setBacklog(final int backlog)
{
this.backlog = backlog;
}
/**
* @jmx:managed-attribute
*/
public int getBacklog()
{
return backlog;
}
/**
* @jmx:managed-attribute
*/
public void setBindAddress(final InetAddress addr)
{
this.bindAddress = addr;
}
/**
* @jmx:managed-attribute
*/
public InetAddress getBindAddress()
{
return bindAddress;
}
/**
* @jmx:managed-attribute
*/
public void setListenerEnabled(final boolean enabled)
{
listenerEnabled = enabled;
}
/**
* @jmx:managed-attribute
*/
public boolean setListenerEnabled()
{
return listenerEnabled;
}
/**
* @jmx:managed-attribute
*/
public void setLoggerRepositoryFactoryType(final Class type)
throws InstantiationException, IllegalAccessException, ClassCastException
{
this.loggerRepositoryFactory = (LoggerRepositoryFactory)type.newInstance();
}
/**
* @jmx:managed-attribute
*/
public Class getLoggerRepositoryFactoryType()
{
if (loggerRepositoryFactory == null) {
return null;
}
return loggerRepositoryFactory.getClass();
}
/**
* @jmx:managed-operation
*/
public LoggerRepository getLoggerRepository(final InetAddress addr)
{
return loggerRepositoryFactory.create(addr);
}
///////////////////////////////////////////////////////////////////////////
// Socket Listener //
///////////////////////////////////////////////////////////////////////////
protected class SocketListenerThread
extends Thread
{
protected Log log = LogFactory.getLog(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 (Exception e) {
log.error("Exception caught from main loop; ignoring", e);
}
}
}
protected void doRun() throws Exception
{
while (enabled) {
boolean debug = log.isDebugEnabled();
Socket socket = serverSocket.accept();
InetAddress addr = socket.getInetAddress();
if (debug) {
log.debug("Connected to client: " + addr);
}
LoggerRepository repo = getLoggerRepository(addr);
if (debug) {
log.debug("Using repository: " + repo);
}
//
// jason: may want to expose socket node as an MBean for management
//
log.debug("Starting new socket node");
SocketNode node = new SocketNode(socket, repo);
Thread thread = new Thread(node);
thread.start();
log.debug("Socket node started");
}
}
}
///////////////////////////////////////////////////////////////////////////
// LoggerRepositoryFactory //
///////////////////////////////////////////////////////////////////////////
public static interface LoggerRepositoryFactory
{
public LoggerRepository create(InetAddress addr);
}
/**
* A simple LoggerRepository factory which simply returns
* the current repository from the LogManager.
*/
public static class DefaultLoggerRepositoryFactory
implements LoggerRepositoryFactory
{
private LoggerRepository repo;
public LoggerRepository create(final InetAddress addr)
{
if (repo == null) {
repo = LogManager.getLoggerRepository();
}
return repo;
}
}
///////////////////////////////////////////////////////////////////////////
// AbstractManagedObject Overrides //
///////////////////////////////////////////////////////////////////////////
protected void doStart() 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();
}
// create a new server socket to handle port number changes
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 doStop() throws Exception
{
listenerThread.shutdown();
listenerThread = null;
serverSocket = null;
}
}