无法在Log4j2中实现TcpSocketServer

时间:2019-06-20 06:49:24

标签: java spring-boot logging log4j2

我正在尝试使用Log4j2中的SocketAppender将SpringBoot应用程序中的日志写入远程服务器。首先,我在实现了TcpSocketServer的地方运行侦听器应用程序(这也是一个春季启动应用程序),然后运行我的主应用程序。我收到以下错误。主应用程序在localhost:8080上运行,而侦听器应用程序在localhost:9600上运行。

我做对了吗?如何正确实现此日志记录?我在网上找不到合适的例子。

  

在侦听器应用程序中

java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens
  

在主应用程序中

2019-06-20 17:24:28,091 main ERROR Unable to write to stream 
TCP:localhost:9600 for appender socket-appender: org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:localhost:9600
2019-06-20 17:24:28,092 main ERROR An exception occurred processing Appender socket-appender org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:localhost:9600
Caused by: java.net.SocketException: Broken pipe (Write failed)

我的实施

  

主应用中的Log4j2配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
    <Appenders>
        <Socket name="socket-appender" host="localhost" port="9600">
            <JsonLayout properties="true"/>
        </Socket>
    </Appenders>
    <Loggers>
        <AsyncLogger  name="socket-appender" level="info">
            <AppenderRef ref="socket-appender"/>
        </AsyncLogger>
        <AsyncRoot level="info">
            <AppenderRef ref="socket-appender"/>
        </AsyncRoot>
    </Loggers>
</Configuration>
  

侦听器应用程序中的Log4j2配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="SocketServer">
    <Appenders>
        <RollingRandomAccessFile name="Rolling-Random-Access-File-Appender"
                                 fileName="logs/rollingrandomaccessfile.log"
                                 filePattern="archive/logs/rollingrandomaccessfile.log.%d{yyyy-MM-dd-hh-mm}.gz">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="1 KB"/>
            </Policies>
            <DefaultRolloverStrategy max="30"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <AsyncLogger>
            <AppenderRef ref="Rolling-Random-Access-File-Appender"/>
        </AsyncLogger>
        <AsyncRoot level="info">
            <AppenderRef ref="Rolling-Random-Access-File-Appender"/>
        </AsyncRoot>
    </Loggers>
</Configuration>
  

TcpSocketServer在侦听器应用程序中的实现

package com.springReceiver.receiveFromSocket;

import org.apache.logging.log4j.core.net.server.ObjectInputStreamLogEventBridge;
import org.apache.logging.log4j.core.net.server.TcpSocketServer;

import java.io.IOException;
import java.io.ObjectInputStream;

class Receiver {

    void writeLogs(){

        TcpSocketServer<ObjectInputStream> server = null;
        try {
            server = new TcpSocketServer<>(9600,new ObjectInputStreamLogEventBridge());
            server.run();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }


    }
}

2 个答案:

答案 0 :(得分:0)

在客户端尝试此配置:

<Socket name="socket" host="xxxxxxxxx" port="1090" connectTimeoutMillis="1000" reconnectionDelayMillis="1000" >
            <SerializedLayout />
</Socket>

答案 1 :(得分:0)

首先,您的TCPServer似乎正在使用从未发布的logging-log4j-tools中未经修改的代码-这是有充分理由的。该代码期望发送的有效负载是Java序列化的LogEvent。但是代码没有对可以反序列化的对象执行任何白名单,这是一个安全漏洞(请参见https://www.cvedetails.com/cve/CVE-2017-5645/)。

像客户端配置一样切换到JSONLayout是一种更好的方法,但这意味着您的服务器将必须将JSON转换回LogEvent,这还意味着您将需要包含代码以能够重构您的任何对象正在通过,否则它们将被视为地图。