配置 Keycloak 分级结构化日志与脱敏访问日志

配置 Keycloak 分级结构化日志与脱敏访问日志

原文:Keycloak Team,Configuring logging。中文翻译与技术整理:未完纪。2026 年 10 月 9 日核对当前指南及 下载页,下载页标识 Keycloak 26.8.0。本文采用这一时点的文档,未安装或启动服务器。

日志既帮助观察 Keycloak 的健康状态,也用于定位故障和保留重要事件记录。Keycloak 底层使用 JBoss Logging。配置不止是调高或调低级别,还包括选择输出去向、加入请求上下文、切换 JSON、采用异步处理,以及独立记录 HTTP 访问。以下命令用 Linux/macOS 的 bin/kc.sh 表示;Windows 发行包使用对应的 bin/kc.bat。它们是启动参数片段,不包含生产环境所需的全部数据库、TLS 和主机名配置。

日志先经过根和分类级别筛选,再由console file syslog处理器进一步过滤;HTTP访问日志可单独脱敏并写入轮换文件
级别过滤与输出路由示意;处理器无法恢复前面已被过滤的记录。

选择输出处理器

console 将日志写到标准输出,file 将日志保存到磁盘,syslog 把日志交给 Syslog 服务。用逗号分隔的 –log 一次启用一个或多个处理器。默认只启用 console。

bin/kc.sh start --log="console,file"

处理器的专属参数只有在对应处理器启用后才生效。详细配置可查官方 日志指南中的 Console、File 与 Syslog 参考链接;本文同时整理当前页面的相关选项,不延伸到外部 Syslog 服务的部署。

根级别与分类级别

选项或模式 作用与默认值
FATAL 严重故障,已经完全不能提供请求服务。
ERROR 导致请求无法处理的重大错误或问题。
WARN 非致命问题,未必需要立即修正。
INFO 生命周期事件或重要信息,通常较低频。
DEBUG 调试细节,例如数据库相关日志,频率更高。
TRACE 最细粒度的调试信息,可能非常高频。
ALL / OFF ALL 接受所有级别;OFF 完全关闭日志,原文不建议这样做。

没有独立设置的分类会沿包名层次继承较上层分类的设置;找不到匹配上层分类时,才使用根日志级别。根级别通过 –log-level 设置,值不区分大小写。如果同一列表里重复给出根级别,最后一次出现的值生效。

bin/kc.sh start --log-level=INFO
bin/kc.sh start --log-level="INFO,org.hibernate:debug,org.hibernate.hql.internal.ast:info"

第二条命令让普通日志维持 INFO,把 org.hibernate 提到 debug,再把更具体的 org.hibernate.hql.internal.ast 降回 info,以避免 SQL 抽象语法树细节占满输出。一个分类设置会影响子分类,但更具体的子分类设置优先。

如果只想调整某个分类而不覆盖整条 –log-level,可以使用独立的 –log-level-<category>。这种独立选项的优先级高于组合列表。环境变量写法将分类名转成大写并把点换成下划线,例如 KC_LOG_LEVEL_ORG_KEYCLOAK=trace;命令行等其他配置源保持原来的分类名。

bin/kc.sh start --log-level="INFO,org.hibernate:debug" --log-level-org.keycloak=trace

同理,若组合列表指定 org.hibernate:debug,而环境变量 KC_LOG_LEVEL_ORG_HIBERNATE=trace 生效,则该分类使用 trace。不要仅看某一条启动参数判断最终级别,还要考虑部署环境注入的独立选项。

处理器只做进一步过滤

console、file 和 syslog 分别支持 log-console-level、log-file-level 与 log-syslog-level。该层的级别按原文要求使用小写,默认 all,表示不再额外限制。处理器目前不能分别设置一组分类级别。

最关键的关系是:先由有效的根或分类级别决定是否产生一条记录,再由处理器级别决定是否输出。把 console 设成 debug,无法找回已被根 INFO 过滤的普通 DEBUG 记录。反过来,根设 debug、console 设 info,文件处理器保持 all,就能让文件保留调试信息而控制台只显示 INFO 及以上。

bin/kc.sh start --log=console,file --log-level=debug --log-console-level=info

希望文件保留 debug,控制台和 Syslog 只保留 warn,可使用:

