added DATA_COUNT and DATA_COUNT_INTERVAL params. extracted into separate config.

This commit is contained in:
Garth 2023-04-07 10:42:01 +02:00
parent d88e22d899
commit 3b148f90f7
3 changed files with 104 additions and 50 deletions

View file

@ -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();
}
}

View file

@ -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()))

View file

@ -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 postInit(KeycloakSessionFactory factory) {
registry = CDI.current().select(MeterRegistry.class).get();
@Override
public void init(Scope scopeConfig) {
config = MicrometerEventConfig.getConfig();
log.infof("Configuration: %s", config);
}
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);
});
}
@Override
public void postInit(KeycloakSessionFactory factory) {
registry = CDI.current().select(MeterRegistry.class).get();
@Override
public EventListenerProvider create(KeycloakSession session) {
return new MicrometerEventListener(registry, session, replace);
}
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 void close() {}
@Override
public EventListenerProvider create(KeycloakSession session) {
return new MicrometerEventListener(registry, session, config);
}
@Override
public void close() {}
private Iterable<Tag> tags(String... tags) {
if (tags.length % 2 != 0) throw new IllegalStateException("Tag name value pairs must be even");
@ -76,12 +78,12 @@ 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
@ -89,19 +91,19 @@ public class MicrometerEventListenerFactory implements EventListenerProviderFact
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));
});
});