簡體   English   中英

如何將異常stacktrace記錄到調試級別?

[英]How to log exception stacktrace into debug level?

這是akka中使用的調試級別功能的列表:

def debug(message : scala.Predef.String)
def debug(template : scala.Predef.String, arg1 : scala.Any)
def debug(template : scala.Predef.String, arg1 : scala.Any, arg2 : scala.Any)
def debug(template : scala.Predef.String, arg1 : scala.Any, arg2 : scala.Any, arg3 : scala.Any)
def debug(template : scala.Predef.String, arg1 : scala.Any, arg2 : scala.Any, arg3 : scala.Any, arg4 : scala.Any)

以下是錯誤級別功能列表:

def error(cause : scala.Throwable, message : scala.Predef.String)
def error(cause : scala.Throwable, template : scala.Predef.String, arg1 : scala.Any)
def error(cause : scala.Throwable, template : scala.Predef.String, arg1 : scala.Any, arg2 : scala.Any)
def error(cause : scala.Throwable, template : scala.Predef.String, arg1 : scala.Any, arg2 : scala.Any, arg3 : scala.Any)
def error(cause : scala.Throwable, template : scala.Predef.String, arg1 : scala.Any, arg2 : scala.Any, arg3 : scala.Any, arg4 : scala.Any)

因為在高負載系統中使用了代碼,所以我只需要在調試級別記錄異常stacktrace。 要在調試級別記錄日志,我必須寫:

//some where in try catch block
val log : akka.event.LoggingAdapter
val e : Exception

if (log.isDebugEnabled) {
    log.error(e, "Unexpected error")
}

除了混合級別以外,akka中還有更好的替代方法嗎?

這是一個類型類,它以如下方式擴展了Akka日志記錄:可以在warninginfodebug級別上記錄throwables:

AkkaThrowableLogging

import java.io.{PrintWriter, StringWriter}
import akka.event.LoggingAdapter

object AkkaThrowableLogging {
  implicit class LoggingAdapterOps(logger: LoggingAdapter) {

    private def throwableStr(t: Throwable): String = {
      val sw = new StringWriter()
      val pw = new PrintWriter(sw, true)
      t.printStackTrace(pw)
      sw.getBuffer.toString
    }

    private def concat(cause: Throwable, message: String) = s"$message\n${throwableStr(cause)}"

    /**
      * Log message at warning level, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def warning(cause: Throwable, message: String): Unit =
      logger.warning(concat(cause, message))

    /**
      * Message template with 1 replacement argument, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def warning(cause: Throwable, template: String, arg1: Any): Unit =
      logger.warning(concat(cause, template), arg1)

    /**
      * Message template with 2 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def warning(cause: Throwable, template: String, arg1: Any, arg2: Any): Unit =
      logger.warning(concat(cause, template), arg1, arg2)

    /**
      * Message template with 3 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def warning(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any): Unit =
      logger.warning(concat(cause, template), arg1, arg2, arg3)

    /**
      * Message template with 4 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def warning(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit =
      logger.warning(concat(cause, template), arg1, arg2, arg3, arg4)

    /**
      * Log message at info level, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def info(cause: Throwable, message: String): Unit =
      logger.info(concat(cause, message))

    /**
      * Message template with 1 replacement argument.
      * @see [[LoggingAdapter]]
      */
    def info(cause: Throwable, template: String, arg1: Any): Unit =
      logger.info(concat(cause, template), arg1)

    /**
      * Message template with 2 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def info(cause: Throwable, template: String, arg1: Any, arg2: Any): Unit =
      logger.info(concat(cause, template), arg1, arg2)

    /**
      * Message template with 3 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def info(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any): Unit =
      logger.info(concat(cause, template), arg1, arg2, arg3)

    /**
      * Message template with 4 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def info(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit =
      logger.info(concat(cause, template), arg1, arg2, arg3, arg4)

    /**
      * Log message at debug level, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def debug(cause: Throwable, message: String): Unit =
      logger.debug(concat(cause, message))

    /**
      * Message template with 1 replacement argument.
      * @see [[LoggingAdapter]]
      */
    def debug(cause: Throwable, template: String, arg1: Any): Unit =
      logger.debug(concat(cause, template), arg1)

    /**
      * Message template with 2 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def debug(cause: Throwable, template: String, arg1: Any, arg2: Any): Unit =
      logger.debug(concat(cause, template), arg1, arg2)

    /**
      * Message template with 3 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def debug(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any): Unit =
      logger.debug(concat(cause, template), arg1, arg2, arg3)

    /**
      * Message template with 4 replacement arguments, including the exception that caused the error.
      * @see [[LoggingAdapter]]
      */
    def debug(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit =
      logger.debug(concat(cause, template), arg1, arg2, arg3, arg4)
  }
}

用法

import AkkaThrowableLogging._
log.warning(new Exception("FooBarBaz"), "Hello {}", "world")

輸出:

[WARN] [10/16/2016 19:05:50.614] [ScalaTest-run-running-AkkaThrowableLoggingTest] [AkkaThrowableLoggingTest(akka://AkkaTest)] Hello world
java.lang.Exception: FooBarBaz
    at test.AkkaThrowableLoggingTest$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(AkkaThrowableLoggingTest.scala:12)
    at test.AkkaThrowableLoggingTest$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(AkkaThrowableLoggingTest.scala:11)
    at test.AkkaThrowableLoggingTest$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(AkkaThrowableLoggingTest.scala:11)
    at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22)
    at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
    at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
    at org.scalatest.Transformer.apply(Transformer.scala:22)
    ...

警告:錯誤級別的日志輸出可能與較低級別的日志輸出不同

由於Akka的LoggingAdapter不提供用於執行此操作的API,因此無法將該異常傳遞給基礎的日志記錄框架(例如log4j,logback等)。 因此,該異常無法在該級別上設置格式,而是由throwableStr函數處理,該函數使用默認的Java格式(調用printStackTrace時得到的信息)。 因此, log.error(e, ...)的日志輸出可能log.warning(, ...)log.info(e, ...)log.debug(e, ...) log.info(e, ...)的日志輸出不同log.debug(e, ...) 在大多數情況下,不會有任何區別,因為異常的格式仍然是默認格式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM