使用 Scala 记录消息

您可以使用 SLF4J API (http://www.slf4j.org/),将使用 Scala 编写的函数或过程处理程序发出的消息记录到日志中。当您 设置事件表 来存储日志条目时,Snowflake 会将处理程序代码生成的日志条目存储在表中。

您可以使用 Snowflake 上的 Snowflake 遥测库包含的 SLF4J API (http://www.slf4j.org/)。为此,请在创建函数或过程时,在 PACKAGES 子句中包含以下值:com.snowflake:telemetry:latest

有关使用 Maven 打包代码时包含遥测库的信息,请参阅 设置 Java 和 Scala 环境以使用遥测类

备注

使用 Snowflake 遥测库将其他库添加到函数或过程的执行环境中。有关更多信息,请参阅 Snowflake 遥测包依赖项

备注

SLF4J 不支持 FATAL 级别的日志记录消息。对于用 Java 或 Scala 编写的处理程序,FATAL 级别会被视为 ERROR 级别。

例如,如果将 LOG_LEVEL 参数设置为 FATAL,就会引入来自 Java 或 Scala 处理程序 ERROR 级别的消息。

有关在 Snowflake 中设置日志记录和检索消息的一般信息,请参阅 来自函数和过程的日志记录消息

通过代码记录之前,您必须:

  • 设置事件表来收集通过处理程序代码记录的消息。

    有关更多信息,请参阅 事件表概述

  • 确保您设置了日志记录级别,以便将所需的消息存储在事件表中。

    有关更多信息,请参阅 为日志、指标和跟踪设置级别

添加自定义属性

创建日志条目时,可以在键值对中添加您自己的属性。Snowflake 将这些自定义属性保存到事件表的 RECORD_ATTRIBUTES 列 中。

要添加自定义属性,请调用 slf4j 流畅 API 的方法,例如 Logger.atInfoLogger.atError。使用这些方法在日志条目中设置键值对。每个返回一个 org.slf4j.spi.LoggingEventBuilder (https://www.slf4j.org/apidocs/org/slf4j/spi/LoggingEventBuilder.html),您可以用它来设置日志消息。

以下示例中的代码将消息“Logging with attributes”记录到事件表的 VALUE 列中。它还向 RECORD_ATTRIBUTES 列添加了一个自定义属性。

CREATE OR REPLACE PROCEDURE do_logging_scala()
RETURNS VARCHAR
LANGUAGE SCALA
RUNTIME_VERSION = '2.12'
PACKAGES=('com.snowflake:telemetry:latest', 'com.snowflake:snowpark:latest')
HANDLER = 'ScalaLoggingHandler.doThings'
AS
$$
  import org.slf4j.Logger
  import org.slf4j.LoggerFactory
  import com.snowflake.snowpark.Session

  class ScalaLoggingHandler {
    private val logger: Logger = LoggerFactory.getLogger(getClass)

    def doThings(session: Session): String = {
      logger.atInfo().addKeyValue("custom1", "value1").setMessage("Logging with attributes").log();
      return "SUCCESS"
    }
  }
$$;
Copy

Logger.atInfo 调用的输出在事件表中如下所示。请注意,RECORD_ATTRIBUTES 列将包括 Snowflake 自动添加的属性。

------------------------------------------------------------------
| VALUE                     | RECORD_ATTRIBUTES                  |
------------------------------------------------------------------
| "Logging with attributes" | {                                  |
|                           |   "custom1": "value1",             |
|                           |   "thread.name": "Thread-5"        |
|                           | }                                  |
------------------------------------------------------------------

Scala 示例

下面示例中的代码引用了 Snowflake 遥测库,并从中获取了一个日志记录器。它会在 INFO 级别记录一条消息。它还会记录一个异常错误。

有关可用于在特定级别记录日志的方法的更多信息,请参阅 SLF4J 方法 (https://www.slf4j.org/apidocs/org/slf4j/Logger.html)。

CREATE OR REPLACE PROCEDURE do_logging()
RETURNS VARCHAR
LANGUAGE SCALA
RUNTIME_VERSION = '2.12'
PACKAGES=('com.snowflake:snowpark:latest', 'com.snowflake:telemetry:latest')
HANDLER = 'ScalaLoggingHandler.doThings'
AS
$$
  import org.slf4j.Logger
  import org.slf4j.LoggerFactory
  import com.snowflake.snowpark.Session

  class ScalaLoggingHandler {
    private val logger: Logger = LoggerFactory.getLogger(getClass)

    logger.info("Logging from within the Scala constructor.")

    def doThings(session: Session): String = {
      logger.info("Logging from Scala method start.")

      try {
        throwException
      } catch {
        case e: Exception => logger.error("Logging an error from Scala handler: " + e.getMessage())
        return "ERROR"
      }
      return "SUCCESS"
    }

    // Simulate a thrown exception to catch.
    @throws(classOf[Exception])
    private def throwException = {
      throw new Exception("Something went wrong.")
    }
  }
$$
;
Copy

您可以通过对事件表执行 SELECT 命令,来访问日志消息。有关更多信息,请参阅 查看日志消息

以下示例中的代码查询存储日志消息的事件表。该查询报告处理程序类中每个日志条目的严重性和消息。

SET event_table_name='my_db.public.my_event_table';

SELECT
  RECORD['severity_text'] AS SEVERITY,
  VALUE AS MESSAGE
FROM
  IDENTIFIER($event_table_name)
WHERE
  SCOPE['name'] = 'ScalaLoggingHandler'
  AND RECORD_TYPE = 'LOG';
Copy

前面的示例生成以下输出。

---------------------------------------------------------------------------
| SEVERITY | MESSAGE                                                      |
---------------------------------------------------------------------------
| "INFO"   | "Logging from within the Scala constructor."                 |
---------------------------------------------------------------------------
| "INFO"   | "Logging from Scala method start."                           |
---------------------------------------------------------------------------
| "ERROR"  | "Logging an error from Scala handler: Something went wrong." |
---------------------------------------------------------------------------
语言: 中文