001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.net.server; 018 019import java.io.File; 020import java.io.FileInputStream; 021import java.io.FileNotFoundException; 022import java.io.IOException; 023import java.io.InputStream; 024import java.net.MalformedURLException; 025import java.net.URI; 026import java.net.URL; 027import java.util.Objects; 028 029import org.apache.logging.log4j.LogManager; 030import org.apache.logging.log4j.Logger; 031import org.apache.logging.log4j.core.LogEventListener; 032import org.apache.logging.log4j.core.config.Configuration; 033import org.apache.logging.log4j.core.config.ConfigurationSource; 034import org.apache.logging.log4j.core.config.xml.XmlConfiguration; 035import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory; 036import org.apache.logging.log4j.util.Strings; 037 038/** 039 * Abstract socket server for TCP and UDP implementations. 040 * 041 * @param <T> The kind of input stream read 042 * 043 * TODO Make a LifeCycle 044 */ 045public abstract class AbstractSocketServer<T extends InputStream> extends LogEventListener implements Runnable { 046 047 /** 048 * Factory that creates a Configuration for the server. 049 */ 050 protected static class ServerConfigurationFactory extends XmlConfigurationFactory { 051 052 private final String path; 053 054 public ServerConfigurationFactory(final String path) { 055 this.path = path; 056 } 057 058 @Override 059 public Configuration getConfiguration(final String name, final URI configLocation) { 060 if (Strings.isNotEmpty(path)) { 061 File file = null; 062 ConfigurationSource source = null; 063 try { 064 file = new File(path); 065 final FileInputStream is = new FileInputStream(file); 066 source = new ConfigurationSource(is, file); 067 } catch (final FileNotFoundException ex) { 068 // Ignore this error 069 } 070 if (source == null) { 071 try { 072 final URL url = new URL(path); 073 source = new ConfigurationSource(url.openStream(), url); 074 } catch (final MalformedURLException mue) { 075 // Ignore this error 076 } catch (final IOException ioe) { 077 // Ignore this error 078 } 079 } 080 081 try { 082 if (source != null) { 083 return new XmlConfiguration(source); 084 } 085 } catch (final Exception ex) { 086 // Ignore this error. 087 } 088 System.err.println("Unable to process configuration at " + path + ", using default."); 089 } 090 return super.getConfiguration(name, configLocation); 091 } 092 } 093 094 protected static final int MAX_PORT = 65534; 095 096 private volatile boolean active = true; 097 098 protected final LogEventBridge<T> logEventInput; 099 100 protected final Logger logger; 101 102 /** 103 * Creates a new socket server. 104 * 105 * @param port listen to this port 106 * @param logEventInput Use this input to read log events. 107 */ 108 public AbstractSocketServer(final int port, final LogEventBridge<T> logEventInput) { 109 this.logger = LogManager.getLogger(this.getClass().getName() + '.' + port); 110 this.logEventInput = Objects.requireNonNull(logEventInput, "LogEventInput"); 111 } 112 113 protected boolean isActive() { 114 return this.active; 115 } 116 117 protected void setActive(final boolean isActive) { 118 this.active = isActive; 119 } 120 121 /** 122 * Start this server in a new thread. 123 * 124 * @return the new thread that running this server. 125 */ 126 public Thread startNewThread() { 127 final Thread thread = new Thread(this); 128 thread.start(); 129 return thread; 130 } 131 132}