我如何监听日志中抛出的错误?

时间:2014-08-31 22:47:12

标签: java

我正在试图弄清楚如何在Java中监听错误。我想要做的是当一个错误被抛到控制台,程序将检测它并简化它(堆栈跟踪可能是可怕的!)。

以下是我的尝试:

        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
        {
            @Override
            public void uncaughtException(Thread t, Throwable e)
            {
                // do some good stuff here, like logging or sending an alert email to the Support team
                System.out.println("EXCEPTION CAUGHT!");
                System.out.println(e.getMessage());
            }
        });

但不幸的是,它不是说EXCEPTION CAUGHT!发生错误。我应该这样做,还是有一些方法可以在更新时监听System.out日志本身?

1 个答案:

答案 0 :(得分:2)

由于缺乏答案,但很多讨论可能发生的事情是你的框架设置了一个吞下你的异常的自定义处理程序(例如几乎每个web框架)。

这里有一些代码来说明它是如何工作的,因为有一个默认的处理程序,然后每个线程或线程组都可以拥有自己的处理程序。

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;


    public class Tests 
    {
        public static void main(String ... args)
        {       
            Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() 
            {

                @Override
                public void uncaughtException(Thread t, Throwable e) 
                {
                    System.out.print("[Handler Handling]\t");
                    System.out.print(t.getName());
                    System.out.print("\n");
                    e.printStackTrace(System.out);
                    System.out.println("[End Handling]");
                }
            }); 

            new Thread()
            {
                {
                    //Disable this handler
                    this.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

                        @Override
                        public void uncaughtException(Thread thread, Throwable throwable) {
                            System.out.print("[Different Handling]\t");
                            System.out.print(thread.getName());
                            System.out.print("\n");
                            throwable.printStackTrace(System.out);
                            System.out.println("[End Different Handler]");
                        }
                    });
                }
                public void run()
                {
                    throw new RuntimeException("This is thrown in the child thread.");
                }
            }.start();

            try 
            {
                Thread.sleep(500);
            } 
            catch (InterruptedException e1) 
            {
                e1.printStackTrace();
            }

            JFrame gui = new JFrame();
            gui.setSize(400, 300);
            gui.setTitle("Swing Thread");
            JButton error = new JButton("Throw Error");
            error.addActionListener(
                new ActionListener()
                {
                    @Override
                    public void actionPerformed(ActionEvent arg0) 
                    {
                        throw new RuntimeException("This exception happens in the Swing thread");
                    }

                });

            gui.add(error);
            gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            gui.setVisible(true);

            throw new RuntimeException("This is thrown in the main thread.");
        }
    }

这将提供以下输出(如果您点击按钮,则会提供类似的内容):

[Different Handling]    Thread-0
java.lang.RuntimeException: This is thrown in the child thread.
    at Tests$2.run(Tests.java:45)
[End Different Handler]
[Handler Handling]  main
java.lang.RuntimeException: This is thrown in the main thread.
    at Tests.main(Tests.java:77)
[End Handling]
[Handler Handling]  AWT-EventQueue-0
java.lang.RuntimeException: This exception happens in the Swing thread
    at Tests$3.actionPerformed(Tests.java:68)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    <...snipped for brevity...>
[End Handling]

因此,如果没有更多信息,就无法完全回答您的问题。例如,如果您使用JavaFX,则处理未捕获的异常有不同的模式。这完全取决于您的框架和情况。实际上,如果你是在主线程上设置处理程序并从那里开始那么这应该没有问题。