Spring Boot Logging Level设置为off时Bug

探讨了阿里云KAFKA主动关闭空闲链接导致的客户端异常问题,并提供了一种临时解决方案,通过调整日志级别至FATAL来避免频繁的日志输出。

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

发博词

阿里云的KAFA有一个特性就是会主动关闭空闲的链接,这样导致的问题就是客户端程序会不停的报如下的异常信息:

java.io.IOException: 远程主机强迫关闭了一个现有的连接。
	at sun.nio.ch.SocketDispatcher.write0(Native Method) ~[na:1.8.0_112]
	at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51) ~[na:1.8.0_112]
	at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) ~[na:1.8.0_112]
	at sun.nio.ch.IOUtil.write(IOUtil.java:65) ~[na:1.8.0_112]
	at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) ~[na:1.8.0_112]
	at org.apache.kafka.common.network.SslTransportLayer.flush(SslTransportLayer.java:195) ~[kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.common.network.SslTransportLayer.close(SslTransportLayer.java:163) ~[kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.common.utils.Utils.closeAll(Utils.java:731) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.common.network.KafkaChannel.close(KafkaChannel.java:54) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.common.network.Selector.doClose(Selector.java:540) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.common.network.Selector.close(Selector.java:531) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.common.network.Selector.pollSelectionKeys(Selector.java:378) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.common.network.Selector.poll(Selector.java:303) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:349) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:226) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.clients.consumer.KafkaConsumer.pollOnce(KafkaConsumer.java:1048) [kafka-clients-0.10.2.0.jar:na]
	at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:995) [kafka-clients-0.10.2.0.jar:na]
	at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:558) [spring-kafka-1.1.6.RELEASE.jar:na]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_112]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_112]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112]

而这个异常信息,其实意义不大,而且会一直出,所以就有了需求想要关闭kafka这个包的日志。

临时解决方法

Spring Boot Logging将LogLevel抽象为6个级别,还有一个OFF,是配置关闭日志:

/**
 * Logging levels supported by a {@link LoggingSystem}.
 *
 * @author Phillip Webb
 */
public enum LogLevel {

	TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF

}

但是将某个包的日志级别设置为OFF时,控制台会报如下的信息:

2017-08-24 13:52:12.882 ERROR 12672 --- [           main] o.s.cloud.logging.LoggingRebinder        : Cannot set level: false for 'org.apache.kafka'

定位到LoggingRebinder#setLogLevel方法:

private void setLogLevel(LoggingSystem system, Environment environment, String name,
			String level) {
		try {
			if (name.equalsIgnoreCase("root")) {
				name = null;
			}
			level = environment.resolvePlaceholders(level);
			system.setLogLevel(name, LogLevel.valueOf(level.toUpperCase()));
		}
		catch (RuntimeException ex) {
			this.logger.error("Cannot set level: " + level + " for '" + name + "'");
		}
	}

此时 RuntimeException ex的异常信息如下

java.lang.IllegalArgumentException: No enum constant org.springframework.boot.logging.LogLevel.FALSE

查看level = environment.resolvePlaceholders(level)的值,确实是字符串false而不是off,所以LogLevel.valueOf(level.toUpperCase())在解析的时候就报错了。

属性的值在ConfigFileApplicationListener加载完各个PropertySource之后,这个值就确定了。

临时的解决办法是将日志级别调整到fatal,不管是我们自己的代码还是各类开源框架log信息时的最高的级别一般都是error,调整到fatal可以解决大部分问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈振阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值