From 3b148f90f71c48dc77014a3597e0adc1776e10db Mon Sep 17 00:00:00 2001 From: Garth <244253+xgp@users.noreply.github.com> Date: Fri, 7 Apr 2023 10:42:01 +0200 Subject: [PATCH] added DATA_COUNT and DATA_COUNT_INTERVAL params. extracted into separate config. --- .../metrics/MicrometerEventConfig.java | 52 +++++++++++ .../metrics/MicrometerEventListener.java | 12 +-- .../MicrometerEventListenerFactory.java | 90 ++++++++++--------- 3 files changed, 104 insertions(+), 50 deletions(-) create mode 100644 src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventConfig.java diff --git a/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventConfig.java b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventConfig.java new file mode 100644 index 0000000..a688f4c --- /dev/null +++ b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventConfig.java @@ -0,0 +1,52 @@ +package io.kokuwa.keycloak.metrics; + + +public class MicrometerEventConfig { + + private static final String KEY_EVENT_REPLACE_IDS = "KC_METRICS_EVENT_REPLACE_IDS"; + private static final String KEY_DATA_COUNT = "KC_METRICS_DATA_COUNT"; + private static final String KEY_DATA_COUNT_INTERVAL = "KC_METRICS_DATA_COUNT_INTERVAL"; + private static final long DEFAULT_DATA_COUNT_INTERVAL = 60; + + private final boolean replaceIds; + private final boolean dataCount; + private final long dataCountInterval; + + public static MicrometerEventConfig getConfig() { + long interval = DEFAULT_DATA_COUNT_INTERVAL; + try { + interval = Long.parseLong(System.getenv(KEY_DATA_COUNT_INTERVAL)); + } catch (Exception ignore) {} + return new MicrometerEventConfig("true".equals(System.getenv(KEY_EVENT_REPLACE_IDS)), + "true".equals(System.getenv(KEY_DATA_COUNT)), + interval); + } + + private MicrometerEventConfig(boolean replaceIds, boolean dataCount, long dataCountInterval) { + this.replaceIds = replaceIds; + this.dataCount = dataCount; + this.dataCountInterval = dataCountInterval; + } + + public boolean replaceIds() { + return replaceIds; + } + + public boolean dataCount() { + return dataCount; + } + + public long dataCountInterval() { + return dataCountInterval; + } + + @Override + public String toString() { + StringBuilder o = new StringBuilder(); + o.append("replaceIds: ").append(replaceIds).append(", "); + o.append("dataCount: ").append(dataCount).append(", "); + o.append("dataCountInterval: ").append(dataCountInterval); + return o.toString(); + } + +} diff --git a/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java index 85aaf96..03027fe 100644 --- a/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java +++ b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListener.java @@ -18,20 +18,20 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose private static final Logger log = Logger.getLogger(MicrometerEventListener.class); private final MeterRegistry registry; private final KeycloakSession session; - private final boolean replace; + private final MicrometerEventConfig config; - public MicrometerEventListener(MeterRegistry registry, KeycloakSession session, boolean replaceId) { + public MicrometerEventListener(MeterRegistry registry, KeycloakSession session, MicrometerEventConfig config) { this.registry = registry; this.session = session; - this.replace = replaceId; + this.config = config; } @Override public void onEvent(Event event) { registry.counter("keycloak_event_user", - "realm", toBlank(replace ? getRealmName(event.getRealmId()) : event.getRealmId()), + "realm", toBlank(config.replaceIds() ? getRealmName(event.getRealmId()) : event.getRealmId()), "type", toBlank(event.getType()), - "client", toBlank(replace ? getClientId(event.getClientId()) : event.getClientId()), + "client", toBlank(config.replaceIds() ? getClientId(event.getClientId()) : event.getClientId()), "error", toBlank(event.getError())) .increment(); } @@ -39,7 +39,7 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose @Override public void onEvent(AdminEvent event, boolean includeRepresentation) { registry.counter("keycloak_event_admin", - "realm", toBlank(replace ? getRealmName(event.getRealmId()) : event.getRealmId()), + "realm", toBlank(config.replaceIds() ? getRealmName(event.getRealmId()) : event.getRealmId()), "resource", toBlank(event.getResourceType()), "operation", toBlank(event.getOperationType()), "error", toBlank(event.getError())) diff --git a/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerFactory.java b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerFactory.java index 298ab6d..b2356d8 100644 --- a/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerFactory.java +++ b/src/main/java/io/kokuwa/keycloak/metrics/MicrometerEventListenerFactory.java @@ -23,45 +23,47 @@ public class MicrometerEventListenerFactory implements EventListenerProviderFact private static final String PROVIDER_ID = "metrics-listener"; private static final int INTERVAL = 60 * 1000; //1 MINUTE - private static final Logger log = Logger.getLogger(MicrometerEventListener.class); - private MeterRegistry registry; - private boolean replace; - @Override - public String getId() { - return PROVIDER_ID; - } + private static final Logger log = Logger.getLogger(MicrometerEventListener.class); + private MeterRegistry registry; + private MicrometerEventConfig config; - @Override - public void init(Scope config) { - replace = "true".equals(System.getenv("KC_METRICS_EVENT_REPLACE_IDS")); - log.info(replace ? "Configured with model names." : "Configured with model ids."); - } + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public void init(Scope scopeConfig) { + config = MicrometerEventConfig.getConfig(); + log.infof("Configuration: %s", config); + } - @Override - public void postInit(KeycloakSessionFactory factory) { - registry = CDI.current().select(MeterRegistry.class).get(); + @Override + public void postInit(KeycloakSessionFactory factory) { + registry = CDI.current().select(MeterRegistry.class).get(); - KeycloakModelUtils.runJobInTransaction(factory, s1 -> { - TimerProvider timer = s1.getProvider(TimerProvider.class); - log.info("Registering gauge update job TimerProvider"); - timer.schedule(() -> { - KeycloakModelUtils.runJobInTransaction(s1.getKeycloakSessionFactory(), s2 -> { - log.info("Updating gauges"); - updateGauges(s2); - }); - }, INTERVAL, PROVIDER_ID); - }); - } + if (config.dataCount()) { + KeycloakModelUtils.runJobInTransaction(factory, s1 -> { + TimerProvider timer = s1.getProvider(TimerProvider.class); + log.info("Registering gauge update job TimerProvider"); + timer.schedule(() -> { + KeycloakModelUtils.runJobInTransaction(s1.getKeycloakSessionFactory(), s2 -> { + log.info("Updating gauges"); + updateGauges(s2); + }); + }, config.dataCountInterval(), PROVIDER_ID); + }); + } + } - @Override - public EventListenerProvider create(KeycloakSession session) { - return new MicrometerEventListener(registry, session, replace); - } - - @Override - public void close() {} + @Override + public EventListenerProvider create(KeycloakSession session) { + return new MicrometerEventListener(registry, session, config); + } + @Override + public void close() {} private Iterable tags(String... tags) { if (tags.length % 2 != 0) throw new IllegalStateException("Tag name value pairs must be even"); @@ -76,32 +78,32 @@ public class MicrometerEventListenerFactory implements EventListenerProviderFact session.realms().getRealmsStream().forEach(realm -> { // keycloak_users = total number of users registry.gauge("keycloak_users", - tags("realm", replace ? realm.getName() : realm.getId()), + tags("realm", config.replaceIds() ? realm.getName() : realm.getId()), session.users().getUsersCount(realm)); - + // keycloak_clients = total number of clients registry.gauge("keycloak_clients", - tags("realm", replace ? realm.getName() : realm.getId()), + tags("realm", config.replaceIds() ? realm.getName() : realm.getId()), realm.getClientsCount()); - + // sessions - by client - + realm.getClientsStream().forEach(client -> { // keycloak_active_user_sessions registry.gauge("keycloak_active_user_sessions", - tags("realm", replace ? realm.getName() : realm.getId(), - "client", replace ? client.getClientId() : client.getId()), + tags("realm", config.replaceIds() ? realm.getName() : realm.getId(), + "client", config.replaceIds() ? client.getClientId() : client.getId()), session.sessions().getActiveUserSessions(realm, client)); // keycloak_active_client_sessions registry.gauge("keycloak_active_client_sessions", - tags("realm", replace ? realm.getName() : realm.getId(), - "client", replace ? client.getClientId() : client.getId()), + tags("realm", config.replaceIds() ? realm.getName() : realm.getId(), + "client", config.replaceIds() ? client.getClientId() : client.getId()), session.sessions().getActiveClientSessionStats(realm,false).get(client.getId())); // keycloak_offline_sessions registry.gauge("keycloak_offline_sessions", - tags("realm", replace ? realm.getName() : realm.getId(), - "client", replace ? client.getClientId() : client.getId()), + tags("realm", config.replaceIds() ? realm.getName() : realm.getId(), + "client", config.replaceIds() ? client.getClientId() : client.getId()), session.sessions().getOfflineSessionsCount(realm, client)); }); });