【问题标题】:How to capture exception stacktrace (stderr) to file in Scala如何将异常堆栈跟踪(stderr)捕获到 Scala 中的文件
【发布时间】:2018-12-20 23:04:24
【问题描述】:

如何在 Scala 中将异常堆栈跟踪捕获到文件中?我尝试使用System.setErr,但它不起作用,而Console.withErr 只能为代码 sn-p 而不是整个应用程序设置。任何想法? 我想将应用程序的所有未捕获异常记录到一个文件中

编辑:

更多上下文:我在一个 spark-shell 中运行,并在类路径中添加了一个 jar。我所做的是实例化一个类的对象,并且在该类中运行的第一个代码如下,这并没有给我
预期打印

Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
def uncaughtException(t: Thread, e: Throwable): Unit = {
  logger.error("exception logged")
  println("exception logged")
}
})

throw new Exception("my ex")

但我在标准输出和日志文件中都看不到打印

【问题讨论】:

  • 所有未捕获的异常?您的意思是您想吞下所有异常并让应用继续运行吗?
  • “没有用”是什么意思?哪个异常没有被记录?是怎么扔的?您应该发布您的System.setErr() 代码。
  • 我只想在应用死机之前记录堆栈跟踪。我试过的代码使用了这个System.setErr(new PrintStream( new FileOutputStream("a.txt"))),异常只是一个测试throw new Exception("e")
  • @alexpila 你的代码对我有用,我已经用一个例子编辑了我的答案。让我问一下……您是否从 println 或您的记录器框架中看到任何东西(不仅仅是在异常中)?
  • @alexlipa,你读过this吗?我尝试了各种方法来重现您的问题,但我的尝试总是按预期工作。如果没有足够的代码来重现您的问题,我们只能猜测您所看到的。

标签: scala jvm


【解决方案1】:

只需使用 Thread.setUncaughtExceptionHandler:

Java uncaught global exception handler

如果您的应用是单线程的,请使用 Thread.currentThread() 来获取当前线程。

编辑

object ErrorHandling {
  def main(args: Array[String]): Unit = {
    Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
      def uncaughtException(t: Thread, e: Throwable): Unit = {
//        logger.error("exception logged")
        println(s"exception logged: $e")
        e.printStackTrace()
      }
    })
    throw new Exception(s"boom")
  }
}

应该给你类似的东西:

exception logged: java.lang.Exception: boom
java.lang.Exception: boom
    at ErrorHandling$.main(ErrorHandling.scala:10)
    at ErrorHandling.main(ErrorHandling.scala)

【讨论】:

  • 这适用于一个主要的例子。我将其作为 spark 应用程序运行,并且在实例化对象时使用此代码,但它不起作用
  • @alexpila 在处理 spark 时,特别是在分布式集群中时,这是否有效完全取决于执行语句的主机以及异常所在的线程抛出。在没有看到您的代码或了解更多信息的情况下,我什至无法开始告诉您可能出了什么问题,但是在处理 Spark 应用程序时,这绝对不是正确的方法。 Spark 有各种日志,您的异常可能已经在其中之一中。我建议删除所有更改日志的代码并检查 master 和 worker 日志。
  • 我的代码在 master 上运行,我正在登录为我的应用程序创建的自定义记录器。此外,我不仅在记录,还只是打印了一些行,而我在输出中看不到它们。我开始认为这可能与线程有关。我不确定如何在这里提供一小段代码,因为我所拥有的基本上就是我上面写的,整个事情都是在获得 spark 上下文之后发生的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 2011-01-15
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 2013-02-21
相关资源
最近更新 更多