Debezium 日志

Debezium 内置了广泛的日志记录功能,您可以更改日志记录配置来控制哪些日志语句出现在日志中以及日志发送到何处。Debezium(以及 Kafka 和 Kafka Connect)使用 Java 的 Log4j 日志框架。

默认情况下,连接器在启动时会产生大量有用的信息,但在连接器正常处理数据时会产生非常少的日志。这通常在连接器正常运行时已足够,但在连接器行为异常时可能不够。在这种情况下,您可以更改日志记录级别,以便连接器生成更详细的日志消息,描述连接器正在做什么以及没有做什么。

日志概念

在配置日志记录之前,您应该了解 Log4J 的 *日志记录器*、*日志级别* 和 *附加器* 是什么。

日志记录器

应用程序生成的每条日志消息都会发送到一个特定的 *日志记录器*(例如,io.debezium.connector.mysql)。日志记录器以层级结构排列。例如,io.debezium.connector.mysql 日志记录器是 io.debezium.connector 日志记录器的子级,而 io.debezium.connector 日志记录器又是 io.debezium 日志记录器的子级。在层级结构的顶部,*根日志记录器* 定义了其下方所有日志记录器的默认日志记录器配置。

日志级别

应用程序生成的每条日志消息也有一个特定的 *日志级别*

  1. ERROR - 错误、异常和其他严重问题

  2. WARN - *潜在* 的问题和故障

  3. INFO - 状态和一般活动(通常量不大)

  4. DEBUG - 更详细的活动,有助于诊断意外行为

  5. TRACE - 非常详细的活动(通常量很大)

附加器

一个 *附加器* 本质上是日志消息写入的目的地。每个附加器控制其日志消息的格式,让您更能控制日志消息的外观。

要配置日志记录,您需要为每个日志记录器指定所需的级别以及应将这些日志消息写入的附加器。由于日志记录器是层级化的,根日志记录器的配置为它下方所有日志记录器提供了默认值,尽管您可以覆盖任何子(或后代)日志记录器。

理解默认日志配置

如果您在 Kafka Connect 进程中运行 Debezium 连接器,那么 Kafka Connect 会使用 Kafka 安装目录中的 Log4j 配置文件(例如,/opt/kafka/config/connect-log4j.properties)。默认情况下,此文件包含以下配置:

示例 1. connect-log4j.properties 中的默认配置
log4j.rootLogger=INFO, stdout  (1)

log4j.appender.stdout=org.apache.log4j.ConsoleAppender  (2)
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  (3)
log4j.appender.stdout.layout.ConversionPattern=[%d] %p %m (%c)%n  (4)
...
表 1. 默认 connect-log4j.properties 设置说明
属性 描述

1

根日志记录器,定义了默认日志记录器配置。默认情况下,日志记录器包括 INFOWARNERROR 消息。这些日志消息会写入 stdout 附加器。

2

指示 stdout 附加器将日志消息写入控制台,而不是文件。

3

指定 stdout 附加器使用模式匹配算法来格式化日志消息。

4

stdout 附加器使用的模式(有关详细信息,请参阅 Log4j 文档)。

除非您配置其他日志记录器,否则 Debezium 使用的所有日志记录器都继承 rootLogger 配置。

配置日志

默认情况下,Debezium 连接器将所有 INFOWARNERROR 消息写入控制台。您可以通过以下任一方法更改默认日志记录配置:

您还可以使用其他方法通过 Log4j 配置 Debezium 日志。有关更多信息,请搜索有关设置和使用附加器将日志消息发送到特定目的地的教程。

通过配置日志记录器设置日志级别

默认的 Debezium 日志级别提供了足够的信息来显示连接器是否健康。但是,如果连接器不健康,您可以更改其日志级别来解决问题。

通常,Debezium 连接器将其日志消息发送到名称与生成日志消息的 Java 类完全限定名匹配的日志记录器。Debezium 使用包来组织具有相似或相关功能的代码。这意味着您可以控制特定类或特定包内(或其下)所有类的所有日志消息。

