You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助Quarkus和MicroMeter为Keycloak 22添加自定义指标

如何将自定义指标合并到Keycloak 22.0.1+原生Prometheus指标端点?

问题背景

  • Keycloak 22.0.1及以上版本基于Quarkus构建,原生支持Prometheus格式的MicroMeter指标
  • 需编写扩展JAR,通过EventListenerProvider和RealmResourceProvider添加自定义指标(比如按Realm统计的登录次数)
  • 当前实现:参考同类项目自定义了PrometheusMeterRegistry,通过/auth/realms/master/custom-metrics端点暴露,但Prometheus仅能抓取一个URL,无法合并原生指标与自定义指标

核心疑问

如何将自定义指标添加到Keycloak原生的MeterRegistry中?是否需要编写Quarkus扩展以通过@Inject注入MeterRegistry?有没有Keycloak SPI可直接获取原生MeterRegistry?


解决方案

1. 直接通过CDI注入原生MeterRegistry(无需Quarkus扩展)

Keycloak的Quarkus运行时已将MeterRegistry作为CDI Bean暴露,在Keycloak SPI实现类中可直接用@Inject注入,无需额外编写Quarkus扩展。

示例代码(自定义EventListenerProviderFactory):

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import jakarta.inject.Inject;
import org.keycloak.events.EventListenerProvider;
import org.keycloak.events.EventListenerProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;

public class RealmLoginMetricsFactory implements EventListenerProviderFactory {

    @Inject
    private MeterRegistry meterRegistry;
    private Counter realmLoginCounter;

    @Override
    public void init(org.keycloak.Config.Scope config) {
        // 注册按Realm维度统计的登录次数指标
        realmLoginCounter = Counter.builder("keycloak_realm_login_total")
                .description("Total number of successful logins per realm")
                .register(meterRegistry);
    }

    @Override
    public EventListenerProvider create(KeycloakSession session) {
        return new RealmLoginMetricsListener(realmLoginCounter, session);
    }

    @Override
    public void postInit(KeycloakSessionFactory factory) {}

    @Override
    public void close() {}

    @Override
    public String getId() {
        return "realm-login-metrics";
    }
}

在自定义EventListener中触发指标累加:

public class RealmLoginMetricsListener implements EventListenerProvider {
    private final Counter loginCounter;
    private final KeycloakSession session;

    public RealmLoginMetricsListener(Counter loginCounter, KeycloakSession session) {
        this.loginCounter = loginCounter;
        this.session = session;
    }

    @Override
    public void onEvent(Event event) {
        if (EventType.LOGIN.equals(event.getType())) {
            // 按Realm打标签
            loginCounter.tag("realm", event.getRealmId()).increment();
        }
    }

    @Override
    public void close() {}
}

最后在META-INF/services/org.keycloak.events.EventListenerProviderFactory文件中添加SPI实现类全路径,确保Keycloak能扫描到。

2. 利用Keycloak 22+新增的MetricsProvider SPI

Keycloak 22及以上版本提供了MetricsProvider SPI,专门用于扩展原生指标体系,无需手动管理MeterRegistry:

  • 实现org.keycloak.metrics.MetricsProvider接口
  • 在init方法中注册自定义指标,Keycloak会自动将其合并到原生的/metrics端点
  • 该SPI会自动关联Keycloak上下文,无需手动处理Realm等维度的标签

3. 关键注意事项

  • 禁止自行实例化PrometheusMeterRegistry:这会导致指标分散在不同端点,无法合并
  • 确保SPI类被正确扫描:必须在META-INF/services下添加对应SPI的配置文件
  • 指标命名规范:建议使用keycloak_前缀,避免与Quarkus原生指标冲突

内容的提问来源于stack exchange,提问作者lathspell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 22:58:30