From 11d76c96554cc71c6a941c99222c08c76bd04bf2 Mon Sep 17 00:00:00 2001 From: Gengliang Wang Date: Fri, 29 Mar 2024 13:10:40 -0700 Subject: [PATCH] [SPARK-47576][INFRA] Implement logInfo API in structured logging framework ### What changes were proposed in this pull request? Implement logWarning API in structured logging framework. Also, revise the test case names to make it more reasonable for the `PatternLoggingSuite` ### Why are the changes needed? To enhance Apache Spark's logging system by implementing structured logging. ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? New UT ### Was this patch authored or co-authored using generative AI tooling? No Closes #45777 from gengliangwang/logInfo. Authored-by: Gengliang Wang Signed-off-by: Gengliang Wang --- .../org/apache/spark/internal/Logging.scala | 14 +++++++++++++ .../spark/util/StructuredLoggingSuite.scala | 21 ++++++++++--------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/common/utils/src/main/scala/org/apache/spark/internal/Logging.scala b/common/utils/src/main/scala/org/apache/spark/internal/Logging.scala index 2fed115f3dbbd..0aa93d6289d1d 100644 --- a/common/utils/src/main/scala/org/apache/spark/internal/Logging.scala +++ b/common/utils/src/main/scala/org/apache/spark/internal/Logging.scala @@ -122,6 +122,20 @@ trait Logging { if (log.isInfoEnabled) log.info(msg) } + protected def logInfo(entry: LogEntry): Unit = { + if (log.isInfoEnabled) { + log.info(entry.message) + entry.context.map(_.close()) + } + } + + protected def logInfo(entry: LogEntry, throwable: Throwable): Unit = { + if (log.isInfoEnabled) { + log.info(entry.message, throwable) + entry.context.map(_.close()) + } + } + protected def logDebug(msg: => String): Unit = { if (log.isDebugEnabled) log.debug(msg) } diff --git a/common/utils/src/test/scala/org/apache/spark/util/StructuredLoggingSuite.scala b/common/utils/src/test/scala/org/apache/spark/util/StructuredLoggingSuite.scala index b032649170bc7..5dfd3bb46021b 100644 --- a/common/utils/src/test/scala/org/apache/spark/util/StructuredLoggingSuite.scala +++ b/common/utils/src/test/scala/org/apache/spark/util/StructuredLoggingSuite.scala @@ -58,33 +58,34 @@ abstract class LoggingSuiteBase extends AnyFunSuite // scalastyle:ignore funsuit def expectedPatternForMsgWithMDCAndException(level: String): String - test("Structured logging") { + test("Basic logging") { val msg = "This is a log message" Seq( ("ERROR", () => logError(msg)), - ("WARN", () => logWarning(msg))).foreach { case (level, logFunc) => + ("WARN", () => logWarning(msg)), + ("INFO", () => logInfo(msg))).foreach { case (level, logFunc) => val logOutput = captureLogOutput(logFunc) assert(expectedPatternForBasicMsg(level).r.matches(logOutput)) } } - test("Structured logging with MDC") { + test("Logging with MDC") { Seq( - ("ERROR", () => logError(log"Lost executor ${MDC(EXECUTOR_ID, "1")}.")), - ("WARN", () => logWarning(log"Lost executor ${MDC(EXECUTOR_ID, "1")}."))) - .foreach { + ("ERROR", () => logError(msgWithMDC)), + ("WARN", () => logWarning(msgWithMDC)), + ("INFO", () => logInfo(msgWithMDC))).foreach { case (level, logFunc) => val logOutput = captureLogOutput(logFunc) assert(expectedPatternForMsgWithMDC(level).r.matches(logOutput)) } } - test("Structured exception logging with MDC") { + test("Logging with MDC and Exception") { val exception = new RuntimeException("OOM") Seq( - ("ERROR", () => logError(log"Error in executor ${MDC(EXECUTOR_ID, "1")}.", exception)), - ("WARN", () => logWarning(log"Error in executor ${MDC(EXECUTOR_ID, "1")}.", exception))) - .foreach { + ("ERROR", () => logError(msgWithMDCAndException, exception)), + ("WARN", () => logWarning(msgWithMDCAndException, exception)), + ("INFO", () => logInfo(msgWithMDCAndException, exception))).foreach { case (level, logFunc) => val logOutput = captureLogOutput(logFunc) assert(expectedPatternForMsgWithMDCAndException(level).r.findFirstIn(logOutput).isDefined)