过程
  1. 打开 connect-log4j.properties 文件。

  2. 配置连接器的日志记录器。

    以下示例配置了 MySQL 连接器以及连接器使用的数据库模式历史实现器的日志记录器,并将它们设置为记录 DEBUG 级别的消息:

    示例 2. 启用日志记录器并将日志级别设置为 DEBUGconnect-log4j.properties 配置
    ...
    log4j.logger.io.debezium.connector.mysql=DEBUG, stdout  (1)
    log4j.logger.io.debezium.relational.history=DEBUG, stdout  (2)
    
    log4j.additivity.io.debezium.connector.mysql=false  (3)
    log4j.additivity.io.debezium.storage.kafka.history=false
    ...
    表 2. 启用日志记录器并设置日志级别的 connect-log4j.properties 设置说明
    属性 描述

    1

    配置名为 io.debezium.connector.mysql 的日志记录器,以将 DEBUGINFOWARNERROR 消息发送到 stdout 附加器。

    2

    配置名为 io.debezium.relational.history 的日志记录器,以将 DEBUGINFOWARNERROR 消息发送到 stdout 附加器。

    3

    这对 log4j.additivity.io 条目禁用了 additivity。如果您使用多个附加器,请将 additivity 值设置为 false,以防止将重复的日志消息发送到父日志记录器的附加器。

  3. 如有必要,请为连接器内特定类子集更改日志级别。

    提高整个连接器的日志级别会增加日志的详细程度,这可能难以理解发生了什么。在这些情况下,您可以仅为与您正在排查的问题相关的类子集更改日志级别。

    1. 将连接器的日志级别设置为 DEBUGTRACE

    2. 查看连接器的日志消息。

      找到与您正在排查的问题相关的日志消息。每条日志消息的末尾显示了生成该消息的 Java 类的名称。

    3. 将连接器的日志级别恢复为 INFO

    4. 为每个已识别的 Java 类配置一个日志记录器。

      例如,考虑一个场景:您不确定 MySQL 连接器在处理 binlog 时为什么会跳过某些事件。您可以不为整个连接器启用 DEBUGTRACE 日志记录,而是将连接器的日志级别保持在 INFO,然后仅为读取 binlog 的类配置 DEBUGTRACE 级别。

      示例 3. 启用 BinlogReaderDEBUG 日志记录的 connect-log4j.properties 配置
      ...
      log4j.logger.io.debezium.connector.mysql=INFO, stdout
      log4j.logger.io.debezium.connector.mysql.BinlogReader=DEBUG, stdout
      log4j.logger.io.debezium.relational.history=INFO, stdout
      
      log4j.additivity.io.debezium.connector.mysql=false
      log4j.additivity.io.debezium.storage.kafka.history=false
      log4j.additivity.io.debezium.connector.mysql.BinlogReader=false
      ...

使用 Kafka Connect REST API 动态设置日志级别

您可以使用 Kafka Connect REST API 在运行时动态设置连接器的日志级别。与在 connect-log4j.properties 中设置的日志级别更改不同,通过 API 所做的更改会立即生效,并且不需要重新启动 worker。

您在 API 中指定的日志级别设置仅适用于接收请求的端点的 worker。群集中其他 worker 的日志级别保持不变。

指定的级别在 worker 重启后不会持久化。要使日志级别更改持久化,请通过 配置日志记录器添加映射诊断上下文connect-log4j.properties 中设置日志级别。

过程
  • 通过向 admin/loggers 端点发送 PUT 请求并指定以下信息来设置日志级别:

    • 您想更改日志级别的包。

    • 您想设置的日志级别。

      curl -s -X PUT -H "Content-Type:application/json" https://:8083/admin/loggers/io.debezium.connector.<connector_package> -d '{"level": "<log_level>"}'

      例如,要记录 Debezium MySQL 连接器的调试信息,请向 Kafka Connect 发送以下请求:

      curl -s -X PUT -H "Content-Type:application/json" https://:8083/admin/loggers/io.debezium.connector.mysql -d '{"level": "DEBUG"}'

使用映射诊断上下文设置日志级别

大多数 Debezium 连接器(以及 Kafka Connect worker)使用多个线程来执行不同的活动。这使得在查看日志文件时难以仅找到特定逻辑活动的日志消息。为了使日志消息更容易找到,Debezium 提供了几种 *映射诊断上下文* (MDC),为每个线程提供额外信息。

Debezium 提供以下 MDC 属性:

dbz.connectorType

连接器类型的简短别名。例如,MySqlMongoPostgres 等。与同一 *类型* 连接器相关的所有线程使用相同的值,因此您可以使用此属性找到给定类型连接器生成的所有日志消息。

dbz.connectorName

连接器配置中定义的连接器或数据库服务器的名称。例如 productsserverA 等。与特定 *连接器实例* 相关的所有线程使用相同的值,因此您可以找到特定连接器实例生成的所有日志消息。

dbz.connectorContext

连接器任务中作为单独线程运行的活动的简短名称。例如,mainbinlogsnapshot 等。在某些情况下,当连接器将线程分配给特定资源(例如表或集合)时,可以使用该资源的名称。与连接器相关的每个线程将使用不同的值,因此您可以找到与此特定活动相关的​​所有日志消息。

要启用连接器的 MDC,请在 connect-log4j.properties 文件中配置一个附加器。

过程
  1. 打开 connect-log4j.properties 文件。

  2. 配置一个附加器以使用任何支持的 Debezium MDC 属性。在以下示例中,stdout 附加器被配置为使用这些 MDC 属性。

    示例 4. 将 stdout 附加器设置为使用 MDC 属性的 connect-log4j.properties 配置
    ...
    log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p  %X{dbz.connectorType}|%X{dbz.connectorName}|%X{dbz.connectorContext}  %m   [%c]%n
    ...

    前面示例中的配置将生成类似于以下输出的日志消息:

    ...
    2017-02-07 20:49:37,692 INFO   MySQL|dbserver1|snapshot  Starting snapshot for jdbc:mysql://mysql:3306/?useInformationSchema=true&nullCatalogMeansCurrent=false&useSSL=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull with user 'debezium'   [io.debezium.connector.mysql.SnapshotReader]
    2017-02-07 20:49:37,696 INFO   MySQL|dbserver1|snapshot  Snapshot is using user 'debezium' with these MySQL grants:   [io.debezium.connector.mysql.SnapshotReader]
    2017-02-07 20:49:37,697 INFO   MySQL|dbserver1|snapshot  GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'debezium'@'%'   [io.debezium.connector.mysql.SnapshotReader]
    ...

日志中的每一行都包含连接器类型(例如,MySQL)、连接器名称(例如,dbserver1)以及线程的活动(例如,snapshot)。

在 Debezium 容器镜像中配置日志级别

用于 Kafka 和 Kafka Connect 的 Debezium 容器镜像都设置了它们的 log4j.properties 文件来配置 Debezium 相关的日志记录器。所有日志消息都发送到 Docker 容器的控制台(从而发送到 Docker 日志)。日志消息还会写入 /kafka/logs 目录下的文件中。

容器使用 LOG_LEVEL 环境变量来设置根日志记录器的日志级别。您可以使用此环境变量来设置容器中运行的服务的日志级别。当您启动容器并将此环境变量的值设置为日志级别(例如,-e LOG_LEVEL=DEBUG)时,容器内的所有代码都将使用该日志级别。

还有一个选项可以覆盖其他 log4j 属性。如果您想以不同的方式配置 log4j.rootLogger,请使用环境变量 CONNECT_LOG4J_LOGGERS。例如,要仅记录到 stdout(不带 appender),可以使用 CONNECT_LOG4J_LOGGERS=INFO, stdout。您还可以设置其他支持的 CONNECT_LOG4J 前缀的环境变量,这些变量将映射到 log4j.properties 文件中的属性,方法是移除 CONNECT_ 前缀、将所有字符转换为小写并将所有 '_' 字符转换为 '.'。

如果您需要更精细地控制日志配置,请创建一个基于我们镜像的新容器镜像,但在您的 Dockerfile 中,将您自己的 log4j.properties 文件复制到镜像中。例如:

Dockerfile
...
COPY log4j.properties $KAFKA_HOME/config/log4j.properties
...