【问题标题】:How to construct log receiver in Java?如何在 Java 中构造日志接收器?
【发布时间】:2012-08-13 12:07:45
【问题描述】:

我想创建一个Receiver 来收集和管理 JMSAppender 发送的日志。现在它只工作 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();
        }
    }
}

【问题讨论】:

  • @HotLicks JMS Topic 是由 JMSAppender 创建的,我的问题是如果我必须等待所有日志关闭文件,如何实时处理日志。

标签: java log4j jms appender


【解决方案1】:

不要在构造函数中关闭打印编写器并删除您的Thread.sleep()。您的程序不会终止,因为您正在调用 conn.start();,这会在 JMS 客户端中创建等待线程。

pw.println() 之后添加pw.flush();onMessage()

编辑: 您不必关闭文件。但是,如果您想创建干净的实现,请在关闭挂钩中执行。

【讨论】:

  • 好的,那么consumer.close(); sess.close(); conn.close(); System.exit(1); 呢?我也应该删除它吗?
【解决方案2】:

我觉得我在这里指出了显而易见的事情,但您确实意识到您正在等待 30 秒在您的构造函数中

如果您想在 30 秒后关闭连接,那么我建议您使用 Timer 并在那里执行线程安全关闭连接。

在您的构造函数中暂停的后果是,当其他线程调用onMessage 时,您的对象还没有完成创建,可能会出现异常行为。

【讨论】:

  • 好的,我知道了。但是,为了证明自己的合理性,我使用this tutorial 来做到这一点。我没有注意到删除日志记录是最愚蠢的事情,但离开 Thread.sleep()
  • 天哪,该教程的作者该被枪毙了!
【解决方案3】:

那是因为你在这 30 秒后关闭了它,然后甚至退出了​​ jvm。

在 JVM 退出时关闭:Runtime.addShutdownHook

【讨论】:

  • 好吧,听起来很合理 :) 那么关闭文件呢?每个日志后我应该何时关闭文件以保存它?日志查看器是必需的
  • 抱歉没有检查链接。现在修好了。我看到你找到了更好的方法。恭喜。
【解决方案4】:

最后我写了receiver:

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

使用文件接收器:

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


    }
}

和标准输出接收器

public class StdoutReceiver {

    public static void logOnConsole(LoggingEvent event) {

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

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2021-10-23
    相关资源
    最近更新 更多