bin/kc.sh start --log=console,file,syslog --log-level=debug --log-console-level=warn --log-syslog-level=warn

如果 Syslog 还要记录 org.keycloak.events 的 trace,而其他输出只到 info,则同时允许该分类生成 TRACE,并让 Syslog 处理器接受 trace:

bin/kc.sh start --log=console,file,syslog --log-level="debug,org.keycloak.events:trace" --log-syslog-level=trace --log-console-level=info --log-file-level=info

编辑整理:这里去掉了原文示例 –log-level 参数末尾多余的逗号,保留其级别含义。更细分类可以比根更详细;处理器仍只能过滤已经通过相应分类判断的记录。

把请求上下文加入日志

MDC(映射诊断上下文)可以附加当前 realm、client 等信息。正文给出 –log-mdc-enabled=true;同页选项表同时注明,它仅在 log-mdc 预览特性启用后可用。配置时应先按该版本的特性管理方式启用 log-mdc,再开启 MDC 日志,不能把正文的一条参数理解成所有环境都能独立使用。

bin/kc.sh start --log-mdc-enabled=true

原文显示的格式类似 {kc.clientId=security-admin-console, kc.realmName=master}。log-mdc-keys 决定加入哪些键,字段带 kc. 前缀;当前可选 realmName、clientId、userId、ipAddress、org、sessionId、authenticationSessionId、authenticationTabId,默认列表不包括 userId 和 ipAddress。选择这些字段时要考虑实际日志访问者需要什么信息,不能把“有上下文”自动等同于“可以不加限制保存个人数据”。

选择 JSON 格式和服务字段

三个处理器均支持 log-<handler>-output=json。JSON 的组织形式则由 log-<handler>-json-format 指定,可选 default 或 ecs。ecs 指 Elastic Common Schema;原文提到该规范正与 OpenTelemetry 语义约定汇合,这不代表现有输出字段会自动适配所有下游系统。

bin/kc.sh start --log-console-output=json --log-console-json-format=ecs

ECS 示例包含 @timestamp、event.sequence、log.logger、log.level、message、process.thread.name、process.thread.id、mdc、host.hostname、process.pid、data_stream.type、ecs.version 和 service.* 等字段。原文示例消息内的 Keycloak 999.0.0-SNAPSHOT 只是构造的日志内容,不是本文版本依据。

所有启用 JSON 的处理器可共用 log-service-name 和 log-service-environment。service.name 默认 keycloak;默认 JSON 格式通常不设置 service.environment,ECS 格式未指定时使用 Quarkus profile,例如 prod。以下参数显式标记部署身份:

bin/kc.sh start --log-console-output=json --log-service-name=my-keycloak --log-service-environment=production

异步日志的收益与代价

异步日志为每个启用异步的处理器建立独立线程和队列,记录先进入队列,再由该线程调用输出处理器。它能减少请求线程承担的日志 I/O,适合较高吞吐、较低延迟、工作线程较少或远端输出较慢的场景。处理器本身如何写日志没有改变,只是执行位置变了。

队列不是无限缓冲。默认每个队列容纳 512 条记录,队列满时会阻塞提交日志的线程,等待腾出空间。额外线程和队列会增加内存占用,资源紧张环境不一定适合启用;服务器异常退出还可能丢失尚未写出的记录。不能将异步配置描述成“不阻塞”或“保证不丢日志”。

bin/kc.sh start --log-async=true
bin/kc.sh start --log-console-async=true --log-file-async=true --log-syslog-async=true

log-async 给出全局默认值;单独的 log-<handler>-async 未设置时继承它。处理器仍需通过 –log 启用,单独设置异步参数不会自动打开 file 或 syslog。只在对应处理器启用异步时,队列长度选项才有效。

bin/kc.sh start --log=console,file,syslog --log-async=true --log-console-async-queue-length=512 --log-file-async-queue-length=512 --log-syslog-async-queue-length=512

启用 HTTP 访问日志

访问日志记录进入服务器的 HTTP 请求,帮助调试、分析流量和建立访问轨迹。它的记录级别是 INFO,因此全局或 org.keycloak.http.access-log 分类必须允许 INFO;相关输出处理器也不能把它再次过滤。默认根级别就是 info,打开访问日志后通常即可看到。

bin/kc.sh start --http-access-log-enabled=true

