Как отправить сообщение через веб-сокет в плагине log4j2? - PullRequest
0 голосов
/ 02 августа 2020

Пользовательский плагин log4j инициализируется перед настройкой веб-сокета, что делает невозможным автоматическое подключение SimpMessagingTemplate весенней загрузки. Я также попытался получить класс из контекста приложения, но это не сработало. Как мне подойти к этому?

Пользовательский класс плагина:

@SuppressWarnings("deprecation")
@Plugin(category = "Core", name = "AmtAppender", elementType = "appender")
public class AmtAppender extends AbstractAppender implements ApplicationContextAware{
    private final Logger logger = LogManager.getLogger(this.getClass().getName());
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock();
    private static MongoTemplate mongotemplate;
    private static MongoDbFactory mongodbfactory;
    private String alertcollection=null;
    private AMTBaseProcessor amtBaseProcessor=null;
    private final String DEFAULT_APP_CONFIG_LOCATION = "/application.properties";
    LogQueueDataDTO logdata=new LogQueueDataDTO();
    DateTimeFormatter dateformat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
    private ApplicationContext applicationContext;
    
    protected AmtAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout,
                final boolean ignoreExceptions) {
            super(name,filter,layout,ignoreExceptions);
      }
    
    
    @PluginFactory
    public static AmtAppender createAppender(
      @PluginAttribute("name") String name, 
      @PluginElement("Filter") Filter filter,
      @PluginElement("Layout") Layout<? extends Serializable> layout,
      @PluginAttribute("ignoreExceptions") boolean ignoreExceptions    
      ) {
        return new AmtAppender(name, filter,layout,ignoreExceptions);
    }
    
    private Properties getApplicationProperties() {
         Properties prop = new Properties();
            try {               
                 Resource resource;             
                 resource = new ClassPathResource(DEFAULT_APP_CONFIG_LOCATION);                              
                 prop = PropertiesLoaderUtils.loadProperties(resource);
                 return prop;
            }
            catch (Exception e) {
                 logger.info("IOException in getApplicationProperties() ::"+e);
            }
            return null;
    }
    
    void setMongoTemplate(){         
            Properties prop = getApplicationProperties();
           mongodbfactory=new SimpleMongoDbFactory(new MongoClientURI(prop.getProperty("spring.data.mongodb.uri.alarm")));
            mongotemplate = new MongoTemplate(mongodbfactory);  
        }
     
    private String getAlertCollection() {
         try {
         Properties prop =getApplicationProperties();       
         alertcollection=prop.getProperty("appender.alertCollection");
         if(alertcollection==null)
         logger.info("Alert collection in application properties file is null");
         }
         catch(Exception e) {
             logger.info("Exception :: {}", e);
         }
         return alertcollection;         
     }
    
    @Override   
    public void append(LogEvent event) {
        this.readLock.lock();
        
        if(applicationContext==null) {
            getContext();
        }
        
        try{            
            String datetime=dateformat.format(new Date().toInstant()).toString();
            logdata.setMessage(event.getLevel().name()+" "+datetime+" "+event.getThreadName()+" "+event.getSource().getFileName()+" "+event.getSource().getMethodName()+" :: "+event.getSource().getLineNumber()+" "+event.getMessage().getFormat());
            if(event.getLevel().name().equals("ERROR") ||event.getLevel().name().equals("FATAL") ||event.getLevel().name().equals("WARN")){     
                LogDataProcessorDTO logDataProcessorDTO=amtBaseProcessor.getLogDataProcessorDTO(logdata, true, false);
                mongotemplate.save(logDataProcessorDTO.getProcessedLogData(),alertcollection);  
                getContext().getBean(SimpMessagingTemplate.class).convertAndSend("/websocket/data", logDataProcessorDTO);
            }
            
            }
        catch(Exception e){
            logger.info("Exception in append() ::"+e);  
        }
        finally{
            this.readLock.unlock();
        }
        
    }


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

    public ApplicationContext getContext() {
        return applicationContext;
    }
}

Похоже, что приведенный ниже код не работает. Как мне подойти к этому?

getContext().getBean(SimpMessagingTemplate.class).convertAndSend("/websocket/data", logDataProcessorDTO);

1 Ответ

0 голосов
/ 03 августа 2020

Если вы используете Spring Boot, он инициализирует ведение журнала несколько раз. Только самый первый не будет иметь доступа к свойствам Spring. Если вы можете предоставить другой файл конфигурации, который регистрирует эти события в другом месте назначения, вы можете позволить Log4j извлекать значения для вас с помощью Spring Lookup.

...