使用追踪进行根本原因分析

使用 OpenTelemetry 追踪记录请求生命周期内的信息,以识别 Keycloak 和连接系统中的延迟和错误的根本原因。

本指南解释了如何通过使用 OpenTelemetry (OTel) 在 Keycloak 中启用和配置分布式追踪。追踪可以详细监控每个请求的生命周期,从而帮助快速识别和诊断问题,提高调试和维护效率。

它提供了对性能瓶颈的有价值的见解,并可以帮助优化系统的整体效率以及跨系统边界的效率。Keycloak 使用受支持的 Quarkus OTel 扩展,该扩展提供了应用程序追踪的平滑集成和暴露。

启用追踪

可以使用构建时选项 tracing-enabled 启用暴露追踪,如下所示

bin/kc.[sh|bat] start --tracing-enabled=true

默认情况下,追踪导出器使用 gRPC 协议和端点 https://127.0.0.1:4317 批量发送数据。

默认服务名称为 keycloak,通过 tracing-service-name 属性指定,该属性优先于 tracing-resource-attributes 属性中定义的 service.name

有关可以通过 tracing-resource-attributes 属性提供的资源属性的更多信息,请参阅 Quarkus OpenTelemetry 资源 指南。

只有在 启用 opentelemetry 功能(默认情况下)时才能启用追踪。

有关更多追踪设置,请参阅以下所有可能的配置。

开发设置

为了查看捕获的 Keycloak 追踪,可以使用利用 Jaeger 追踪平台的基本设置。对于开发目的,可以使用 Jaeger-all-in-one 尽可能轻松地查看追踪。

Jaeger-all-in-one 包括 Jaeger 代理、OTel 收集器和查询服务/UI。您无需安装单独的收集器,因为您可以直接将追踪数据发送到 Jaeger。
podman|docker run --name jaeger \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
jaegertracing/all-in-one

暴露端口

16686

Jaeger UI

4317

OpenTelemetry 协议 gRPC 接收器(默认)

4318

OpenTelemetry 协议 HTTP 接收器

您可以访问 https://127.0.0.1:16686/ 上的 Jaeger UI 以查看追踪信息。Jaeger UI 可能看起来像这样,其中包含任意 Keycloak 追踪

Jaeger UI

追踪中的信息

Span

Keycloak 为以下活动创建 span

  • 传入的 HTTP 请求

  • 传出的数据库请求,包括获取数据库连接

  • 传出的 LDAP 请求,包括连接到 LDAP 服务器

  • 传出的 HTTP 请求,包括 IdP 代理

标签

Keycloak 根据请求的类型向追踪添加标签。所有标签都以 kc. 为前缀。

示例标签包括

kc.clientId

客户端 ID

kc.realmName

Realm 名称

kc.sessionId

用户会话 ID

kc.token.id

token 中提到的 id

kc.token.issuer

token 中提到的 issuer

kc.token.sid

token 中提到的 sid

kc.authenticationSessionId

身份验证会话 ID

kc.authenticationTabId

身份验证 Tab ID

日志

如果追踪被采样,它将包含请求期间创建的任何用户事件。这包括例如 LOGINLOGOUTREFRESH_TOKEN 事件,以及用户事件中找到的所有详细信息和 ID。

LDAP 通信错误也会在记录的追踪中显示为日志条目,其中包含堆栈追踪和失败操作的详细信息。

日志中的追踪 ID

启用追踪后,追踪 ID 将包含在所有已启用的日志处理程序的日志消息中(更多信息请参见 配置日志记录)。这对于将日志事件与请求执行关联非常有用,这可以提供更好的可追溯性和调试。来自同一请求的所有日志行都将在日志中具有相同的 traceId

日志消息还包含一个 sampled 标志,该标志与下面描述的采样有关,并指示 span 是否被采样 - 发送到收集器。

日志记录的格式可能如下所示

2024-08-05 15:27:07,144 traceId=b636ac4c665ceb901f7fdc3fc7e80154, parentId=d59cea113d0c2549, spanId=d59cea113d0c2549, sampled=true WARN  [org.keycloak.events] ...

隐藏日志中的追踪 ID

您可以通过指定其关联的 Keycloak 选项 log-<handler-name>-include-trace 来隐藏特定日志处理程序中的追踪 ID,其中 <handler-name> 是日志处理程序的名称。例如,要禁用 console 日志中的追踪信息,您可以按如下方式将其关闭

bin/kc.[sh|bat] start --tracing-enabled=true --log=console --log-console-include-trace=false
当您显式覆盖特定日志处理程序的日志格式时,*-include-trace 选项不起任何作用,并且不包含任何追踪信息。

采样

采样器决定是否应丢弃或转发追踪,从而通过限制发送到收集器的已收集追踪的数量来有效减少开销。它有助于管理资源消耗,从而避免追踪每个请求的巨大存储成本和潜在的性能损失。

对于生产就绪环境,应正确设置采样以最大限度地降低基础设施成本。

Keycloak 支持多个内置的 OpenTelemetry 采样器,例如

  • always_on

  • always_off

  • traceidratio(默认)

  • parentbased_always_on

  • parentbased_always_off

  • parentbased_traceidratio

可以使用 tracing-sampler-type 属性更改使用的采样器。

默认采样器

Keycloak 的默认采样器是 traceidratio,它根据通过 tracing-sampler-ratio 属性配置的指定比率来控制追踪采样的速率。

追踪比率

