You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Apache Mina中记录日志?基于log4j.properties实现连接及数据收发日志

没问题,我来帮你搞定这个需求!其实结合Log4j和Apache Mina来记录连接状态与收发数据并不复杂,分两步走:先配置Log4j的日志输出,再在Mina的代码里埋点或用自带过滤器打日志,下面给你详细说明:

第一步:配置log4j.properties

首先要让Log4j把日志输出到指定文件,同时控制日志级别和格式。这里给你一个典型的配置示例:

# 根日志级别
log4j.rootLogger=INFO, file

# 配置文件输出Appender(滚动文件,避免单个文件过大)
log4j.appender.file=org.apache.log4j.RollingFileAppender
# 日志文件路径,根据自己的项目路径修改
log4j.appender.file.File=/opt/mina-server/mina-connection.log
# 单个日志文件最大容量,超过后自动生成新文件
log4j.appender.file.MaxFileSize=10MB
# 最多保留的历史日志文件数量
log4j.appender.file.MaxBackupIndex=5
# 日志格式:包含时间、级别、类名、日志内容
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] %c{1} - %m%n

# 可选:单独控制Apache Mina框架的日志级别,避免过多框架冗余日志
log4j.logger.org.apache.mina=INFO
# 配置你的业务Handler类的日志级别,开发时可以设为DEBUG方便调试
log4j.logger.com.yourcompany.mina.handler.CustomHandler=DEBUG
第二步:在Apache Mina代码中实现日志记录

有两种常用方式,你可以根据需求选择:

方式一:手动在IoHandler中记录日志(推荐,定制化程度高)

Mina的核心业务逻辑都在IoHandler实现类里,你可以在这里注入Log4j的Logger,针对每个关键事件打日志:

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

public class CustomHandler extends IoHandlerAdapter {
    // 绑定当前类的Logger实例
    private static final Logger logger = Logger.getLogger(CustomHandler.class);

    // 连接创建时触发
    @Override
    public void sessionCreated(IoSession session) throws Exception {
        logger.info("新连接创建:远程地址=" + session.getRemoteAddress());
        super.sessionCreated(session);
    }

    // 连接正式打开时触发
    @Override
    public void sessionOpened(IoSession session) throws Exception {
        logger.info("连接已建立:远程地址=" + session.getRemoteAddress());
        super.sessionOpened(session);
    }

    // 连接关闭时触发
    @Override
    public void sessionClosed(IoSession session) throws Exception {
        logger.info("连接已断开:远程地址=" + session.getRemoteAddress());
        super.sessionClosed(session);
    }

    // 收到客户端消息时触发
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        // 根据消息类型转换为可读格式(如果是字节数组转字符串,解码后的对象直接toString)
        String receivedContent = message instanceof byte[] ? new String((byte[]) message, "UTF-8") : message.toString();
        logger.debug("收到消息来自[" + session.getRemoteAddress() + "]:" + receivedContent);
        
        // 这里写你的业务处理逻辑,比如回复消息
        String response = "已接收:" + receivedContent;
        session.write(response);
    }

    // 消息发送完成时触发
    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        String sentContent = message instanceof byte[] ? new String((byte[]) message, "UTF-8") : message.toString();
        logger.debug("发送消息到[" + session.getRemoteAddress() + "]:" + sentContent);
        super.messageSent(session, message);
    }

    // 捕获连接异常时触发
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        logger.error("连接[" + session.getRemoteAddress() + "]发生异常", cause);
        // 异常处理:比如强制关闭连接
        session.closeNow();
    }
}

这种方式可以完全控制日志的内容和格式,适合需要自定义日志细节的场景。

方式二:使用Mina自带的LoggingFilter(快速实现,适合简单场景)

Mina提供了LoggingFilter,可以自动帮你记录连接事件和消息收发,不用手动写日志代码,只需把它添加到过滤器链中:

import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import java.net.InetSocketAddress;

public class MinaServer {
    public static void main(String[] args) throws Exception {
        NioSocketAcceptor acceptor = new NioSocketAcceptor();
        
        // 创建LoggingFilter,默认记录INFO级别的连接事件、DEBUG级别的消息
        LoggingFilter loggingFilter = new LoggingFilter();
        // 可选:调整日志级别,比如把消息日志改成INFO
        // loggingFilter.setMessageLogLevel(Level.INFO);

        // 将过滤器添加到链中(注意顺序:建议放在编解码过滤器之后)
        acceptor.getFilterChain().addLast("logger", loggingFilter);
        
        // 设置业务Handler
        acceptor.setHandler(new CustomHandler());
        
        // 绑定端口启动服务
        acceptor.bind(new InetSocketAddress(8080));
        System.out.println("Mina服务已启动,监听端口8080");
    }
}

这种方式优点是快速集成,无需编写大量日志代码,但日志内容比较固定,定制化程度低,适合简单的日志记录需求。

注意事项
  • 确保项目中已引入Log4j 1.x的依赖包(比如log4j-1.2.17.jar),如果用Log4j2的话配置格式会不同,这里针对你提到的log4j.properties默认是Log4j 1.x。
  • 如果处理的是二进制消息,直接转字符串可能会乱码,建议先通过Mina的Codec过滤器解码为业务对象后再记录。
  • 生产环境建议把日志级别设为INFO或WARN,避免过多DEBUG日志影响性能;开发调试时可以用DEBUG级别。

内容的提问来源于stack exchange,提问作者Nexus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:00:35