0

ReceiverJMSAppender が送信するログを収集して管理するための を作成したいと考えています。現在は 30 秒しか動作しませんThread.sleep(30000);が ( )、システムからのすべてのログを待機する必要があります。pw.close();ファイル内のすべてのログを表示するために閉じる必要がある場合、どうすればよいですか? ファイルからログをログ ビューアーに読み込み、リアルタイムで表示したいと考えています。

public class Receiver implements MessageListener {

    PrintWriter pw = new PrintWriter("result.log");

    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);

        Thread.sleep(30000);
        consumer.close();
        sess.close();
        conn.close();
        pw.close();
        System.exit(1);
    }

    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())); 

            System.out.println("zapisujemy do pliku");
            pw.println("["+ nowAsString + "]" + 
                    " [" + event.getThreadName()+"]" +
                    " ["+ event.getLoggerName() + "]" +
                    " ["+ event.getMessage()+"]");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
4

4 に答える 4

1

コンストラクターで印刷ライターを閉じて、Thread.sleep(). conn.start();JMS クライアントに待機中のスレッドを作成する呼び出しを行っているため、プログラムは終了しません。

pw.flush();の後pw.println()に追加onMessage()

編集: ファイルを閉じる必要はありません。ただし、クリーンな実装を作成する場合は、シャットダウン フックで行います。

于 2012-08-13T12:13:13.837 に答える
0

ここで明らかなことを指摘しているように感じますが、コンストラクターで 30 秒待っていることに気付きましたか?

30 秒後に接続を閉じたい場合はTimer、そこで接続をスレッドセーフに閉じることをお勧めします。

コンストラクターで一時停止すると、他のスレッドが を呼び出したときonMessageに、オブジェクトがまだ作成されておらず、不規則な動作をする可能性があります。

于 2012-08-13T12:27:29.427 に答える
0

最後に、レシーバーを書きました:

public class Receiver implements MessageListener {

    static Connection conn;
    ActiveMQConnectionFactory factory;
    static Session sess;
    static MessageConsumer consumer;


    public Receiver() throws Exception {

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

    }

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

        Runtime.getRuntime().addShutdownHook(new Thread(new ShutDownListener(consumer, sess, conn)));
        new Receiver();
    }


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

            /*
             * log on console and into a file
             */

            FileReceiver.logToFile(event);
            StdoutReceiver.logOnConsole(event);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

FileReceiver の場合:

public class FileReceiver {

    static PrintWriter pw;
    static DateFormat df;

    static {
        try {
            df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
            pw = new PrintWriter("result.log");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                pw.close();
                System.exit(1);
            }
        });
    }

    public static void logToFile(LoggingEvent event) {
        String nowAsString = df.format(new Date(event.getTimeStamp()));

        pw.println("[" + nowAsString + "]" + " [" + event.getThreadName() + "]"
                + " [" + event.getLoggerName() + "]" + " ["
                + event.getMessage() + "]");
        pw.flush();


    }
}

および StdOutReceiver

public class StdoutReceiver {

    public static void logOnConsole(LoggingEvent event) {

        System.out.println("[" + event.getTimeStamp() + "]" + " ["
                + event.getThreadName() + "]" + " [" + event.getLoggerName()
                + "]" + " [" + event.getMessage() + "]");
    }

}
于 2012-08-14T09:25:05.863 に答える
0

これは、30 秒後にそれを閉じてから、jvm を終了するためです。

JVM 出口でクローズを行います。Runtime.addShutdownHook

于 2012-08-13T12:10:52.387 に答える