2016-10-14 1 views
0

Есть ли способ настроить log4j2 для чтения атрибутов Appender, например, из весеннего боба? Мне особенно любопытно, что в JmsAppender динамически задано целевое назначение на основе параметра, считываемого из базы данных, а не из контекста JNDI.log4j2 queue/topic configuration by spring

BR Золтан

ответ

0

Ваш лучший шанс продлить JMSAppender и переопределить методы Append в регистраторе. Хорошим примером является here

В этом случае класс распространяется и использует AMQ для размещения этих сообщений. Вы должны иметь возможность расширить это из БД и использовать API, чтобы получить дескриптор очереди или темы и начать добавлять в нее сообщения. Это предполагает, что у вас есть необходимые клиентские библиотеки и разрешения для подключения к поставщику сообщений (например, в WMQ, вам может понадобиться имя QM, очередь, хост, порт) из БД (в вашем случае). Затем расширенный JMS-приложение можно использовать в вашей конфигурации LOG4J2 для отправки сообщений журнала.

+0

Спасибо за ответ, в этом случае я должен определить полную конфигурацию протоколирования, например, в качестве параметра Spring config java, просто программно, или я могу каким-то образом ссылаться на этот расширяющийся класс в log4j2.xml? – Zoltan

0

кажется, что я нашел гибридный soution, который является очень полезным, пользовательским JmsAppender в сочетании с пружинным контекстом:

@Plugin(name = "OwnJmsAppender", category = "Core", elementType = "appender", printObject = true) 
public class OwnJmsAppender extends AbstractAppender { 

private final Lock lock = new ReentrantLock(); 
private Session session; 
private Connection connection; 
private Destination destination; 
private MessageProducer producer; 

protected OwnJmsAppender(String name, Filter filter, Layout<? extends Serializable> layout, final boolean ignoreExceptions) { 
    super(name, filter, layout, ignoreExceptions); 
    init(); 
} 

@Override 
public void append(LogEvent le) { 
    this.lock.lock(); 
    try { 
     if (connection == null) { 
      init(); 
     } 
     byte[] bytes = getLayout().toByteArray(le); 
     TextMessage message = session.createTextMessage(new String(bytes, Charset.forName("UTF-8"))); 
     producer.send(message); 
    } catch (JMSException e) { 
     LOGGER.error(e); 
    } finally { 
     this.lock.unlock(); 
    } 
} 

@Override 
public void stop() { 
    super.stop(); 
    try { 
     session.close(); 
     connection.close(); 
    } catch (JMSException e) { 
     LOGGER.error(e); 
    } 

} 

/** 
* Reading attributes from log4j2.xml configuration by {@link PluginElement} 
* annotation. Also initiates the logger. 
* 
* @param name 
* @param layout 
* @param filter 
* @return 
*/ 
@PluginFactory 
public static OwnJmsAppender createAppender(@PluginAttribute("name") String name, 
     @PluginElement("PatternLayout") Layout<? extends Serializable> layout, @PluginElement("Filter") final Filter filter) { 
    if (name == null) { 
     LOGGER.error("No name provided for OwnJmsAppender"); 
     return null; 
    } 

    return new OwnJmsAppender(name, filter, getLayout(layout), true); 
} 

private static Layout<? extends Serializable> getLayout(Layout<? extends Serializable> layout) { 
    Layout<? extends Serializable> finalLayout = layout; 
    if (finalLayout == null) { 
     finalLayout = PatternLayout.createDefaultLayout(); 
    } 
    return finalLayout; 
} 

private void init() { 
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CommonDbConfig.class); 
    ParameterStorage parameterStorage = (DatabaseParameterStorage) context.getBean("databaseParameterStorage"); 
    // the parameterStorage springbean reads params from database 
    String brokerUri = parameterStorage.getStringValue("broker.url"); 
    String queueName = "logQueue"; 
    context.close(); 

    try { 
     ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUri); 
     connection = connectionFactory.createConnection(); 
     connection.start(); 
     session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 
     destination = session.createQueue(queueName); 
     producer = session.createProducer(destination); 
     producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 
    } catch (JMSException e) { 
     LOGGER.error(e); 
    } 
} 

}

И вызвать его из log4j2.xml:

<Configuration> 
    <Appenders> 
     <OwnJmsAppender name="jmsQueue"> 
      <PatternLayout pattern="%maxLen{%d{DEFAULT} [%p] - %m %xEx%n}{500}" /> 
     </OwnJmsAppender> 
</Appenders> 
<Loggers> 
    <Logger name="com.your.package" level="info" additivity="false"> 
     <AppenderRef ref="jmsQueue" /> 
    </Logger> 
</Loggers> 
</Configuration>