如何抑制Log4j2 Socket Appender异常或按环境变量禁用它?
问题描述
我使用的Log4j2 Socket Appender配置如下:
<Socket name="Socket" host="localhost" port="24224" reconnectionDelay="5000" immediateFlush="true"> <PatternLayout> <charset>UTF-8</charset> <alwaysWriteExceptions>false</alwaysWriteExceptions> <Pattern> {"key": "value"} </Pattern> </PatternLayout> </Socket>
但在未安装对应日志服务器的环境中,日志会抛出如下异常:
2023-08-04 13:56:58,708 main ERROR TcpSocketManager (TCP:localhost:24224) caught exception and will continue: java.io.IOException: Unable to create socket for localhost at port 24224 using ip addresses and ports , 0:0:0:0:0:0:0:1:24224 at org.apache.logging.log4j.core.net.TcpSocketManager$TcpSocketManagerFactory.createSocket(TcpSocketManager.java:506) at org.apache.logging.log4j.core.net.TcpSocketManager$TcpSocketManagerFactory.createManager(TcpSocketManager.java:475) at org.apache.logging.log4j.core.net.TcpSocketManager$TcpSocketManagerFactory.createManager(TcpSocketManager.java:456) at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:113) at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114) at org.apache.logging.log4j.core.net.TcpSocketManager.getSocketManager(TcpSocketManager.java:202) at org.apache.logging.log4j.core.appender.SocketAppender.createSocketManager(SocketAppender.java:443) at org.apache.logging.log4j.core.appender.SocketAppender$Builder.build(SocketAppender.java:221) at org.apache.logging.log4j.core.appender.SocketAppender$Builder.build(SocketAppender.java:195) at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122) at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1002) at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:942) at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934) at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:552) at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:241) at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:288) at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:579) at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:651) at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:668) at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:253) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45) at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194) at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:581) at p_outils.httptest_0_1.httpTest.<clinit>(httpTest.java:59)
想了解如何抑制这些错误,或者通过环境变量让Log4j2不实例化该Appender。
解决方案
1. 抑制连接错误日志
要屏蔽TcpSocketManager输出的连接失败错误,直接在Log4j2配置的<Loggers>节点下添加一条规则,关闭该类的日志输出:
<Loggers> <!-- 保留原有Logger配置 --> <Logger name="org.apache.logging.log4j.core.net.TcpSocketManager" level="OFF"/> </Loggers>
这条配置会完全阻止该类产生任何日志,包括你遇到的连接异常信息。如果需要保留其他级别日志,也可以将level设为FATAL,不过这类连接错误属于ERROR级别,设为OFF是最彻底的解决方式。
2. 通过环境变量控制Appender实例化
利用Log4j2的条件配置特性,结合环境变量来决定是否加载Socket Appender。修改你的Appender配置,添加条件判断:
<Appenders> <!-- 保留原有Appender配置 --> <Socket name="Socket" host="localhost" port="24224" reconnectionDelay="5000" immediateFlush="true"> <PatternLayout> <charset>UTF-8</charset> <alwaysWriteExceptions>false</alwaysWriteExceptions> <Pattern>{"key": "value"}</Pattern> </PatternLayout> <Condition> <Equals target="${env:ENABLE_SOCKET_APPENDER}" value="true"/> </Condition> </Socket> </Appenders>
- 在需要启用Socket Appender的环境中,设置环境变量:
- Linux/macOS终端:
export ENABLE_SOCKET_APPENDER=true - Windows命令行:
set ENABLE_SOCKET_APPENDER=true - Windows PowerShell:
$env:ENABLE_SOCKET_APPENDER = "true"
- Linux/macOS终端:
- 在未设置该变量或变量值不为
true的环境中,Log4j2会跳过这个Appender的初始化,不会尝试建立Socket连接,也就不会产生错误日志。
如果需要默认启用、仅在特定环境关闭,也可以反转条件逻辑:
<Condition> <Not> <Equals target="${env:DISABLE_SOCKET_APPENDER}" value="true"/> </Not> </Condition>
此时只要设置DISABLE_SOCKET_APPENDER=true,就会关闭该Appender。
内容的提问来源于stack exchange,提问作者Ibrahim Mezouar
相关产品推荐
相关产品推荐

