2016-10-14 4 views
0

たとえば、spring beanからAppender属性を読み取るようにlog4j2を設定する方法はありますか?特に、JmsAppenderでは、JNDIコンテキストではなくデータベースから読み取られたパラメータに基づいて、ターゲット宛先を動的に設定することに興味があります。バネによるlog4j2キュー/トピック設定

BR ゾルタン

答えて

0

あなたの最高のチャンスはJMSAppenderを拡張し、ロガーでアペンドメソッドをオーバーライドすることです。良い例はhere

この場合、AMQを拡張してこれらのメッセージを投稿します。これをDBから拡張し、APIを使用してQueueまたはTopicへのハンドルを取得し、メッセージを追加することができるはずです。これは、適切なクライアントライブラリとメッセージングプロバイダに接続する権限を持っていることを前提としています(たとえば、WMQではQM名、キュー、ホスト、ポートが必要です)。ログメッセージを送信するために、拡張JMSアペンダをLOG4J2コンフィグレーションで使用できます。

+0

答えをありがとう、この場合、私は完全にロギング設定を定義する必要があります。たとえば、バネ設定の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> 
関連する問題