默认追踪比率为 1.0,这意味着所有追踪都被采样 - 发送到收集器。该比率是 [0,1] 范围内的浮点数。例如,当比率为 0.1 时,仅采样 10% 的追踪。

对于生产就绪环境,追踪比率应为较小的数字,以防止追踪存储基础设施的巨大成本并避免性能开销。
可以将比率设置为 0.0在运行时完全禁用采样。

原理

采样器根据当前采样的 span 比率做出自己的采样决策,而与父 span 上做出的决策无关,就像使用 parentbased_traceidratio 采样器一样。

parentbased_traceidratio 采样器可能是首选的默认类型,因为它确保了父 span 和子 span 之间的采样一致性。具体而言,如果采样了父 span,则其所有子 span 也将被采样 - 所有 span 的采样决策相同。这有助于将所有 span 保持在一起,并防止存储不完整的追踪。

但是,它可能会引入某些安全风险,从而导致 DoS 攻击。外部调用者可以操纵追踪标头,可以注入父 span,并且追踪存储可能会不堪重负。需要评估正确的 HTTP 标头(尤其是 tracestate)过滤和足够的调用者信任措施。

有关更多信息,请参阅 W3C 追踪上下文 文档。

Kubernetes 环境中的追踪

当在使用 Keycloak Operator 时启用追踪时,有关部署的某些信息会传播到基础容器。

通过 Keycloak CR 进行配置

您可以通过 Keycloak CR 更改追踪配置。有关更多信息,请参阅 高级配置

基于 Kubernetes 属性过滤追踪

您可以根据标签在追踪后端过滤掉所需的追踪

  • service.name - Keycloak 部署名称

  • k8s.namespace.name - 命名空间

  • host.name - Pod 名称

Keycloak Operator 自动为它管理的 pod 中包含的每个 Keycloak 容器设置 KC_TRACING_SERVICE_NAMEKC_TRACING_RESOURCE_ATTRIBUTES 环境变量。

KC_TRACING_RESOURCE_ATTRIBUTES 变量始终包含(如果未被覆盖)表示当前命名空间的 k8s.namespace.name 属性。

相关选项

log-console-include-trace

在控制台日志中包含追踪信息。

如果指定了 log-console-format 选项,则此选项无效。

CLI: --log-console-include-trace
Env: KC_LOG_CONSOLE_INCLUDE_TRACE

仅当控制台日志处理程序和追踪已激活时可用

true(默认),false

log-file-include-trace

在文件日志中包含追踪信息。

如果指定了 log-file-format 选项,则此选项无效。

CLI: --log-file-include-trace
Env: KC_LOG_FILE_INCLUDE_TRACE

仅当文件日志处理程序和追踪已激活时可用

true(默认),false

log-syslog-include-trace

在 Syslog 中包含追踪信息。

如果指定了 log-syslog-format 选项,则此选项无效。

CLI: --log-syslog-include-trace
Env: KC_LOG_SYSLOG_INCLUDE_TRACE

仅当 Syslog 处理程序和追踪已激活时可用

true(默认),false

tracing-compression

用于压缩有效负载的 OpenTelemetry 压缩方法。

如果未设置,则禁用压缩。

CLI: --tracing-compression
Env: KC_TRACING_COMPRESSION

仅当启用追踪时可用

gzip, none(默认)

tracing-enabled

启用 OpenTelemetry 追踪。

CLI: --tracing-enabled
Env: KC_TRACING_ENABLED

仅当启用 'opentelemetry' 功能时可用

true, false(默认)

tracing-endpoint

要连接的 OpenTelemetry 端点。

CLI: --tracing-endpoint
Env: KC_TRACING_ENDPOINT

仅当启用追踪时可用

https://127.0.0.1:4317(默认)

tracing-jdbc-enabled

启用 OpenTelemetry JDBC 追踪。

CLI: --tracing-jdbc-enabled
Env: KC_TRACING_JDBC_ENABLED

仅当启用追踪时可用

true(默认),false

tracing-protocol

用于遥测数据的 OpenTelemetry 协议。

CLI: --tracing-protocol
Env: KC_TRACING_PROTOCOL

仅当启用追踪时可用

grpc(默认), http/protobuf

tracing-resource-attributes

导出追踪中存在的 OpenTelemetry 资源属性,用于表征遥测生产者。

格式为 key1=val1,key2=val2 的值。有关更多信息,请查看追踪指南。

CLI: --tracing-resource-attributes
Env: KC_TRACING_RESOURCE_ATTRIBUTES

仅当启用追踪时可用

tracing-sampler-ratio

OpenTelemetry 采样器比率。

Span 将被采样的概率。预期双精度值,范围为 [0,1]。

CLI: --tracing-sampler-ratio
Env: KC_TRACING_SAMPLER_RATIO

仅当启用追踪时可用

1.0(默认)

tracing-sampler-type

用于追踪的 OpenTelemetry 采样器。

CLI: --tracing-sampler-type
Env: KC_TRACING_SAMPLER_TYPE

仅当启用追踪时可用

always_on, always_off, traceidratio(默认), parentbased_always_on, parentbased_always_off, parentbased_traceidratio

tracing-service-name

OpenTelemetry 服务名称。

优先于 tracing-resource-attributes 属性中定义的 service.name

CLI: --tracing-service-name
Env: KC_TRACING_SERVICE_NAME

仅当启用追踪时可用

keycloak(默认)

在此页上