5

ロギング コンポーネントを分散システムに追加しようとしています。AspectJ現在のソースコードの連鎖を避けるために書かれています。ログの送信にsocket appenderを使っていますが、もっと効果的なものを試してみたいです。

JMSAppenderと を使用する必要があると聞きましたAsyncAppenderが、構成に失敗しました。Receiverログを収集してデータベースと GUI に渡す (私は を使用します)を作成する必要がありますChainSawか?

私はturorial1tutorial2に従おうとしましたが、十分に明確ではありません.

ここに画像の説明を入力

編集:

私が用意した小さなデモでは、リクエストに対して 6 つのログを送信しました (3 つのコンポーネントのシミュレーション)。

[2012-08-08 15:40:28,957] [request1344433228957] [Component_A] [start]
[2012-08-08 15:40:32,050] [request1344433228957] [Component_B] [start]
[2012-08-08 15:40:32,113] [request1344433228957] [Component_C] [start]
[2012-08-08 15:40:32,113] [request1344433228957] [Component_C] [end - throwing]
[2012-08-08 15:40:32,144] [request1344433228957] [Component_B] [end]
[2012-08-08 15:40:32,175] [request1344433228957] [Component_A] [end]

ソケットアペンダーの使用。したがって、私のlog4j.propertiesは次のとおりです。

log4j.rootLogger=DEBUG, server

log4j.appender.server=org.apache.log4j.net.SocketAppender
log4j.appender.server.Port=4712
log4j.appender.server.RemoteHost=localhost
log4j.appender.server.ReconnectionDelay=1000

だから私は走る

>java -classpath log4j-1.2.17.jar org.apache.log4j.net.SimpleSocketServer 4712 log4j-server.properties

設定あり

log4j.rootLogger=DEBUG, CA, FA

#
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=[%d] [%t] [%c] [%m]%n

#
log4j.appender.FA=org.apache.log4j.FileAppender
log4j.appender.FA.File=report.log
log4j.appender.FA.layout=org.apache.log4j.PatternLayout
log4j.appender.FA.layout.ConversionPattern=[%d] [%t] [%c] [%m]%n

次に、ログをファイルから Chainsaw に送信します。

ここに画像の説明を入力

絶対に基本的なことですが、もっとうまくやる方法を学びたいです。まず、ログを非同期で送信したいと思います。次に、ログをファイルに渡すなどの非常に単純なレシーバーを作成します。

上記のチュートリアルに従おうとしましたが、失敗しました。質問は次のとおりです。設定例をいくつか提供していただけますか? ファイルReceiver.javaの例log4.properties

4

4 に答える 4

2

NFSまたはCDFSを使用して、すべてのマシンにドライブをマウントします。各アプリケーションインスタンスに異なるファイルに書き込んでもらいます。使用するマシンの数に関係なく、1つのディレクトリ(またはドライブ)ですべてのログを見つけることができます。

ラウンドトリップが50ミリ秒を超えるなど、待ち時間が長いグローバルWANでNFSまたはCDFSを使用することはありません。このため、私はJMSを使用しました(ただし、log4jは使用しませんでした)

于 2012-08-08T11:23:48.340 に答える
2

syslog と組み込みの syslog アペンダーをお勧めします。信頼性の高いログ (おそらく +Asyc アペンダー) には TCP を使用し、ファイア アンド フォーゲット ログには UDP を使用します。必要に応じて、rsyslog 構成があります。

于 2012-08-16T20:35:13.230 に答える
2

最後に、それを構成する方法を見つけました。2つのファイルをsrcフォルダに入れました。

jndi.properties

topic.logTopic=logTopic

および log4j-jms.properties

log4j.rootLogger=INFO, stdout, jms

## Be sure that ActiveMQ messages are not logged to 'jms' appender
log4j.logger.org.apache.activemq=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= 

## Configure 'jms' appender. You'll also need jndi.properties file in order to make it work
log4j.appender.jms=org.apache.log4j.net.JMSAppender
log4j.appender.jms.InitialContextFactoryName=org.apache.activemq.jndi.ActiveMQInitialContextFactory
log4j.appender.jms.ProviderURL=tcp://localhost:61616
log4j.appender.jms.TopicBindingName=logTopic
log4j.appender.jms.TopicConnectionFactoryBindingName=ConnectionFactory

次に、VM 引数を指定してプログラムを実行します

-Dlog4j.configuration=log4j-jms.properties

クラスでログを受け取るReceiver.java

public class Receiver implements MessageListener {

    PrintWriter pw = new PrintWriter("result.log");
    Connection conn;
    Session sess;
    MessageConsumer consumer;

    public Receiver() throws Exception {


        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        Connection conn = factory.createConnection();
        Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        conn.start();
        MessageConsumer consumer = sess.createConsumer(sess.createTopic("logTopic"));
        consumer.setMessageListener(this);
    }

    public static void main(String[] args) throws Exception {
        new Receiver();

    }

    public void onMessage(Message message) {
        try {
            LoggingEvent event = (LoggingEvent) ((ActiveMQObjectMessage) message).getObject();

            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS"); 
            String nowAsString = df.format(new Date(event.getTimeStamp())); 

            pw.println("["+ nowAsString + "]" + 
                    " [" + event.getThreadName()+"]" +
                    " ["+ event.getLoggerName() + "]" +
                    " ["+ event.getMessage()+"]");
            pw.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
于 2012-08-13T13:27:29.010 に答える
2

私の2セント..何をするにしても、非同期メカニズムを使用してログをレシーバーに配信するようにしてください。そうしないと、最終的にアプリが停止します。別のポイントとして、ログを確実に配信するには、アペンダー自体に組み込まれたフェイルオーバー メカニズムを検討する必要があります。ログを気にする場合は、レシーバーが短時間または長時間オフラインになる可能性があります。フェイルオーバーは確実に必要です。あなたが説明したのと同様のシステムを構築しました (追加して申し訳ありません) が、必要に応じて私たちのアペンダーを使用できます (ダウンロードを見てください)。これは無料で、ソースがあります。ビデオチュートリアルもあります。フェイルオーバーと柔軟な非同期メカニズムに加えて、バックアップ フォールバックがあります。

何個のアペンダーを使用する必要がありますか? jvm ごとに 1 つのアペンダーで問題ありません。構成ファイルはおそらく jvm ごとに作成する必要がありますが、レシーバーをどのように実装するかは不明です。いずれにせよ、アペンダーは少なくともホスト ポート ペアであるレシーバーを見つける必要があります。データベースに関しては、RDBMS での私の経験は非常に悪いものです (nosql に移行しています) が、2 億レコードを超えない場合、ほとんどの商用データベースは多少の努力を必要とします。私が言わなければならない簡単な作業ではありません.商用品質のシステムを構築するのに数年かかりました.いくつかの細い長方形で描画しただけです:)

于 2012-08-08T18:54:33.090 に答える