Apache Druid 日志配置实战:log4j2.xml、指标与请求日志调优指南
2026/9/23 4:20:25 网站建设 项目流程
  • 数据库
  • 数据分析
  • OLAP
  • 大数据
  • 实时分析
  • 数据仓库
  • 后端

【免费下载链接】druid

Apache Druid: a high performance real-time analytics database.

项目地址:https://gitcode.com/gh_mirrors/druid7/druid
点击查看免费下载

Druid 节点(Broker、Coordinator、Historical、MiddleManager 等)在运行过程中会向控制台输出两类信息:用于排错的调试日志,以及反映节点运行状态的周期性子指标。本文以 Druid 官方 logging 配置文档 为核心,系统讲解如何通过 log4j2.xml 覆盖默认日志配置、如何通过 JVM 参数接入 JUL 桥接、如何控制指标日志的级别,以及如何开启请求级(Query/HTTP)日志。读完后,你将能独立完成一个 Druid 集群各节点日志行为的完整定制。

一、Druid 日志体系概览

Druid 的日志体系由两层组成:

  1. 应用日志(Application Logs):各节点基于 log4j2 输出调试与运行信息,默认打印到控制台(SYSTEM_OUT)。
  2. 指标日志(Metrics Logs):节点周期性发射自身状态指标(如查询数、缓存命中率、JVM 状态等),默认同样打印到控制台。

官方日志文档(docs/content/configuration/logging.md)明确指出:指标日志默认打印到控制台,并可通过-Ddruid.emitter.logging.logLevel=debug来调整其行为。这里的druid.emitter.logging.logLevel是一个标准的 Druid 运行配置项,其完整取值与含义在 Configuration 文档 中有权威定义,详见本文第五节。

二、用 log4j2.xml 覆盖默认日志配置

Druid 使用 log4j2 作为日志框架,因此日志行为完全可以通过一个标准的log4j2.xml文件来定制。配置方式的核心要点如下:

  • 编写一个log4j2.xml文件;
  • 将该文件所在目录(例如各节点配置目录下的_common/目录)加入 classpath
  • 该目录必须排在 druid jars 之前,否则 classpath 中更靠前的 jar 内嵌配置会抢先生效;
  • 最简单的做法是在启动命令的 classpath前缀位置加上配置目录。

从仓库自带的运行配置可以看出这一实践的具体落地方式:

  • examples/conf/druid/_common/log4j2.xml:examples/conf示例集群共用的 log4j2 配置文件;
  • examples/conf-quickstart/druid/_common/log4j2.xml:快速入门版(conf-quickstart)集群的对应文件。

官方文档提到 Druid 自带示例配置位于config/_common/log4j2.xml,在仓库中即以上述examples/conf/druid/_common/log4j2.xmlexamples/conf-quickstart/druid/_common/log4j2.xml两份文件的形式随发行包提供。每个节点(broker、coordinator、historical、middleManager、overlord)的runtime.properties都依赖这份_common目录下的公共日志配置,因此只需要维护一份即可统一整个集群的日志行为。

三、完整示例 log4j2.xml 逐段详解

官方日志文档给出了一份可完整复制使用的log4j2.xml,仓库中 examples/conf/druid/_common/log4j2.xml 的内容与之完全一致。下面逐段拆解其含义:

