Spring Boot集成Camel与MyBatis时如何将数据库错误记为ERROR级日志
解决Camel MyBatis轮询数据库错误日志级别问题
问题原因
Camel的PollingConsumer(比如MyBatis轮询端点)在轮询过程中发生的异常,默认由Consumer自身的错误处理机制处理,不会进入路由的errorHandler或onException处理器——因为异常发生在消息进入路由之前。默认的DefaultPollingConsumerErrorHandler会以WARN级别记录这类错误。
解决方案
方案1:自定义PollingConsumerPollStrategy(推荐,灵活可控)
通过实现PollingConsumerPollStrategy接口,接管轮询失败后的日志记录逻辑,将日志级别改为ERROR。
- 实现自定义策略类:
import org.apache.camel.Consumer; import org.apache.camel.Endpoint; import org.apache.camel.PollingConsumerPollStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CustomMyBatisPollStrategy implements PollingConsumerPollStrategy { private static final Logger LOG = LoggerFactory.getLogger(CustomMyBatisPollStrategy.class); @Override public boolean begin(Consumer consumer, Endpoint endpoint) { return true; // 允许开始轮询 } @Override public void commit(Consumer consumer, Endpoint endpoint, int polledMessages) { // 轮询成功时无需额外处理 } @Override public boolean rollback(Consumer consumer, Endpoint endpoint, int retryCounter, Exception cause) throws Exception { // 以ERROR级别记录异常 LOG.error("轮询端点{}失败,将在下次轮询时重试。", endpoint.getEndpointUri(), cause); return true; // 返回true保持原有重试逻辑 } }
- 在路由中配置该策略:
@Component public class DataChangesRoute extends RouteBuilder { @Override public void configure() throws Exception { from("mybatis:selectDataChanges?statementType=SelectList&initialDelay=1300&delay=5000") .autoStartup("true") .routeId("dataChanges") .pollStrategy(new CustomMyBatisPollStrategy()) // 绑定自定义轮询策略 .choice().when(body().isNotNull()) .log("Consuming data change: ${body}") .to("direct:sendDataChangeMessage"); // 其他路由... } }
方案2:通过日志框架过滤修改级别(快速简便)
如果仅需修改特定MyBatis轮询错误的日志级别,可直接通过日志框架(如Logback、Log4j2)的过滤规则实现,无需修改代码。
以Logback为例,在logback.xml中添加如下配置:
<!-- 将MyBatis轮询失败的WARN日志升级为ERROR --> <logger name="org.apache.camel.spi.CamelLogger" level="ERROR" additivity="false"> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator> <!-- 匹配MyBatis轮询失败的日志消息 --> <expression>message.contains("failed polling endpoint: mybatis://")</expression> </evaluator> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMatch> </filter> <appender-ref ref="你的日志输出Appender"/> </logger>
方案3:自定义PollingConsumerErrorHandler
直接替换默认的Consumer错误处理器,修改日志记录级别:
- 实现自定义错误处理器:
import org.apache.camel.LoggingLevel; import org.apache.camel.impl.DefaultPollingConsumerErrorHandler; import org.apache.camel.spi.CamelLogger; import org.slf4j.LoggerFactory; public class CustomPollingErrorHandler extends DefaultPollingConsumerErrorHandler { private static final CamelLogger ERROR_LOGGER = new CamelLogger( LoggerFactory.getLogger(DefaultPollingConsumerErrorHandler.class), LoggingLevel.ERROR); public CustomPollingErrorHandler(Consumer consumer) { super(consumer); setLogger(ERROR_LOGGER); // 将日志级别改为ERROR } }
- 在路由中配置:
from("mybatis:selectDataChanges?statementType=SelectList&initialDelay=1300&delay=5000") .autoStartup("true") .routeId("dataChanges") .consumerErrorHandler(new CustomPollingErrorHandler(consumer)) // 绑定自定义错误处理器 .choice().when(body().isNotNull()) .log("Consuming data change: ${body}") .to("direct:sendDataChangeMessage");
说明
- 路由级的
errorHandler和onException只处理消息进入路由后(即from之后的步骤)发生的异常,因此对轮询阶段的异常无效。 - 优先推荐方案1,既能修改日志级别,还能灵活扩展重试逻辑、告警等需求。
内容的提问来源于stack exchange,提问作者dcode
相关产品推荐
相关产品推荐

