You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2017/03/17 15:05:15 UTC

[5/6] logging-log4j2 git commit: Merge branch 'master' into log4j-server

Merge branch 'master' into log4j-server


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/b77b7d03
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b77b7d03
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b77b7d03

Branch: refs/heads/LOG4J2-1851
Commit: b77b7d039653bc1675e7f9a1376cedf9e4fd16c5
Parents: f515fa3 c822338
Author: Mikael St�ldal <mi...@magine.com>
Authored: Fri Mar 17 14:59:48 2017 +0100
Committer: Mikael St�ldal <mi...@magine.com>
Committed: Fri Mar 17 16:03:24 2017 +0100

----------------------------------------------------------------------
 .../core/util/datetime/FixedDateFormat.java     |  32 +-
 .../core/util/datetime/FixedDateFormatTest.java | 177 ++++++++++-
 log4j-server/pom.xml                            |  25 +-
 .../core/net/mom/jms/AbstractJmsReceiver.java   |  48 ---
 .../core/net/mom/jms/JmsQueueReceiver.java      |  46 ---
 .../core/net/mom/jms/JmsTopicReceiver.java      |  46 ---
 .../log4j/core/net/mom/jms/package-info.java    |  26 --
 .../core/net/server/AbstractLogEventBridge.java |  44 ---
 .../core/net/server/AbstractSocketServer.java   | 209 ------------
 .../net/server/InputStreamLogEventBridge.java   | 103 ------
 .../log4j/core/net/server/JmsServer.java        | 148 ---------
 .../server/JsonInputStreamLogEventBridge.java   |  90 ------
 .../log4j/core/net/server/LogEventBridge.java   |  57 ----
 .../server/ObjectInputStreamLogEventBridge.java |  45 ---
 .../core/net/server/SecureTcpSocketServer.java  |  37 ---
 .../log4j/core/net/server/TcpSocketServer.java  | 314 -------------------
 .../log4j/core/net/server/UdpSocketServer.java  | 169 ----------
 .../server/XmlInputStreamLogEventBridge.java    |  54 ----
 .../log4j/core/net/server/package-info.java     |  24 --
 .../log4j/server/AbstractLogEventBridge.java    |  44 +++
 .../log4j/server/AbstractSocketServer.java      | 209 ++++++++++++
 .../log4j/server/InputStreamLogEventBridge.java | 103 ++++++
 .../apache/logging/log4j/server/JmsServer.java  | 148 +++++++++
 .../server/JsonInputStreamLogEventBridge.java   |  90 ++++++
 .../logging/log4j/server/LogEventBridge.java    |  57 ++++
 .../server/ObjectInputStreamLogEventBridge.java |  45 +++
 .../log4j/server/SecureTcpSocketServer.java     |  37 +++
 .../logging/log4j/server/TcpSocketServer.java   | 314 +++++++++++++++++++
 .../logging/log4j/server/UdpSocketServer.java   | 169 ++++++++++
 .../server/XmlInputStreamLogEventBridge.java    |  54 ++++
 .../server/mom/jms/AbstractJmsReceiver.java     |  48 +++
 .../log4j/server/mom/jms/JmsQueueReceiver.java  |  46 +++
 .../log4j/server/mom/jms/JmsTopicReceiver.java  |  46 +++
 .../log4j/server/mom/jms/package-info.java      |  26 ++
 .../logging/log4j/server/package-info.java      |  24 ++
 log4j-server/src/site/markdown/index.md         |   7 +-
 .../net/server/AbstractSocketServerTest.java    | 237 --------------
 .../core/net/server/SslXmlSocketServerTest.java | 104 ------
 .../net/server/TcpJsonSocketServerTest.java     |  62 ----
 .../server/TcpSerializedSocketServerTest.java   |  63 ----
 .../core/net/server/TcpXmlSocketServerTest.java |  65 ----
 .../log4j/core/net/server/ThreadIdFilter.java   |  40 ---
 .../log4j/core/net/server/ThreadNameFilter.java |  39 ---
 .../core/net/server/ThreadPriorityFilter.java   |  40 ---
 .../net/server/UdpJsonSocketServerTest.java     |  58 ----
 .../server/UdpSerializedSocketServerTest.java   |  60 ----
 .../core/net/server/UdpXmlSocketServerTest.java |  61 ----
 .../log4j/server/AbstractSocketServerTest.java  | 237 ++++++++++++++
 .../log4j/server/SslXmlSocketServerTest.java    | 104 ++++++
 .../log4j/server/TcpJsonSocketServerTest.java   |  62 ++++
 .../server/TcpSerializedSocketServerTest.java   |  63 ++++
 .../log4j/server/TcpXmlSocketServerTest.java    |  65 ++++
 .../logging/log4j/server/ThreadIdFilter.java    |  40 +++
 .../logging/log4j/server/ThreadNameFilter.java  |  39 +++
 .../log4j/server/ThreadPriorityFilter.java      |  40 +++
 .../log4j/server/UdpJsonSocketServerTest.java   |  58 ++++
 .../server/UdpSerializedSocketServerTest.java   |  60 ++++
 .../log4j/server/UdpXmlSocketServerTest.java    |  61 ++++
 .../core/net/ssl/client.log4j2-keystore.jks     | Bin 0 -> 6829 bytes
 .../logging/log4j/core/net/ssl/truststore.jks   | Bin 0 -> 1487 bytes
 src/changes/changes.xml                         |   3 +
 61 files changed, 2516 insertions(+), 2306 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/pom.xml
----------------------------------------------------------------------
diff --cc log4j-server/pom.xml
index 2833871,0000000..3a370b4
mode 100644,000000..100644
--- a/log4j-server/pom.xml
+++ b/log4j-server/pom.xml
@@@ -1,197 -1,0 +1,220 @@@
 +<?xml version="1.0" encoding="UTF-8"?>
 +<!--
 +  ~ Licensed to the Apache Software Foundation (ASF) under one or more
 +  ~ contributor license agreements.  See the NOTICE file distributed with
 +  ~ this work for additional information regarding copyright ownership.
 +  ~ The ASF licenses this file to You under the Apache License, Version 2.0
 +  ~ (the "License"); you may not use this file except in compliance with
 +  ~ the License.  You may obtain a copy of the License at
 +  ~
 +  ~     http://www.apache.org/licenses/LICENSE-2.0
 +  ~
 +  ~ Unless required by applicable law or agreed to in writing, software
 +  ~ distributed under the License is distributed on an "AS IS" BASIS,
 +  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +  ~ See the License for the specific language governing permissions and
 +  ~ limitations under the License.
 +  -->
 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 +  <modelVersion>4.0.0</modelVersion>
 +  <parent>
 +    <groupId>org.apache.logging.log4j</groupId>
 +    <artifactId>log4j</artifactId>
 +    <version>2.8.2-SNAPSHOT</version>
 +    <relativePath>../</relativePath>
 +  </parent>
 +  <artifactId>log4j-server</artifactId>
 +  <packaging>jar</packaging>
 +  <name>Apache Log4j Server components</name>
 +  <description>The Apache Log4j server components</description>
 +  <properties>
 +    <log4jParentDir>${basedir}/..</log4jParentDir>
 +    <projectDir>/log4j-server</projectDir>
 +  </properties>
 +  <dependencies>
 +    <dependency>
 +      <groupId>org.apache.logging.log4j</groupId>
 +      <artifactId>log4j-api</artifactId>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.apache.logging.log4j</groupId>
 +      <artifactId>log4j-core</artifactId>
 +    </dependency>
