001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.access.net;
015
016import java.io.BufferedInputStream;
017import java.io.IOException;
018import java.net.Socket;
019
020import ch.qos.logback.access.spi.AccessContext;
021import ch.qos.logback.access.spi.IAccessEvent;
022import ch.qos.logback.core.spi.FilterReply;
023
024// Contributors: Moses Hohman <mmhohman@rainbow.uchicago.edu>
025
026/**
027 * Read {@link IAccessEvent} objects sent from a remote client using Sockets
028 * (TCP). These logging events are logged according to local policy, as if they
029 * were generated locally.
030 * 
031 * <p>
032 * For example, the socket node might decide to log events to a local file and
033 * also resent them to a second socket node.
034 * 
035 * @author Ceki G&uuml;lc&uuml;
036 * @author S&eacute;bastien Pennec
037 * 
038 * @since 0.8.4
039 */
040public class SocketNode implements Runnable {
041
042    Socket socket;
043    AccessContext context;
044    HardenedAccessEventInputStream hardenedOIS;
045
046    public SocketNode(Socket socket, AccessContext context) {
047        this.socket = socket;
048        this.context = context;
049        try {
050            hardenedOIS = new HardenedAccessEventInputStream(new BufferedInputStream(socket.getInputStream()));
051        } catch (Exception e) {
052            System.out.println("Could not open HardenedObjectInputStream to " + socket + e);
053        }
054    }
055    
056    @Override
057    public void run() {
058        IAccessEvent event;
059
060        try {
061            while (true) {
062                // read an event from the wire
063                event = (IAccessEvent) hardenedOIS.readObject();
064                // check that the event should be logged
065                if (context.getFilterChainDecision(event) == FilterReply.DENY) {
066                    break;
067                }
068                // send it to the appenders
069                context.callAppenders(event);
070            }
071        } catch (java.io.EOFException e) {
072            System.out.println("Caught java.io.EOFException closing connection.");
073        } catch (java.net.SocketException e) {
074            System.out.println("Caught java.net.SocketException closing connection.");
075        } catch (IOException e) {
076            System.out.println("Caught java.io.IOException: " + e);
077            System.out.println("Closing connection.");
078        } catch (Exception e) {
079            System.out.println("Unexpected exception. Closing connection." + e);
080        }
081
082        try {
083            hardenedOIS.close();
084        } catch (Exception e) {
085            System.out.println("Could not close connection." + e);
086        }
087    }
088}