访问日志格式有三个预设:common 是默认值,记录基本请求信息;combined 增加 referer 和 user agent;long 记录更完整的信息,包括所有请求头。也可写自己的模式,例如记录地址、方法、请求 URL 和 User-Agent:

bin/kc.sh start --http-access-log-enabled=true --http-access-log-pattern=combined
bin/kc.sh start --http-access-log-enabled=true --http-access-log-pattern='%A %{METHOD} %{REQUEST_URL} %{i,User-Agent}'

原文可用变量列表链接到 Quarkus HTTP 访问日志文档。这些示例只是格式展示,未执行。自定义格式需要按所用 shell 引号规则传递。

脱敏不是所有秘密的安全保证

HTTP 请求头可能包含 Authorization、Cookie 或扩展使用的 API 密钥。当前指南列出的始终遮蔽项包括 Authorization,以及 AUTH_SESSION_ID、KC_AUTH_SESSION_HASH、KEYCLOAK_IDENTITY、KEYCLOAK_SESSION、AUTH_SESSION_ID_LEGACY、KEYCLOAK_IDENTITY_LEGACY、KEYCLOAK_SESSION_LEGACY 这些敏感 Cookie。

默认清单不可能知道每个扩展的自定义秘密。用 http-access-log-masked-headers 与 http-access-log-masked-cookies 扩充名称列表,例如:

bin/kc.sh start --http-access-log-enabled=true --http-access-log-masked-headers=X-Custom,Y-Api-Token --http-access-log-masked-cookies=MY_COOKIE,MY_SECOND_COOKIE

重要范围:同页选项表明确将这些屏蔽列表的行为描述为 long 模式或 %{ALL_REQUEST_HEADERS} 格式。不能据此声称任意自定义逐头格式、URL 查询参数、正文或扩展自行写出的日志都已被脱敏。原文建议 long 和自定义打印请求头只用于开发。本文没有用真实敏感数据试验脱敏,也没有把日志收集等同于合规审计。

排除路径、单独落盘与每日轮换

不希望记录某些路径时,可通过正则表达式排除。例如下面排除 /realms/my-internal-realm/ 及其后续路径。排除后这些请求就不会出现在访问日志里,应先确认这符合自己的排障与追踪需求。

bin/kc.sh start --http-access-log-enabled=true --http-access-log-exclude='/realms/my-internal-realm/.*'

访问日志可以从普通服务器日志中分离,写到独立文件。开启访问日志专用文件后,该访问日志不再写到控制台;不要把这个开关与普通 –log=file 混为一谈。

bin/kc.sh start --http-access-log-enabled=true --http-access-log-file-enabled=true

默认文件是发行目录 data/log 下的 keycloak-http-access.log。可以用 http-access-log-file-name 改基本文件名,用 http-access-log-file-suffix 改后缀。原文示例将基本名设为 my-http-logs、后缀传 txt,描述结果为 my-http-logs.txt;选项表将默认后缀显示为 .log。实际调整后应核对生成的文件名,不要只依靠两段文字中点号写法的差异推断。

bin/kc.sh start --http-access-log-enabled=true --http-access-log-file-enabled=true --http-access-log-file-name=my-http-logs --http-access-log-file-suffix=txt

访问日志默认每天轮换,前一天文件名加入 .{yyyy-MM-dd} 日期部分,再接文件后缀。选项表补充说,同一天发生多次轮换时会在日期后追加递增索引。原文的 2052-02-29 只是文件名演示,并非真实运行日期。需要停用轮换可设置 false,但这不会自动解决不断增长的文件占用问题。

bin/kc.sh start --http-access-log-enabled=true --http-access-log-file-enabled=true --http-access-log-file-rotate=false

配置选项速查

以下将原页完整相关选项按共同规则合并。命令行选项加 — 前缀;环境变量通常是 KC_ 加上全大写、连字符改下划线,例如 log-file 对应 KC_LOG_FILE。分类名和带大小写的遥测头另有说明,应按官方配置映射处理。