-     <!-- Command line for TCP and UDP servers -->
++    <!-- Command line parsing -->
 +    <dependency>
 +      <groupId>com.beust</groupId>
 +      <artifactId>jcommander</artifactId>
 +    </dependency>
++    <!-- Used for JMS server (needs an implementation of course) -->
++    <dependency>
++      <groupId>org.jboss.spec.javax.jms</groupId>
++      <artifactId>jboss-jms-api_1.1_spec</artifactId>
++      <scope>provided</scope>
++      <optional>true</optional>
++    </dependency>
++    <!-- Required for JSON support -->
++    <dependency>
++      <groupId>com.fasterxml.jackson.core</groupId>
++      <artifactId>jackson-databind</artifactId>
++    </dependency>
++    <!-- Required for XML support -->
++    <dependency>
++      <groupId>com.fasterxml.jackson.dataformat</groupId>
++      <artifactId>jackson-dataformat-xml</artifactId>
++    </dependency>
++    <!-- POM for jackson-dataformat-xml 2.8.3 depends on woodstox-core 5.0.2 -->
++    <dependency>
++      <groupId>com.fasterxml.woodstox</groupId>
++      <artifactId>woodstox-core</artifactId>
++      <version>5.0.2</version>
++    </dependency>
 +
 +    <!-- TEST DEPENDENCIES -->
 +
 +    <!-- Pull in useful test classes from API -->
 +    <dependency>
 +      <groupId>org.apache.logging.log4j</groupId>
 +      <artifactId>log4j-core</artifactId>
 +      <type>test-jar</type>
 +      <scope>test</scope>
 +    </dependency>
 +    <dependency>
 +      <groupId>junit</groupId>
 +      <artifactId>junit</artifactId>
 +      <scope>test</scope>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.hamcrest</groupId>
 +      <artifactId>hamcrest-all</artifactId>
 +      <scope>test</scope>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.mockito</groupId>
 +      <artifactId>mockito-core</artifactId>
 +      <scope>test</scope>
 +    </dependency>
 +  </dependencies>
 +  <build>
 +    <plugins>
 +      <!-- Include the standard NOTICE and LICENSE -->
 +      <plugin>
 +        <groupId>org.apache.maven.plugins</groupId>
 +        <artifactId>maven-remote-resources-plugin</artifactId>
 +        <executions>
 +          <execution>
 +            <goals>
 +              <goal>process</goal>
 +            </goals>
 +            <configuration>
 +              <skip>false</skip>
 +            </configuration>
 +          </execution>
 +        </executions>
 +      </plugin>
 +      <plugin>
 +        <groupId>org.apache.felix</groupId>
 +        <artifactId>maven-bundle-plugin</artifactId>
 +        <configuration>
 +          <instructions>
 +            <Export-Package>org.apache.logging.log4j.core.net.*</Export-Package>
 +          </instructions>
 +        </configuration>
 +      </plugin>
 +    </plugins>
 +  </build>
 +  <reporting>
 +    <plugins>
 +      <plugin>
 +        <groupId>org.apache.maven.plugins</groupId>
 +        <artifactId>maven-changes-plugin</artifactId>
 +        <version>${changes.plugin.version}</version>
 +        <reportSets>
 +          <reportSet>
 +            <reports>
 +              <report>changes-report</report>
 +            </reports>
 +          </reportSet>
 +        </reportSets>
 +        <configuration>
 +          <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
 +          <useJql>true</useJql>
 +        </configuration>
 +      </plugin>
 +      <plugin>
 +        <groupId>org.apache.maven.plugins</groupId>
 +        <artifactId>maven-checkstyle-plugin</artifactId>
 +        <version>${checkstyle.plugin.version}</version>
 +        <configuration>
 +          <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
 +          <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
 +          <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
 +          <enableRulesSummary>false</enableRulesSummary>
 +          <propertyExpansion>basedir=${basedir}</propertyExpansion>
 +          <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
 +        </configuration>
 +      </plugin>
 +      <plugin>
 +        <groupId>org.apache.maven.plugins</groupId>
 +        <artifactId>maven-javadoc-plugin</artifactId>
 +        <version>${javadoc.plugin.version}</version>
 +        <configuration>
 +          <bottom><![CDATA[<p align="center">Copyright &#169; {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
 +            Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
 +            and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
 +          <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
 +               project -->
 +          <detectOfflineLinks>false</detectOfflineLinks>
 +          <linksource>true</linksource>
 +        </configuration>
 +        <reportSets>
 +          <reportSet>
 +            <id>non-aggregate</id>
 +            <reports>
 +              <report>javadoc</report>
 +            </reports>
 +          </reportSet>
 +        </reportSets>
 +      </plugin>
 +      <plugin>
 +        <groupId>org.codehaus.mojo</groupId>
 +        <artifactId>findbugs-maven-plugin</artifactId>
 +        <version>${findbugs.plugin.version}</version>
 +        <configuration>
 +          <fork>true</fork>
 +          <jvmArgs>-Duser.language=en</jvmArgs>
 +          <threshold>Normal</threshold>
 +          <effort>Default</effort>
 +          <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile>
 +        </configuration>
 +      </plugin>
 +      <plugin>
 +        <groupId>org.apache.maven.plugins</groupId>
 +        <artifactId>maven-jxr-plugin</artifactId>
 +        <version>${jxr.plugin.version}</version>
 +        <reportSets>
 +          <reportSet>
 +            <id>non-aggregate</id>
 +            <reports>
 +              <report>jxr</report>
 +            </reports>
 +          </reportSet>
 +          <reportSet>
 +            <id>aggregate</id>
 +            <reports>
 +              <report>aggregate</report>
 +            </reports>
 +          </reportSet>
 +        </reportSets>
 +      </plugin>
 +      <plugin>
 +        <groupId>org.apache.maven.plugins</groupId>
 +        <artifactId>maven-pmd-plugin</artifactId>
 +        <version>${pmd.plugin.version}</version>
 +        <configuration>
 +          <targetJdk>${maven.compiler.target}</targetJdk>
 +        </configuration>
 +      </plugin>
 +    </plugins>
 +  </reporting>
 +</project>
 +

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractLogEventBridge.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractLogEventBridge.java
index 0000000,0000000..5e368cb
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractLogEventBridge.java
@@@ -1,0 -1,0 +1,44 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.IOException;
++import java.io.InputStream;
++
++import org.apache.logging.log4j.Logger;
++import org.apache.logging.log4j.status.StatusLogger;
++
++/**
++ * Abstract class for implementations of {@link LogEventBridge}.
++ * 
++ * @param <T>
++ *            The kind of input stream read
++ */
++public abstract class AbstractLogEventBridge<T extends InputStream> implements LogEventBridge<T> {
++
++    protected static final int END = -1;
++
++    protected static final Logger logger = StatusLogger.getLogger();
++
++    // The default is to return the same object as given.
++    @SuppressWarnings("unchecked")
++    @Override
++    public T wrapStream(final InputStream inputStream) throws IOException {
++        return (T) inputStream;
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractSocketServer.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractSocketServer.java
index 0000000,0000000..a8f1140
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/AbstractSocketServer.java
@@@ -1,0 -1,0 +1,209 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.BufferedReader;
++import java.io.File;
++import java.io.FileInputStream;
++import java.io.FileNotFoundException;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.InputStreamReader;
++import java.net.InetAddress;
++import java.net.URI;
++import java.net.URL;
++import java.util.Objects;
++
++import com.beust.jcommander.Parameter;
++import com.beust.jcommander.validators.PositiveInteger;
++import org.apache.logging.log4j.LogManager;
++import org.apache.logging.log4j.Logger;
++import org.apache.logging.log4j.core.LogEventListener;
++import org.apache.logging.log4j.core.LoggerContext;
++import org.apache.logging.log4j.core.config.Configuration;
++import org.apache.logging.log4j.core.config.ConfigurationSource;
++import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
++import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory;
++import org.apache.logging.log4j.core.util.BasicCommandLineArguments;
++import org.apache.logging.log4j.core.util.InetAddressConverter;
++import org.apache.logging.log4j.core.util.Log4jThread;
++import org.apache.logging.log4j.util.Strings;
++
++/**
++ * Abstract socket server for TCP and UDP implementations.
++ *
++ * @param <T>
++ *            The kind of input stream read
++ *
++ *            TODO Make a LifeCycle
++ */
++public abstract class AbstractSocketServer<T extends InputStream> extends LogEventListener implements Runnable {
++
++    protected static class CommandLineArguments extends BasicCommandLineArguments {
++
++        @Parameter(names = { "--config", "-c" }, description = "Log4j configuration file location (path or URL).")
++        private String configLocation;
++
++        @Parameter(names = { "--interactive",
++                "-i" }, description = "Accepts commands on standard input (\"exit\" is the only command).")
++        private boolean interactive;
++
++        @Parameter(names = { "--port",
++                "-p" }, validateWith = PositiveInteger.class, description = "Server socket port.")
++        private int port;
++
++        @Parameter(names = { "--localbindaddress",
++                "-a" }, converter = InetAddressConverter.class, description = "Server socket local bind address.")
++        private InetAddress localBindAddress;
++
++        String getConfigLocation() {
++            return configLocation;
++        }
++
++        int getPort() {
++            return port;
++        }
++
++        protected boolean isInteractive() {
++            return interactive;
++        }
++
++        void setConfigLocation(final String configLocation) {
++            this.configLocation = configLocation;
++        }
++
++        void setInteractive(final boolean interactive) {
++            this.interactive = interactive;
++        }
++
++        void setPort(final int port) {
++            this.port = port;
++        }
++
++        InetAddress getLocalBindAddress() {
++            return localBindAddress;
++        }
++
++        void setLocalBindAddress(final InetAddress localBindAddress) {
++            this.localBindAddress = localBindAddress;
++        }
++    }
++
++    /**
++     * Factory that creates a Configuration for the server.
++     */
++    protected static class ServerConfigurationFactory extends XmlConfigurationFactory {
++
++        private final String path;
++
++        public ServerConfigurationFactory(final String path) {
++            this.path = path;
++        }
++
++        @Override
++        public Configuration getConfiguration(final LoggerContext loggerContext, final String name,
++                final URI configLocation) {
++            if (Strings.isNotEmpty(path)) {
++                File file = null;
++                ConfigurationSource source = null;
++                try {
++                    file = new File(path);
++                    final FileInputStream is = new FileInputStream(file);
++                    source = new ConfigurationSource(is, file);
++                } catch (final FileNotFoundException ignored) {
++                    // Ignore this error
++                }
++                if (source == null) {
++                    try {
++                        final URL url = new URL(path);
++                        source = new ConfigurationSource(url.openStream(), url);
++                    } catch (final IOException ignored) {
++                        // Ignore this error
++                    }
++                }
++
++                try {
++                    if (source != null) {
++                        return new XmlConfiguration(loggerContext, source);
++                    }
++                } catch (final Exception ignored) {
++                    // Ignore this error.
++                }
++                System.err.println("Unable to process configuration at " + path + ", using default.");
++            }
++            return super.getConfiguration(loggerContext, name, configLocation);
++        }
++    }
++
++    protected static final int MAX_PORT = 65534;
++
++    private volatile boolean active = true;
++
++    protected final LogEventBridge<T> logEventInput;
++
++    protected final Logger logger;
++
++    /**
++     * Creates a new socket server.
++     *
++     * @param port
++     *            listen to this port
++     * @param logEventInput
++     *            Use this input to read log events.
++     */
++    public AbstractSocketServer(final int port, final LogEventBridge<T> logEventInput) {
++        this.logger = LogManager.getLogger(this.getClass().getName() + '.' + port);
++        this.logEventInput = Objects.requireNonNull(logEventInput, "LogEventInput");
++    }
++
++    protected boolean isActive() {
++        return this.active;
++    }
++
++    protected void setActive(final boolean isActive) {
++        this.active = isActive;
++    }
++
++    /**
++     * Start this server in a new thread.
++     *
++     * @return the new thread that running this server.
++     */
++    public Thread startNewThread() {
++        final Thread thread = new Log4jThread(this);
++        thread.start();
++        return thread;
++    }
++
++    public abstract void shutdown() throws Exception;
++
++    public void awaitTermination(final Thread serverThread) throws Exception {
++        final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
++        while (true) {
++            final String line = reader.readLine();
++            if (line == null
++                || line.equalsIgnoreCase("quit")
++                || line.equalsIgnoreCase("stop")
++                || line.equalsIgnoreCase("exit")) {
++                this.shutdown();
++                serverThread.join();
++                break;
++            }
++        }
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/InputStreamLogEventBridge.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/InputStreamLogEventBridge.java
index 0000000,0000000..68ec791
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/InputStreamLogEventBridge.java
@@@ -1,0 -1,0 +1,103 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.IOException;
++import java.io.InputStream;
++import java.nio.charset.Charset;
++
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.LogEventListener;
++import org.apache.logging.log4j.core.impl.Log4jLogEvent;
++import org.apache.logging.log4j.util.Strings;
++
++import com.fasterxml.jackson.databind.ObjectMapper;
++import com.fasterxml.jackson.databind.ObjectReader;
++
++/**
++ * Reads and logs {@link LogEvent}s from an {@link InputStream}.
++ */
++public abstract class InputStreamLogEventBridge extends AbstractLogEventBridge<InputStream> {
++
++    private final int bufferSize;
++
++    private final Charset charset;
++
++    private final String eventEndMarker;
++    
++    private final ObjectReader objectReader;
++    
++    public InputStreamLogEventBridge(final ObjectMapper mapper, final int bufferSize, final Charset charset, final String eventEndMarker) {
++        this.bufferSize = bufferSize;
++        this.charset = charset;
++        this.eventEndMarker = eventEndMarker;
++        this.objectReader = mapper.readerFor(Log4jLogEvent.class);
++    }
++
++    abstract protected int[] getEventIndices(final String text, int beginIndex);
++
++    @Override
++    public void logEvents(final InputStream inputStream, final LogEventListener logEventListener) throws IOException {
++        String workingText = Strings.EMPTY;
++        try {
++            // Allocate buffer once
++            final byte[] buffer = new byte[bufferSize];
++            String textRemains = workingText = Strings.EMPTY;
++            while (true) {
++                // Process until the stream is EOF.
++                final int streamReadLength = inputStream.read(buffer);
++                if (streamReadLength == END) {
++                    // The input stream is EOF
++                    break;
++                }
++                final String text = workingText = textRemains + new String(buffer, 0, streamReadLength, charset);
++                int beginIndex = 0;
++                while (true) {
++                    // Extract and log all XML events in the buffer
++                    final int[] pair = getEventIndices(text, beginIndex);
++                    final int eventStartMarkerIndex = pair[0];
++                    if (eventStartMarkerIndex < 0) {
++                        // No more events or partial XML only in the buffer.
++                        // Save the unprocessed string part
++                        textRemains = text.substring(beginIndex);
++                        break;
++                    }
++                    final int eventEndMarkerIndex = pair[1];
++                    if (eventEndMarkerIndex > 0) {
++                        final int eventEndXmlIndex = eventEndMarkerIndex + eventEndMarker.length();
++                        final String textEvent = workingText = text.substring(eventStartMarkerIndex, eventEndXmlIndex);
++                        final LogEvent logEvent = unmarshal(textEvent);
++                        logEventListener.log(logEvent);
++                        beginIndex = eventEndXmlIndex;
++                    } else {
++                        // No more events or partial XML only in the buffer.
++                        // Save the unprocessed string part
++                        textRemains = text.substring(beginIndex);
++                        break;
++                    }
++                }
++            }
++        } catch (final IOException ex) {
++            logger.error(workingText, ex);
++        }
++    }
++
++    protected Log4jLogEvent unmarshal(final String jsonEvent) throws IOException {
++        return this.objectReader.readValue(jsonEvent);
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/JmsServer.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/JmsServer.java
index 0000000,0000000..b673c06
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/JmsServer.java
@@@ -1,0 -1,0 +1,148 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++package org.apache.logging.log4j.server;
++
++import java.io.BufferedReader;
++import java.io.IOException;
++import java.io.InputStreamReader;
++import java.nio.charset.Charset;
++import java.util.concurrent.TimeUnit;
++import java.util.concurrent.atomic.AtomicReference;
++import javax.jms.JMSException;
++import javax.jms.Message;
++import javax.jms.MessageConsumer;
++import javax.jms.MessageListener;
++import javax.jms.ObjectMessage;
++
++import org.apache.logging.log4j.LoggingException;
++import org.apache.logging.log4j.core.AbstractLifeCycle;
++import org.apache.logging.log4j.core.LifeCycle2;
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.LogEventListener;
++import org.apache.logging.log4j.core.appender.mom.JmsManager;
++import org.apache.logging.log4j.core.net.JndiManager;
++
++/**
++ * LogEventListener server that receives LogEvents over a JMS {@link javax.jms.Destination}.
++ *
++ * @since 2.1
++ */
++public class JmsServer extends LogEventListener implements MessageListener, LifeCycle2 {
++
++    private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
++    private final JmsManager jmsManager;
++    private MessageConsumer messageConsumer;
++
++    public JmsServer(final String connectionFactoryBindingName,
++                     final String destinationBindingName,
++                     final String username,
++                     final String password) {
++        final String managerName = JmsServer.class.getName() + '@' + JmsServer.class.hashCode();
++        final JndiManager jndiManager = JndiManager.getDefaultManager(managerName);
++        jmsManager = JmsManager.getJmsManager(managerName, jndiManager, connectionFactoryBindingName,
++            destinationBindingName, username, password);
++    }
++
++    @Override
++    public State getState() {
++        return state.get();
++    }
++
++    @Override
++    public void onMessage(final Message message) {
++        try {
++            if (message instanceof ObjectMessage) {
++                final Object body = ((ObjectMessage) message).getObject();
++                if (body instanceof LogEvent) {
++                    log((LogEvent) body);
++                } else {
++                    LOGGER.warn("Expected ObjectMessage to contain LogEvent. Got type {} instead.", body.getClass());
++                }
++            } else {
++                LOGGER.warn("Received message of type {} and JMSType {} which cannot be handled.", message.getClass(),
++                    message.getJMSType());
++            }
++        } catch (final JMSException e) {
++            LOGGER.catching(e);
++        }
++    }
++
++    @Override
++    public void initialize() {
++    }
++
++    @Override
++    public void start() {
++        if (state.compareAndSet(State.INITIALIZED, State.STARTING)) {
++            try {
++                messageConsumer = jmsManager.createMessageConsumer();
++                messageConsumer.setMessageListener(this);
++            } catch (final JMSException e) {
++                throw new LoggingException(e);
++            }
++        }
++    }
++
++    @Override
++    public void stop() {
++        stop(AbstractLifeCycle.DEFAULT_STOP_TIMEOUT, AbstractLifeCycle.DEFAULT_STOP_TIMEUNIT);
++    }
++
++    @Override
++    public boolean stop(final long timeout, final TimeUnit timeUnit) {
++        boolean stopped = true;
++        try {
++            messageConsumer.close();
++        } catch (final JMSException e) {
++            LOGGER.debug("Exception closing {}", messageConsumer, e);
++            stopped = false;
++        }
++        return stopped && jmsManager.stop(timeout, timeUnit);
++    }
++
++    @Override
++    public boolean isStarted() {
++        return state.get() == State.STARTED;
++    }
++
++    @Override
++    public boolean isStopped() {
++        return state.get() == State.STOPPED;
++    }
++
++    /**
++     * Starts and runs this server until the user types "exit" into standard input.
++     *
++     * @throws IOException
++     * @since 2.6
++     */
++    public void run() throws IOException {
++        this.start();
++        System.out.println("Type \"exit\" to quit.");
++        final BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in, Charset.defaultCharset()));
++        while (true) {
++            final String line = stdin.readLine();
++            if (line == null || line.equalsIgnoreCase("exit")) {
++                System.out.println("Exiting. Kill the application if it does not exit due to daemon threads.");
++                this.stop();
++                return;
++            }
++        }
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/JsonInputStreamLogEventBridge.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/JsonInputStreamLogEventBridge.java
index 0000000,0000000..6a06ae4
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/JsonInputStreamLogEventBridge.java
@@@ -1,0 -1,0 +1,90 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.InputStream;
++import java.nio.charset.Charset;
++
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.jackson.Log4jJsonObjectMapper;
++import org.apache.logging.log4j.util.Chars;
++
++/**
++ * Reads and logs JSON {@link LogEvent}s from an {@link InputStream}..
++ */
++public class JsonInputStreamLogEventBridge extends InputStreamLogEventBridge {
++
++    private static final int[] END_PAIR = new int[] { END, END };
++    private static final char EVENT_END_MARKER = '}';
++    private static final char EVENT_START_MARKER = '{';
++    private static final char JSON_ESC = '\\';
++    private static final char JSON_STR_DELIM = Chars.DQUOTE;
++    private static final boolean THREAD_CONTEXT_MAP_AS_LIST = false;
++
++    public JsonInputStreamLogEventBridge() {
++        this(1024, Charset.defaultCharset());
++    }
++
++    public JsonInputStreamLogEventBridge(final int bufferSize, final Charset charset) {
++        super(new Log4jJsonObjectMapper(THREAD_CONTEXT_MAP_AS_LIST, true), bufferSize, charset,
++                String.valueOf(EVENT_END_MARKER));
++    }
++
++    @Override
++    protected int[] getEventIndices(final String text, final int beginIndex) {
++        // Scan the text for the end of the next JSON object.
++        final int start = text.indexOf(EVENT_START_MARKER, beginIndex);
++        if (start == END) {
++            return END_PAIR;
++        }
++        final char[] charArray = text.toCharArray();
++        int stack = 0;
++        boolean inStr = false;
++        boolean inEsc = false;
++        for (int i = start; i < charArray.length; i++) {
++            final char c = charArray[i];
++            if (inEsc) {
++            	// Skip this char and continue
++            	inEsc = false;
++            } else {
++                switch (c) {
++                case EVENT_START_MARKER:
++                    if (!inStr) {
++                        stack++;
++                    }
++                    break;
++                case EVENT_END_MARKER:
++                    if (!inStr) {
++                        stack--;
++                    }
++                    break;
++                case JSON_STR_DELIM:
++                    inStr = !inStr;
++                    break;
++                case JSON_ESC:
++                    inEsc = true;
++                    break;
++                }
++                if (stack == 0) {
++                    return new int[] { start, i };
++                }
++            }
++        }
++        return END_PAIR;
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/LogEventBridge.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/LogEventBridge.java
index 0000000,0000000..785c365
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/LogEventBridge.java
@@@ -1,0 -1,0 +1,57 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.IOException;
++import java.io.InputStream;
++
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.LogEventListener;
++
++/**
++ * Reads {@link LogEvent}s from the given input stream and logs them as they are discovered on the given logger.
++ * 
++ * <p>
++ * Should be stateless.
++ * </p>
++ * 
++ * @param <T>
++ *            The kind of {@link InputStream} to wrap and read.
++ */
++public interface LogEventBridge<T extends InputStream> {
++
++    /**
++     * Reads {@link LogEvent}s from the given input stream and logs them as they are discovered on the given logger.
++     * 
++     * @param inputStream
++     *            the input stream to read
++     * @param logEventListener
++     *            TODO
++     * @throws IOException
++     */
++    void logEvents(T inputStream, LogEventListener logEventListener) throws IOException;
++
++    /**
++     * Wraps the given stream if needed.
++     * 
++     * @param inputStream
++     *            the stream to wrap
++     * @return the wrapped stream or the given stream.
++     * @throws IOException
++     */
++    T wrapStream(InputStream inputStream) throws IOException;
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/ObjectInputStreamLogEventBridge.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/ObjectInputStreamLogEventBridge.java
index 0000000,0000000..9f22b22
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/ObjectInputStreamLogEventBridge.java
@@@ -1,0 -1,0 +1,45 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.ObjectInputStream;
++
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.LogEventListener;
++
++/**
++ * Reads and logs serialized {@link LogEvent} objects from an {@link ObjectInputStream}.
++ */
++public class ObjectInputStreamLogEventBridge extends AbstractLogEventBridge<ObjectInputStream> {
++
++    @Override
++    public void logEvents(final ObjectInputStream inputStream, final LogEventListener logEventListener)
++            throws IOException {
++        try {
++            logEventListener.log((LogEvent) inputStream.readObject());
++        } catch (final ClassNotFoundException e) {
++            throw new IOException(e);
++        }
++    }
++
++    @Override
++    public ObjectInputStream wrapStream(final InputStream inputStream) throws IOException {
++        return new ObjectInputStream(inputStream);
++    }
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/SecureTcpSocketServer.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/SecureTcpSocketServer.java
index 0000000,0000000..81c9d64
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/SecureTcpSocketServer.java
@@@ -1,0 -1,0 +1,37 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.IOException;
++import java.io.InputStream;
++
++import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
++
++/**
++ * Listens for events over a secure socket connection (SSL/TLS).
++ * 
++ * @param <T>
++ *        The kind of input stream read
++ */
++public class SecureTcpSocketServer<T extends InputStream> extends TcpSocketServer<T> {
++
++    public SecureTcpSocketServer(final int port, final LogEventBridge<T> logEventInput,
++            final SslConfiguration sslConfig) throws IOException {
++        super(port, logEventInput, sslConfig.getSslServerSocketFactory().createServerSocket(port));
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
index 0000000,0000000..7856969
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
@@@ -1,0 -1,0 +1,314 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.EOFException;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.ObjectInputStream;
++import java.io.OptionalDataException;
++import java.net.InetAddress;
++import java.net.ServerSocket;
++import java.net.Socket;
++import java.util.Map;
++import java.util.concurrent.ConcurrentHashMap;
++import java.util.concurrent.ConcurrentMap;
++
++import com.beust.jcommander.Parameter;
++import com.beust.jcommander.validators.PositiveInteger;
++import org.apache.logging.log4j.core.config.ConfigurationFactory;
++import org.apache.logging.log4j.core.util.BasicCommandLineArguments;
++import org.apache.logging.log4j.core.util.Closer;
++import org.apache.logging.log4j.core.util.Log4jThread;
++import org.apache.logging.log4j.message.EntryMessage;
++
++/**
++ * Listens for Log4j events on a TCP server socket and passes them on to Log4j.
++ * 
++ * @param <T>
++ *        The kind of input stream read
++ * @see #main(String[])
++ */
++public class TcpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
++
++    protected static class CommandLineArguments extends AbstractSocketServer.CommandLineArguments {
++        
++        @Parameter(names = { "--backlog",
++                "-b" }, validateWith = PositiveInteger.class, description = "Server socket backlog.")
++        // Same default as ServerSocket
++        private int backlog = 50;
++
++        int getBacklog() {
++            return backlog;
++        }
++
++        void setBacklog(final int backlog) {
++            this.backlog = backlog;
++        }        
++
++    }
++
++    /**
++     * Thread that processes the events.
++     */
++    private class SocketHandler extends Log4jThread {
++
++        private final T inputStream;
++
++        private volatile boolean shutdown = false;
++
++        public SocketHandler(final Socket socket) throws IOException {
++            this.inputStream = logEventInput.wrapStream(socket.getInputStream());
++        }
++
++        @Override
++        public void run() {
++            final EntryMessage entry = logger.traceEntry();
++            boolean closed = false;
++            try {
++                try {
++                    while (!shutdown) {
++                        logEventInput.logEvents(inputStream, TcpSocketServer.this);
++                    }
++                } catch (final EOFException e) {
++                    closed = true;
++                } catch (final OptionalDataException e) {
++                    logger.error("OptionalDataException eof=" + e.eof + " length=" + e.length, e);
++                } catch (final IOException e) {
++                    logger.error("IOException encountered while reading from socket", e);
++                }
++                if (!closed) {
++                    Closer.closeSilently(inputStream);
++                }
++            } finally {
++                handlers.remove(Long.valueOf(getId()));
++            }
++            logger.traceExit(entry);
++        }
++
++        public void shutdown() {
++            this.shutdown = true;
++            interrupt();
++        }
++    }
++
++    /**
++     * Creates a socket server that reads JSON log events.
++     * 
++     * @param port
++     *        the port to listen
++     * @return a new a socket server
++     * @throws IOException
++     *         if an I/O error occurs when opening the socket.
++     */
++    public static TcpSocketServer<InputStream> createJsonSocketServer(final int port) throws IOException {
++        LOGGER.entry("createJsonSocketServer", port);
++        final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new JsonInputStreamLogEventBridge());
++        return LOGGER.exit(socketServer);
++    }
++
++    /**
++     * Creates a socket server that reads serialized log events.
++     * 
++     * @param port
++     *        the port to listen
++     * @return a new a socket server
++     * @throws IOException
++     *         if an I/O error occurs when opening the socket.
++     */
++    public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port) throws IOException {
++        LOGGER.entry(port);
++        final TcpSocketServer<ObjectInputStream> socketServer = new TcpSocketServer<>(port, new ObjectInputStreamLogEventBridge());
++        return LOGGER.exit(socketServer);
++    }
++
++    /**
++     * Creates a socket server that reads serialized log events.
++     * 
++     * @param port the port to listen
++     * @param localBindAddress The server socket's local bin address
++     * @return a new a socket server
++     * @throws IOException
++     *         if an I/O error occurs when opening the socket.
++     * @since 2.7
++     */
++    public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port, final int backlog,
++            final InetAddress localBindAddress) throws IOException {
++        LOGGER.entry(port);
++        final TcpSocketServer<ObjectInputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
++                new ObjectInputStreamLogEventBridge());
++        return LOGGER.exit(socketServer);
++    }
++
++    /**
++     * Creates a socket server that reads XML log events.
++     * 
++     * @param port
++     *        the port to listen
++     * @return a new a socket server
++     * @throws IOException
++     *         if an I/O error occurs when opening the socket.
++     */
++    public static TcpSocketServer<InputStream> createXmlSocketServer(final int port) throws IOException {
++        LOGGER.entry(port);
++        final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new XmlInputStreamLogEventBridge());
++        return LOGGER.exit(socketServer);
++    }
++
++    /**
++     * Main startup for the server. Run with "--help" for to print command line help on the console.
++     * 
++     * @param args
++     *        The command line arguments.
++     * @throws Exception
++     *         if an error occurs.
++     */
++    public static void main(final String[] args) throws Exception {
++        final CommandLineArguments cla = BasicCommandLineArguments.parseCommandLine(args, TcpSocketServer.class, new CommandLineArguments());
++        if (cla.isHelp()) {
++            return;
++        }
++        if (cla.getConfigLocation() != null) {
++            ConfigurationFactory.setConfigurationFactory(new ServerConfigurationFactory(cla.getConfigLocation()));
++        }
++        final TcpSocketServer<ObjectInputStream> socketServer = TcpSocketServer
++                .createSerializedSocketServer(cla.getPort(), cla.getBacklog(), cla.getLocalBindAddress());
++        final Thread serverThread = socketServer.startNewThread();
++        if (cla.isInteractive()) {
++            socketServer.awaitTermination(serverThread);
++        }
++    }
++
++    private final ConcurrentMap<Long, SocketHandler> handlers = new ConcurrentHashMap<>();
++
++    private final ServerSocket serverSocket;
++
++    /**
++     * Constructor.
++     * 
++     * @param port
++     *        The server socket port.
++     * @param backlog
++     *        The server socket backlog.
++     * @param localBindAddress TODO
++     * @param logEventInput
++     *        the log even input
++     * @throws IOException
++     *         if an I/O error occurs when opening the socket.
++     * @since 2.7
++     */
++    @SuppressWarnings("resource")
++    public TcpSocketServer(final int port, final int backlog, final InetAddress localBindAddress, final LogEventBridge<T> logEventInput) throws IOException {
++        this(port, logEventInput, new ServerSocket(port, backlog, localBindAddress));
++    }
++
++    /**
++     * Constructor.
++     * 
++     * @param port
++     *        to listen.
++     * @param logEventInput
++     *        the log even input
++     * @throws IOException
++     *         if an I/O error occurs when opening the socket.
++     */
++    public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput) throws IOException {
++        this(port, logEventInput, extracted(port));
++    }
++
++    private static ServerSocket extracted(final int port) throws IOException {
++        return new ServerSocket(port);
++    }
++
++    /**
++     * Constructor.
++     * 
++     * @param port
++     *        to listen.
++     * @param logEventInput
++     *        the log even input
++     * @param serverSocket
++     *        the socket server
++     * @throws IOException
++     *         if an I/O error occurs when opening the socket.
++     */
++    public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput, final ServerSocket serverSocket)
++            throws IOException {
++        super(port, logEventInput);
++        this.serverSocket = serverSocket;
++    }
++
++    /**
++     * Accept incoming events and processes them.
++     */
++    @Override
++    public void run() {
++        final EntryMessage entry = logger.traceEntry();
++        while (isActive()) {
++            if (serverSocket.isClosed()) {
++                return;
++            }
++            try {
++                // Accept incoming connections.
++                logger.debug("Listening for a connection {}...", serverSocket);
++                final Socket clientSocket = serverSocket.accept();
++                logger.debug("Acepted connection on {}...", serverSocket);
++                logger.debug("Socket accepted: {}", clientSocket);
++                clientSocket.setSoLinger(true, 0);
++
++                // accept() will block until a client connects to the server.
++                // If execution reaches this point, then it means that a client
++                // socket has been accepted.
++
++                final SocketHandler handler = new SocketHandler(clientSocket);
++                handlers.put(Long.valueOf(handler.getId()), handler);
++                handler.start();
++            } catch (final IOException e) {
++                if (serverSocket.isClosed()) {
++                    // OK we're done.
++                    logger.traceExit(entry);
++                    return;
++                }
++                logger.error("Exception encountered on accept. Ignoring. Stack trace :", e);
++            }
++        }
++        for (final Map.Entry<Long, SocketHandler> handlerEntry : handlers.entrySet()) {
++            final SocketHandler handler = handlerEntry.getValue();
++            handler.shutdown();
++            try {
++                handler.join();
++            } catch (final InterruptedException ignored) {
++                // Ignore the exception
++            }
++        }
++        logger.traceExit(entry);
++    }
++
++    /**
++     * Shutdown the server.
++     * 
++     * @throws IOException if the server socket could not be closed
++     */
++    @Override
++    public void shutdown() throws IOException {
++        final EntryMessage entry = logger.traceEntry();
++        setActive(false);
++        Thread.currentThread().interrupt();
++        serverSocket.close();
++        logger.traceExit(entry);
++    }
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/UdpSocketServer.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/UdpSocketServer.java
index 0000000,0000000..a2bac17
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/UdpSocketServer.java
@@@ -1,0 -1,0 +1,169 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.ByteArrayInputStream;
++import java.io.EOFException;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.ObjectInputStream;
++import java.io.OptionalDataException;
++import java.net.DatagramPacket;
++import java.net.DatagramSocket;
++
++import org.apache.logging.log4j.core.config.ConfigurationFactory;
++import org.apache.logging.log4j.core.util.BasicCommandLineArguments;
++
++/**
++ * Listens for Log4j events on a datagram socket and passes them on to Log4j. 
++ * 
++ * @param <T>
++ *            The kind of input stream read
++ * @see #main(String[])
++ */
++public class UdpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
++
++    /**
++     * Creates a socket server that reads JSON log events.
++     * 
++     * @param port
++     *            the port to listen
++     * @return a new a socket server
++     * @throws IOException
++     *             if an I/O error occurs when opening the socket.
++     */
++    public static UdpSocketServer<InputStream> createJsonSocketServer(final int port) throws IOException {
++        return new UdpSocketServer<>(port, new JsonInputStreamLogEventBridge());
++    }
++
++    /**
++     * Creates a socket server that reads serialized log events.
++     * 
++     * @param port
++     *            the port to listen
++     * @return a new a socket server
++     * @throws IOException
++     *             if an I/O error occurs when opening the socket.
++     */
++    public static UdpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port) throws IOException {
++        return new UdpSocketServer<>(port, new ObjectInputStreamLogEventBridge());
++    }
++
++    /**
++     * Creates a socket server that reads XML log events.
++     * 
++     * @param port
++     *            the port to listen
++     * @return a new a socket server
++     * @throws IOException
++     *             if an I/O error occurs when opening the socket.
++     */
++    public static UdpSocketServer<InputStream> createXmlSocketServer(final int port) throws IOException {
++        return new UdpSocketServer<>(port, new XmlInputStreamLogEventBridge());
++    }
++
++    /**
++     * Main startup for the server. Run with "--help" for to print command line help on the console.
++     * 
++     * @param args
++     *            The command line arguments.
++     * @throws Exception
++     *             if an error occurs.
++     */
++    public static void main(final String[] args) throws Exception {
++        final CommandLineArguments cla = BasicCommandLineArguments.parseCommandLine(args, UdpSocketServer.class, new CommandLineArguments());
++        if (cla.isHelp()) {
++            return;
++        }
++        if (cla.getConfigLocation() != null) {
++            ConfigurationFactory.setConfigurationFactory(new ServerConfigurationFactory(cla.getConfigLocation()));
++        }
++        final UdpSocketServer<ObjectInputStream> socketServer = UdpSocketServer
++                .createSerializedSocketServer(cla.getPort());
++        final Thread serverThread = socketServer.startNewThread();
++        if (cla.isInteractive()) {
++            socketServer.awaitTermination(serverThread);
++        }
++    }
++
++    private final DatagramSocket datagramSocket;
++
++    // max size so we only have to deal with one packet
++    private final int maxBufferSize = 1024 * 65 + 1024;
++
++    /**
++     * Constructor.
++     * 
++     * @param port
++     *            to listen on.
++     * @param logEventInput
++     * @throws IOException
++     *             If an error occurs.
++     */
++    public UdpSocketServer(final int port, final LogEventBridge<T> logEventInput) throws IOException {
++        super(port, logEventInput);
++        this.datagramSocket = new DatagramSocket(port);
++    }
++
++    /**
++     * Accept incoming events and processes them.
++     */
++    @Override
++    public void run() {
++        while (isActive()) {
++            if (datagramSocket.isClosed()) {
++                // OK we're done.
++                return;
++            }
++            try {
++                final byte[] buf = new byte[maxBufferSize];
++                final DatagramPacket packet = new DatagramPacket(buf, buf.length);
++                datagramSocket.receive(packet);
++                final ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength());
++                logEventInput.logEvents(logEventInput.wrapStream(bais), this);
++            } catch (final OptionalDataException e) {
++                if (datagramSocket.isClosed()) {
++                    // OK we're done.
++                    return;
++                }
++                logger.error("OptionalDataException eof=" + e.eof + " length=" + e.length, e);
++            } catch (final EOFException e) {
++                if (datagramSocket.isClosed()) {
++                    // OK we're done.
++                    return;
++                }
++                logger.info("EOF encountered");
++            } catch (final IOException e) {
++                if (datagramSocket.isClosed()) {
++                    // OK we're done.
++                    return;
++                }
++                logger.error("Exception encountered on accept. Ignoring. Stack Trace :", e);
++            }
++        }
++    }
++
++    /**
++     * Shutdown the server.
++     */
++    @Override
++    public void shutdown() {
++        this.setActive(false);
++        Thread.currentThread().interrupt();
++        datagramSocket.close();
++    }
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/XmlInputStreamLogEventBridge.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/XmlInputStreamLogEventBridge.java
index 0000000,0000000..683ae07
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/XmlInputStreamLogEventBridge.java
@@@ -1,0 -1,0 +1,54 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++package org.apache.logging.log4j.server;
++
++import java.io.InputStream;
++import java.nio.charset.Charset;
++
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.jackson.Log4jXmlObjectMapper;
++
++/**
++ * Reads and logs {@link LogEvent}s from an {@link InputStream}.
++ */
++public class XmlInputStreamLogEventBridge extends InputStreamLogEventBridge {
++
++    private static final String EVENT_END = "</Event>";
++    private static final String EVENT_START_NS_N = "<Event>";
++    private static final String EVENT_START_NS_Y = "<Event ";
++
++    public XmlInputStreamLogEventBridge() {
++        this(1024, Charset.defaultCharset());
++    }
++
++    public XmlInputStreamLogEventBridge(final int bufferSize, final Charset charset) {
++        super(new Log4jXmlObjectMapper(), bufferSize, charset, EVENT_END);
++    }
++
++    @Override
++    protected int[] getEventIndices(final String text, final int beginIndex) {
++        int start = text.indexOf(EVENT_START_NS_Y, beginIndex);
++        int startLen = EVENT_START_NS_Y.length();
++        if (start < 0) {
++            start = text.indexOf(EVENT_START_NS_N, beginIndex);
++            startLen = EVENT_START_NS_N.length();
++        }
++        final int end = start < 0 ? -1 : text.indexOf(EVENT_END, start + startLen);
++        return new int[] { start, end };
++    }
++
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/AbstractJmsReceiver.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/AbstractJmsReceiver.java
index 0000000,0000000..373d31c
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/AbstractJmsReceiver.java
@@@ -1,0 -1,0 +1,48 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *       http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++package org.apache.logging.log4j.server.mom.jms;
++
++import org.apache.logging.log4j.server.JmsServer;
++
++/**
++ * Common JMS server functionality.
++ *
++ * @since 2.6
++ */
++public abstract class AbstractJmsReceiver {
++
++    /**
++     * Prints out usage information to {@linkplain System#err standard error}.
++     */
++    protected abstract void usage();
++
++    /**
++     * Executes a JmsServer with the given command line arguments.
++     *
++     * @param args command line arguments
++     * @throws Exception
++     */
++    protected void doMain(final String... args) throws Exception {
++        if (args.length != 4) {
++            usage();
++            System.exit(1);
++        }
++        final JmsServer server = new JmsServer(args[0], args[1], args[2], args[3]);
++        server.run();
++    }
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiver.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiver.java
index 0000000,0000000..a7f75ec
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsQueueReceiver.java
@@@ -1,0 -1,0 +1,46 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++package org.apache.logging.log4j.server.mom.jms;
++
++/**
++ * Receives Log Events over a JMS Queue. This implementation expects that all messages will
++ * contain a serialized LogEvent.
++ */
++public class JmsQueueReceiver extends AbstractJmsReceiver {
++
++    private JmsQueueReceiver() {
++    }
++
++    /**
++     * Main startup for the receiver.
++     *
++     * @param args The command line arguments.
++     * @throws Exception if an error occurs.
++     */
++    public static void main(final String[] args) throws Exception {
++        final JmsQueueReceiver receiver = new JmsQueueReceiver();
++        receiver.doMain(args);
++    }
++
++    @Override
++    protected void usage() {
++        System.err.println("Wrong number of arguments.");
++        System.err.println("Usage: java " + JmsQueueReceiver.class.getName()
++            + " QueueConnectionFactoryBindingName QueueBindingName username password");
++    }
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsTopicReceiver.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsTopicReceiver.java
index 0000000,0000000..21828d7
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/JmsTopicReceiver.java
@@@ -1,0 -1,0 +1,46 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++package org.apache.logging.log4j.server.mom.jms;
++
++/**
++ * Receives Topic messages that contain LogEvents. This implementation expects that all messages
++ * are serialized log events.
++ */
++public class JmsTopicReceiver extends AbstractJmsReceiver {
++
++    private JmsTopicReceiver() {
++    }
++
++    /**
++     * Main startup for the receiver.
++     *
++     * @param args The command line arguments.
++     * @throws Exception if an error occurs.
++     */
++    public static void main(final String[] args) throws Exception {
++        final JmsTopicReceiver receiver = new JmsTopicReceiver();
++        receiver.doMain(args);
++    }
++
++    @Override
++    protected void usage() {
++        System.err.println("Wrong number of arguments.");
++        System.err.println("Usage: java " + JmsTopicReceiver.class.getName()
++            + " TopicConnectionFactoryBindingName TopicBindingName username password");
++    }
++}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/package-info.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/package-info.java
index 0000000,0000000..dd9c90e
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/mom/jms/package-info.java
@@@ -1,0 -1,0 +1,26 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++/**
++ * Supporting network code for JMS appenders.
++ *
++ * <p>Note that you can use JmsQueueReceiver or JmsTopicReceiver as executable main classes to receive log events over
++ * JMS (sent via the appropriate JMS appender) that can be subsequently logged according to the configuration given to
++ * the running process. Of course, use of these classes as standalone executables are entirely optional and can
++ * be used directly in your application (e.g., through your Spring {@code beans.xml} configuration).</p>
++ */
++package org.apache.logging.log4j.server.mom.jms;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/main/java/org/apache/logging/log4j/server/package-info.java
----------------------------------------------------------------------
diff --cc log4j-server/src/main/java/org/apache/logging/log4j/server/package-info.java
index 0000000,0000000..c446a9d
new file mode 100644
--- /dev/null
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/package-info.java
@@@ -1,0 -1,0 +1,24 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++/**
++ * Standalone server classes for consuming log events over a network. Each of the various servers should be used with
++ * another Log4j configuration to handle incoming {@link org.apache.logging.log4j.core.LogEvent}s. It is recommended
++ * to consider using the <a href="../../../../../../../../../manual/appenders.html#FlumeAppender">Flume Appender</a>
++ * for highly reliable networked logging.
++ */
++package org.apache.logging.log4j.server;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b77b7d03/log4j-server/src/site/markdown/index.md
----------------------------------------------------------------------
diff --cc log4j-server/src/site/markdown/index.md
index b66e935,0000000..b3d96ba
mode 100644,000000..100644
--- a/log4j-server/src/site/markdown/index.md
+++ b/log4j-server/src/site/markdown/index.md
@@@ -1,29 -1,0 +1,30 @@@
 +<!-- vim: set syn=markdown : -->
 +<!--
 +    Licensed to the Apache Software Foundation (ASF) under one or more
 +    contributor license agreements.  See the NOTICE file distributed with
 +    this work for additional information regarding copyright ownership.
 +    The ASF licenses this file to You under the Apache License, Version 2.0
 +    (the "License"); you may not use this file except in compliance with
 +    the License.  You may obtain a copy of the License at
 +
 +         http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +-->
 +
 +# Log4j Server components
 +
 +## Log4j Server components
 +
++Standalone server classes for consuming log events over a network. Each of the various servers should be used with
++another Log4j configuration to handle incoming log events. It is recommended to consider using the 
++[Flume Appender](../manual/appenders.html#FlumeAppender) for highly reliable networked logging.
 +
 +## Requirements
 +
 +The Log4j Server components requires the Log4j 2 API and core. This component was introduced in Log4j 2.8.2, 
- before it was part of log4j-core. For more information, see [Runtime Dependencies](../runtime-dependencies.html).
- 
- ## Usage
++before it was part of log4j-core. For more information, see [Runtime Dependencies](../manual/runtime-dependencies.html).