有时候项目里面写的try catch部分,无法通过全局异常或者通过实现handlerExceptionResolver 来捕获到。比如一些sql异常、空指针之类导致的内部错误。这时候可以通过日志的级别来打印出来。实现代码如下
package com.gwm.lafeng.filter.log; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.turbo.TurboFilter; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.Map; /** * 启动加载-过滤异常日志 * @author fanht * @date 2022-03-22 14:12 * @versio */ @Component public class DiscoveringPostProcessor implements BeanPostProcessor, ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(bean instanceof LafengLogFilter){ Map<String, TurboFilter> filterBeans = applicationContext.getBeansOfType(TurboFilter.class); for (TurboFilter filter : filterBeans.values()) { LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); loggerContext.addTurboFilter(filter); } } return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName); } }
这个主要是通过TurboFilter来实现的
package com.gwm.lafeng.filter.log; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.turbo.TurboFilter; import ch.qos.logback.core.spi.FilterReply; import com.alibaba.fastjson.JSONObject; import com.gwm.lafeng.filter.DingdingAlarmUtil; import com.gwm.lafeng.filter.IPUtil; import com.gwm.lafeng.filter.VerifyConst; import org.slf4j.MDC; import org.slf4j.Marker; import org.springframework.stereotype.Component; import java.text.MessageFormat; /** * 异常日志堆栈-用于非运行时异常的告警提示 * @author fanht * @date 2022-03-21 17:28 * @versio 1.0 */ @Component public class LafengLogFilter extends TurboFilter { @Override public FilterReply decide(Marker marker, Logger logger, Level level, String s, Object[] objects, Throwable throwable) { //todo 如果是非运行时异常 发送钉钉告警。排除运行时异常 if(throwable != null && level.equals(Level.ERROR) && !logger.getName().equals(VerifyConst.UN_SEND_CLASS)){ String mess = MessageFormat.format("接口异常告警:项目:{0},环境:{1},IP:{2},traceId:{3},接口地址:{4},错误信息:{5},异常信息:{6}", DingdingAlarmUtil.applicationName, DingdingAlarmUtil.env, IPUtil.initIp(), MDC.get("traceId"), logger.getName(), s, JSONObject.toJSON(throwable.getMessage().length() >4000 ? throwable.getMessage().substring(0,4000):throwable.getMessage())); DingdingAlarmUtil.sendDingdingAlerm(mess, DingdingAlarmUtil.dingdingTokenUrl); } return FilterReply.ACCEPT; } }