选项或模式 作用与默认值
log / log-level 输出处理器默认 console;根级别默认 info;分类列表写 category:level。
log-level-<category> 独立分类级别,覆盖组合 log-level;环境变量中的分类大写、点改下划线。
log-async 所有处理器异步默认 false;可由专属选项覆盖。
log-service-name / log-service-environment 所有 JSON 输出的服务名称与环境;名称默认 keycloak,环境规则见前文。
log-<handler>-async / log-<handler>-async-queue-length handler 为 console、file 或 syslog。异步继承全局;队列默认512,仅相应异步处理器有效。
log-<handler>-level 三种处理器都支持,默认 all;值 off/fatal/error/warn/info/debug/trace/all,只能进一步过滤。
log-<handler>-output / log-<handler>-json-format output 为 default 或 json,默认 default;JSON形式 default 或 ecs,默认 default。
log-<handler>-format 三种处理器的非结构化格式默认 %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n。含空格时加引号。
log-<handler>-include-mdc / log-<handler>-include-trace 默认 true,但对应 MDC 或追踪功能必须启用;一旦指定专属 format,这两项不再影响格式。
log-console-color 强制启用或停用控制台颜色;不设置时尝试判断终端能力。
log-file 普通服务器日志路径,默认 data/log/keycloak.log。
log-file-rotation-enabled 普通文件处理器轮换开关,默认 true。
log-file-rotation-file-suffix 普通文件按后缀周期轮换,例如 .yyyy-MM-dd;末尾 .zip 或 .gz 表示压缩。
log-file-rotation-max-backup-index 普通文件最大备份数量,默认5。
log-file-rotation-max-file-size 普通文件达到该大小后轮换,默认10M,支持10M、1G等单位。
log-file-rotation-rotate-on-boot 启动时是否轮换普通日志,默认 true。
log-syslog-app-name RFC5424消息中的应用名,默认 keycloak。
log-syslog-endpoint Syslog目的端点,默认 localhost:514。
log-syslog-protocol tcp、udp或ssl-tcp,默认tcp。
log-syslog-type rfc5424或rfc3164,默认rfc5424。
log-syslog-counting-framing true、false或protocol-dependent,默认后者;tcp/ssl-tcp下默认加消息长度前缀,其他协议默认不加。
log-syslog-max-length 包括头部在内的消息最大字节数;未设置时RFC5424为2048,RFC3164为1024。
http-access-log-enabled 访问日志总开关,默认false。
http-access-log-pattern common/combined/long或自定义模式,默认common。
http-access-log-exclude 排除路径的正则表达式,仅访问日志开启时有效。
http-access-log-masked-headers / http-access-log-masked-cookies 追加要遮蔽的头名/Cookie名清单,范围见前文;内置敏感项始终遮蔽。
http-access-log-file-enabled 访问日志独立文件开关,默认false。
http-access-log-file-name / http-access-log-file-suffix 默认基本名keycloak-http-access、后缀.log,仅访问文件启用时有效。
http-access-log-file-rotate 访问日志每日轮换,默认true;与普通log-file轮换独立。
log-mdc-enabled 默认false,仅log-mdc预览特性开启后可用。
log-mdc-keys 逗号分隔字段,默认realmName,clientId,org,sessionId,authenticationSessionId,authenticationTabId;可选项另含userId、ipAddress。
telemetry-logs-enabled 默认false,需要opentelemetry-logs:v1特性。
telemetry-logs-endpoint 遥测日志端点,未设置则继承telemetry-endpoint。
telemetry-logs-header-<header> 日志导出请求的附加头,例如授权头;包含特殊字符或大小写时按官方环境变量映射配置。
telemetry-logs-level 遥测导出允许的最详细级别,默认all。
telemetry-logs-protocol grpc或http/protobuf;未设置则继承telemetry-protocol。

遥测导出与来源说明

当前指南也支持把日志导出到 OpenTelemetry 收集器,相关入口是 Centralize your observability stack with OpenTelemetry。这里仅保留选项与官方后续阅读路径,不展开外部收集器部署。

代码审核仅为静态:未启动Keycloak、验证磁盘文件、测量吞吐或实际请求脱敏。示例没有真实硬编码密码或令牌;Authorization 等是字段名。需要重点防止的是 long/自定义头打印遗漏秘密、过滤级别让访问记录消失,以及关闭轮换后文件持续增长。官方页脚署名 © Keycloak Authors 2026、© 2026 The Linux Foundation,All rights reserved。中文翻译与原创示意图依单独发布授权提供;原创示意图未使用商标或伪造运行界面。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容