<?xml version="1.0" encoding="UTF-8" ?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{ISO8601} %p [%t] %c - %m%n"/> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> <!-- Uncomment to enable logging of all HTTP requests <Logger name="io.druid.jetty.RequestLog" additivity="false" level="DEBUG"> <AppenderRef ref="Console"/> </Logger> --> </Loggers> </Configuration>
  • <Configuration status="WARN">status控制 log4j2 自身内部日志的级别,设为WARN可避免框架自身的噪音刷屏,同时保留关键告警;
  • <Appenders>段:声明一个名为Console的 Appender,输出目标为SYSTEM_OUT(标准输出);
  • <PatternLayout pattern="%d{ISO8601} %p [%t] %c - %m%n"/>:定义每条日志的格式,含义分别为:
    • %d{ISO8601}:ISO8601 格式的时间戳;
    • %p:日志级别(DEBUG / INFO / WARN / ERROR);
    • %t:产生日志的线程名;
    • %c:Logger 的类名(category);
    • %m:日志消息正文;
    • %n:换行符。
  • <Loggers>段:<Root level="info">将全局日志级别设为INFO,并把所有日志交给ConsoleAppender 输出;
  • 被注释的<Logger name="io.druid.jetty.RequestLog" ...>:这是一段非常有用的开关——取消注释并将其level设为DEBUG,即可开启对所有 HTTP 请求的日志记录additivity="false"表示该 Logger 的日志不再向 Root 重复传播,避免重复输出。

如果你想同时输出到文件(便于采集与归档),只需在<Appenders>段中增加一个RollingFileAppender 并在 Root 中追加AppenderRef即可,模式与此完全一致。

四、开启 JUL(java.util.logging)桥接

Druid 内部部分组件走的是标准java.util.logging(JUL)接口。若希望这些日志也能统一进入 log4j2 的管道,需要设置如下 JVM 服务器参数:

-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

该参数在节点启动时(jvm.config或启动脚本的 JVM 参数区)加入,即可让 JUL 的日志记录统一由 log4j2 管理,保证整个节点只有一套日志配置与格式,避免“部分日志不受 log4j2.xml 控制”的割裂局面。

五、指标(Metrics)日志与 Logging Emitter 配置

Druid 节点周期性发射指标,这些指标经由一个称为Emitter的组件输出。仓库中每个节点的common.runtime.properties都包含相关配置,例如 examples/conf/druid/_common/common.runtime.properties 中就有:

druid.emitter.logging.logLevel=info

与之配套的完整参数表来自 Configuration 文档,核心参数如下:

参数说明默认值
druid.emitter设置为nooplogginghttp可初始化对应的 emitter 模块;composing可同时初始化多个 emitter 模块noop
druid.emitter.logging.loggerClass可选值:HttpPostEmitterLoggingEmitterNoopServiceEmitterServiceEmitter,指定日志输出使用的类LoggingEmitter
druid.emitter.logging.logLevel可选值:debuginfowarnerror,指定指标消息记录的日志级别info

官方文档原文提到"指标日志默认打印到控制台,可通过-Ddruid.emitter.logging.logLevel=debug调整",结合上表可以理解为:druid.emitter默认即为日志输出方式,logLevel决定了指标消息在 log4j2 管道中的记录级别。因此你既可以在common.runtime.properties中修改druid.emitter.logging.logLevel,也可以在启动命令中用-D系统属性覆盖它——后者的优先级更高,适合临时调试。

从源码实现看,Logging Emitter 的装配发生在 server/src/main/java/io/druid/server/initialization/LogEmitterModule.java:该模块以druid.emitter.logging为前缀绑定LoggingEmitterConfig,并通过 Guice 的@Provides方法实例化LoggingEmitter交由生命周期管理。也就是说,所有与druid.emitter.logging.*相关的属性都会自动注入到这个 emitter 的配置对象中。

此外,指标的产生频率与监控项也值得一并关注(同样来自 Configuration 文档):

参数说明默认值
druid.monitoring.emissionPeriod指标发射周期PT1m
druid.monitoring.monitors节点使用的监控器列表,例如["com.metamx.metrics.JvmMonitor","com.metamx.metrics.SysMonitor"]无(不加载监控器)

六、请求日志(Request Logging)实战

除了进程级日志,Druid 还支持对所有能处理查询的节点(Broker、Historical 等)记录查询请求本身,这在排查慢查询、定位请求来源时非常关键。相关配置同样集中在 Configuration 文档 的 Request Logging 一节。

核心开关:

参数说明默认值
druid.request.logging.type可选值:noopfileemitterslf4jfilteredcomposing,决定查询请求的日志方式noop

各类型要点:

  • file:按天将请求日志落盘,配合druid.request.logging.dir指定存储目录;
  • emitter:将每个请求作为事件发送到外部(druid.request.logging.feed指定 feed 名称);
  • slf4j:通过 SLF4J 记录每个请求,消息中以 JSON 序列化查询内容(不受 SLF4J 格式规范限制),日志归类到io.druid.server.log.LoggingRequestLogger
  • filtered:按druid.request.logging.queryTimeThresholdMs过滤,仅记录 query/time 超过阈值的请求,并可通过druid.request.logging.delegate委托给其它记录器;
  • composing:通过druid.request.logging.loggerProviders同时向多个记录器输出。

其中slf4j类型支持通过 MDC 增强日志字段,便于在日志系统中做结构化检索:

参数说明默认值
druid.request.logging.setMDC是否在日志条目中写入 MDC 字段(需日志后端支持 MDC 格式化)false
druid.request.logging.setContextMDC是否把查询context加入 MDC(仅在setMDCtrue时生效)false

setMDC=true时填充的 MDC 字段包括:queryId(查询 ID)、dataSource(查询的数据源)、queryType(查询类型)、hasFilters(是否带过滤条件)、remoteAddr(客户端地址)、duration(查询时间区间长度)、resultOrdering(结果排序方式)、descending(是否降序查询)。

从源码实现看,server/src/main/java/io/druid/server/log/LoggingRequestLogger.java 正是slf4j类型的底层实现:它在log()方法中把queryIddataSourcequeryTypehasFiltersremoteAddrdurationdescending以及(当setContextMDC开启时)查询 context 的每一项写入 MDC,然后以LOG.info输出完整的RequestLogLine,并在 finally 块中恢复调用前的 MDC 上下文。请求日志记录器本身的装配则由 server/src/main/java/io/druid/guice/QueryableModule.java 完成——它以druid.request.logging为前缀绑定RequestLoggerProvider,并注册了fileemitterslf4jcomposingfiltered五种实现。

除了查询请求,若想记录所有HTTP 请求(而不仅是查询),则回到本文第三节提到的开关:把io.druid.jetty.RequestLog这个 Logger 的级别设为DEBUG即可(官方文档与 Configuration 文档 均如此说明)。

七、附加:启动期属性日志与敏感信息脱敏

在集群排查"某个配置到底有没有生效"时,可以借助启动期属性日志。相关参数同样见 Configuration 文档:

参数说明默认值
druid.startup.logging.logProperties启动时打印全部属性(来自common.runtime.propertiesruntime.properties与 JVM 命令行)false
druid.startup.logging.maskProperties对包含这些关键词的属性做脱敏处理(如password["password"]

注意:若同时开启这两项,仍可能有部分敏感信息被记录到日志,生产环境请谨慎评估。

小结

围绕 Druid 的日志,本文覆盖了四个层次的配置能力:进程日志(通过log4j2.xml定制 Appender、PatternLayout 与 Root 级别,并将配置目录置于 classpath 前缀)、JUL 桥接-Djava.util.logging.manager)、指标日志druid.emitter/druid.emitter.logging.logLevel,由LogEmitterModule装配)、以及请求日志druid.request.logging.type的五种模式与 MDC 字段,由QueryableModule装配、LoggingRequestLogger实现)。实际运维中,建议将log4j2.xml统一放在各节点_common/目录并保持一份配置多节点复用,同时按环境(开发/生产)区分druid.emitter.logging.logLevel与请求日志开关,避免生产环境因过度日志引入性能开销。

  • 数据库
  • 数据分析
  • OLAP
  • 大数据
  • 实时分析
  • 数据仓库
  • 后端

【免费下载链接】druid

Apache Druid: a high performance real-time analytics database.

项目地址:https://gitcode.com/gh_mirrors/druid7/druid
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询