簡體   English   中英

將spring bean注入自定義的logback過濾器

[英]Inject spring bean into custom logback filter

為了減少應用程序中存在的日志記錄量,我們決定在每個客戶端的基礎上啟用/禁用某些方法的日志記錄。

public class LoggingFilter extends Filter<ILoggingEvent> {

@Autowired
private MethodNameValidator validator;

@Override
public FilterReply decide(ILoggingEvent event) {
    Map<String, String> mdcProperties = event.getMDCPropertyMap();

    if (mdcProperties.isEmpty()) {
        return FilterReply.ACCEPT;
    }

    String accountId = mdcProperties.get(MDCUtil.ACCOUNT_ID);
    String methodName = mdcProperties.get(MDCUtil.METHOD_NAME);

    if (validator.isValidMethodName(accountId, methodName)) {
        return FilterReply.ACCEPT;
    }

    return FilterReply.DENY;
}

}

上面定義的自定義過濾器具有一個驗證組件,在該組件中實現了方法驗證邏輯。

驗證器是一個Spring Bean(也通過JMX公開用於外部配置)。

我無法將MethodNameValidator bean注入到過濾器中。

過濾器也是一個bean。

有沒有辦法做到這一點?

如果我可以動態設置一個Logback過濾器,那么我可以將過濾器初始化為Bean,按名稱獲取所需的記錄器並應用該過濾器。

無法通過提供的Logback api知道如何執行此操作。

這對我有用。

@Component
public class DiscoveringPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    ApplicationContext applicationContext;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if(bean instanceof CustomLoggingFilter){
            Map<String, TurboFilter> filterBeans = applicationContext.getBeansOfType(TurboFilter.class);
            for (TurboFilter filter : filterBeans.values()) {
                LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
                loggerContext.addTurboFilter(filter);
            }
        }
        return bean;

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}

2。

@Named("customLoggingFilter")
public class CustomLoggingFilter extends TurboFilter {

    @Autowired
    private TestService ts;

    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
        System.out.println(ts.doTest());
        return FilterReply.ACCEPT;
    }
}

那就是我們釘牢的方式。 Turbo過濾器代替事件過濾器。 謝謝 ;)

//filter definition
public class MethodLoggingFilter extends TurboFilter {


private MethodNameValidator  methodNameValidator ;

public MethodLoggingFilter(MethodNameValidator methodNameValidator) {
    this.methodNameValidator = methodNameValidator;
}

@Override
public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
    return shouldApplyFilter(level, MDCUtils.getSmsChannelId(), MDCUtils.getMethodName()) ? FilterReply.DENY : FilterReply.NEUTRAL;
}

private boolean shouldApplyFilter(Level level, String accountId, String methodName) {

    if (level == Level.WARN || level == Level.ERROR) {
        return false;//warn and error are logged for any method
    }

    if (methodName == null) {
        return false;
    }

    Integer accountId = accountId != null ? Integer.valueOf(accountId) : null;

    return !methodNameValidator .isLoggingAllowed(accountId, methodName);
}

}
//configuration

    @Bean
public MethodLoggingFilter methodLoggingFilter(MethodNameValidator  methodNameValidator) {
    MethodLoggingFilter filter = new MethodLoggingFilter(methodNameValidator);

    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    loggerContext.addTurboFilter(filter);

    return filter;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM