log4j通过SocketAppender将日志内容发送到远程服务器

该博客介绍了如何利用log4j的SocketAppender将日志内容实时发送到远程服务器,以便进行统一处理,如邮件通知、短信告警、日志分析等。文中提供了一个简单的服务端和客户端示例,服务端通过监听特定端口接收log4j发送的日志事件,客户端则配置log4j.xml以启用SocketAppender。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过log4j可以实现将日志内容发送到其他服务器,其他机器可以再对日志做统一处理,比如发送邮件,发送短信,日志分析等等。具体demo如下:

1. 客户端代码

         客户端代码分为log4j的配置文件,和客户端记录log4j日志类

        log4j.xml内容如下

      

<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE log4j:configuration SYSTEM "dtd/log4j.dtd">  
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">  
 <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">       
     <layout class="org.apache.log4j.PatternLayout">           
        <param name="ConversionPattern" value="%d{ABSOLUTE\} %5p %c{1\}:%L - %m%n"/>     
      </layout>    
</appender>
<appender name="remoteFile" class="org.apache.log4j.net.SocketAppender">
         <param name="remoteHost" value="127.0.0.1" /><!-- 这是远程log server -->
         <param name="port" value="4445" /><!-- 这是远程log server port -->
         <param name="Threshold" value="INFO" /><!-- log 级别 -->
         <param name="ReconnectionDelay" value="1000" />
         <param name="LocationInfo" value="true" />
​</appender>
<logger name="testRemote" additivity="false">
         <level value="INFO" />
         <appender-ref ref="STDOUT" />
</logger>
<logger name="testRemote2" additivity="false">
         <level value="INFO" />
         <appender-ref ref="remoteFile" />
</logger>
<root>  
       <level value="info" />  
       <appender-ref ref="STDOUT" />  
 </root>  
</log4j:configuration> 

  测试类如下

   

public class Log4JSocketAppenderTest
{
    public static void main(String[] args) throws Exception
    {
        //发送日志记录时间
        long runTime = 1000 * 60 * 1;
        DOMConfigurator.configure(Log4JSocketAppenderTest.class.getResource("log4j.xml"));
        Logger remoteLogger = LogManager.getLogger("testRemote2");
        long i = 0;
        String sendInfo = "the send info is ";
        long old = System.currentTimeMillis();
        while (true)
        {
            System.out.println("send info begin:  " + sendInfo + i);
            remoteLogger.info(sendInfo + i);
            i++;
            //每3秒记录一次日志
            Thread.sleep(1000 * 3);
            long now = System.currentTimeMillis();
            if((now - old) > runTime)
            {
                break;
            }
        }
    }
}

 


2.  服务端代码

     服务端代码是监听对应的端口,并接收log4j发过来的内容 

  
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.log4j.Logger;

public class LogSocketServer implements Runnable
{
    private static final Logger logger = Logger.getLogger(LogSocketServer.class);
    
    public void run()
    {
        logger.debug("begin call listen log info .....");
        ServerSocket serverSocket;
        Socket socket = null;
        try
        {   
            //如果没有配置端口  则抛出异常
            serverSocket = new ServerSocket(4445);
            
            while (true) {   
                
             logger.info("Waiting to accept a new client.");   
   
                socket = serverSocket.accept();   
   
                InetAddress inetAddress = socket.getInetAddress();   
   
                logger.debug("Connected to client at " + inetAddress);   
   
                logger.debug("Starting new socket node.");   
   
                new Thread(new LogSocketNode(socket)).start();   
   
            }   
        }
        catch (Exception e) 
        {   
            logger.error("error in liston info  ", e);  
        }   
   
    }
}

 
 

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;public class LogSocketNode implements Runnable {
      
     Socket socket;  
     ObjectInputStream ois;  
     static Logger logger = Logger.getLogger(LogSocketNode.class);  
     public LogSocketNode(Socket socket) {  
         this.socket = socket;  
         try {  
             ois = new ObjectInputStream(new BufferedInputStream(  
                     socket.getInputStream()));  
         } catch (Exception e) {  
             logger.error("Could not open ObjectInputStream to " + socket, e);  
         }  
     }  
   
   
     public void run() {  
         LoggingEvent event;  
         try {  
             if (ois != null) {  
                 while (true) {  
                     // read an event from the wire   
                      event = (LoggingEvent) ois.readObject();  
                      System.out.println("get log info is : " + event.getMessage());  
                 }  
   
             }  
   
         } catch (java.io.EOFException e) {  
   
             logger.error("Caught java.io.EOFException closing conneciton.");  
   
         } catch (java.net.SocketException e) {  
   
             logger.error("Caught java.net.SocketException closing conneciton.");  
   
         } catch (IOException e) {  
   
             logger.error("Caught java.io.IOException: " + e);  
   
             logger.error("Closing connection.");  
   
         } catch (Exception e) {  
   
             logger.error("Unexpected exception. Closing conneciton.", e);  
   
         } finally {  
   
             if (ois != null) {  
   
                 try {  
                     logger.debug("begin close ois");
                     ois.close(); 
                     logger.debug("end close ois");
   
                 } catch (Exception e) {  
   
                     logger.error("Could not close connection.", e);  
   
                 }  
   
             }  
   
             if (socket != null) {  
   
                 try {  
                  logger.debug("begin close socket");
                     socket.close();  
                     logger.debug("end close socket");
   
                 } catch (IOException ex) {  
                     logger.error("socket close error ", ex);
                 }  
   
             }  
   
         }  
   
     }  
   }


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值