View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.net.server;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileNotFoundException;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.net.MalformedURLException;
25  import java.net.URI;
26  import java.net.URL;
27  import java.util.Objects;
28  
29  import org.apache.logging.log4j.LogManager;
30  import org.apache.logging.log4j.Logger;
31  import org.apache.logging.log4j.core.LogEventListener;
32  import org.apache.logging.log4j.core.config.Configuration;
33  import org.apache.logging.log4j.core.config.ConfigurationSource;
34  import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
35  import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory;
36  import org.apache.logging.log4j.core.util.Log4jThread;
37  import org.apache.logging.log4j.util.Strings;
38  
39  /**
40   * Abstract socket server for TCP and UDP implementations.
41   * 
42   * @param <T> The kind of input stream read
43   * 
44   * TODO Make a LifeCycle
45   */
46  public abstract class AbstractSocketServer<T extends InputStream> extends LogEventListener implements Runnable {
47  
48      /**
49       * Factory that creates a Configuration for the server.
50       */
51      protected static class ServerConfigurationFactory extends XmlConfigurationFactory {
52  
53          private final String path;
54  
55          public ServerConfigurationFactory(final String path) {
56              this.path = path;
57          }
58  
59          @Override
60          public Configuration getConfiguration(final String name, final URI configLocation) {
61              if (Strings.isNotEmpty(path)) {
62                  File file = null;
63                  ConfigurationSource source = null;
64                  try {
65                      file = new File(path);
66                      final FileInputStream is = new FileInputStream(file);
67                      source = new ConfigurationSource(is, file);
68                  } catch (final FileNotFoundException ex) {
69                      // Ignore this error
70                  }
71                  if (source == null) {
72                      try {
73                          final URL url = new URL(path);
74                          source = new ConfigurationSource(url.openStream(), url);
75                      } catch (final MalformedURLException mue) {
76                          // Ignore this error
77                      } catch (final IOException ioe) {
78                          // Ignore this error
79                      }
80                  }
81  
82                  try {
83                      if (source != null) {
84                          return new XmlConfiguration(source);
85                      }
86                  } catch (final Exception ex) {
87                      // Ignore this error.
88                  }
89                  System.err.println("Unable to process configuration at " + path + ", using default.");
90              }
91              return super.getConfiguration(name, configLocation);
92          }
93      }
94  
95      protected static final int MAX_PORT = 65534;
96  
97      private volatile boolean active = true;
98  
99      protected final LogEventBridge<T> logEventInput;
100 
101     protected final Logger logger;
102 
103     /**
104      * Creates a new socket server.
105      * 
106      * @param port listen to this port
107      * @param logEventInput Use this input to read log events.
108      */
109     public AbstractSocketServer(final int port, final LogEventBridge<T> logEventInput) {
110         this.logger = LogManager.getLogger(this.getClass().getName() + '.' + port);
111         this.logEventInput = Objects.requireNonNull(logEventInput, "LogEventInput");
112     }
113 
114     protected boolean isActive() {
115         return this.active;
116     }
117 
118     protected void setActive(final boolean isActive) {
119         this.active = isActive;
120     }
121 
122     /**
123      * Start this server in a new thread.
124      * 
125      * @return the new thread that running this server.
126      */
127     public Thread startNewThread() {
128         final Thread thread = new Log4jThread(this);
129         thread.start();
130         return thread;
131     }
132 
133 }