diff --git a/src/main/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTask.java b/src/main/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTask.java index eabfe2f..0a3c57c 100644 --- a/src/main/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTask.java +++ b/src/main/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTask.java @@ -68,20 +68,24 @@ public void close() {} private void scrape(KeycloakSession session) { session.realms().getRealmsStream().forEach(realm -> { var tagRealm = Tag.of("realm", realm.getName()); - gauge("keycloak_users", Set.of(tagRealm), session.users().getUsersCount(realm)); - gauge("keycloak_clients", Set.of(tagRealm), session.clients().getClientsCount(realm)); + gauge("keycloak_users", Set.of(tagRealm), session.users().getUsersCount(realm), true); + gauge("keycloak_clients", Set.of(tagRealm), session.clients().getClientsCount(realm), true); var sessions = session.sessions(); var activeSessions = sessions.getActiveClientSessionStats(realm, false); realm.getClientsStream().forEach(client -> { var tags = Set.of(tagRealm, Tag.of("client", client.getClientId())); - gauge("keycloak_offline_sessions", tags, sessions.getOfflineSessionsCount(realm, client)); - gauge("keycloak_active_user_sessions", tags, sessions.getActiveUserSessions(realm, client)); - gauge("keycloak_active_client_sessions", tags, activeSessions.getOrDefault(client.getId(), 0L)); + gauge("keycloak_offline_sessions", tags, sessions.getOfflineSessionsCount(realm, client), false); + gauge("keycloak_active_user_sessions", tags, sessions.getActiveUserSessions(realm, client), false); + gauge("keycloak_active_client_sessions", tags, activeSessions.getOrDefault(client.getId(), 0L), false); }); }); } - private void gauge(String name, Set tags, long value) { - values.computeIfAbsent(name + tags, s -> Metrics.gauge(name, tags, new AtomicLong())).set(value); + private void gauge(String name, Set tags, long value, boolean force) { + var key = name + tags; + if (!force && value == 0 && !values.containsKey(key)) { + return; + } + values.computeIfAbsent(key, s -> Metrics.gauge(name, tags, new AtomicLong())).set(value); } } diff --git a/src/test/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTaskTest.java b/src/test/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTaskTest.java index 7e46b8e..63201ce 100644 --- a/src/test/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTaskTest.java +++ b/src/test/java/io/kokuwa/keycloak/metrics/stats/MetricsStatsTaskTest.java @@ -135,12 +135,12 @@ void scrape() { task().run(session); assertUsersCount(realmModel, 0); assertClientsCount(realmModel, 0); - assertOfflineSessions(realmModel, client1Model, 0); - assertOfflineSessions(realmModel, client2Model, 0); - assertActiveUserSessions(realmModel, client1Model, 0); - assertActiveUserSessions(realmModel, client2Model, 0); - assertActiveClientSessions(realmModel, client1Model, 0); - assertActiveClientSessions(realmModel, client2Model, 0); + assertOfflineSessions(realmModel, client1Model, null); + assertOfflineSessions(realmModel, client2Model, null); + assertActiveUserSessions(realmModel, client1Model, null); + assertActiveUserSessions(realmModel, client2Model, null); + assertActiveClientSessions(realmModel, client1Model, null); + assertActiveClientSessions(realmModel, client2Model, null); // initial values @@ -155,12 +155,12 @@ void scrape() { task().run(session); assertUsersCount(realmModel, 10); assertClientsCount(realmModel, 20); - assertOfflineSessions(realmModel, client1Model, 0); + assertOfflineSessions(realmModel, client1Model, null); assertOfflineSessions(realmModel, client2Model, 1); assertActiveUserSessions(realmModel, client1Model, 2); assertActiveUserSessions(realmModel, client2Model, 3); assertActiveClientSessions(realmModel, client1Model, 5); - assertActiveClientSessions(realmModel, client2Model, 0); + assertActiveClientSessions(realmModel, client2Model, null); // updated values @@ -199,19 +199,19 @@ private static void assertClientsCount(RealmModel realm, int count) { assertGauge("keycloak_clients", realm, null, count); } - private static void assertActiveClientSessions(RealmModel realm, ClientModel client, int count) { + private static void assertActiveClientSessions(RealmModel realm, ClientModel client, Integer count) { assertGauge("keycloak_active_client_sessions", realm, client, count); } - private static void assertActiveUserSessions(RealmModel realm, ClientModel client, int count) { + private static void assertActiveUserSessions(RealmModel realm, ClientModel client, Integer count) { assertGauge("keycloak_active_user_sessions", realm, client, count); } - private static void assertOfflineSessions(RealmModel realm, ClientModel client, int count) { + private static void assertOfflineSessions(RealmModel realm, ClientModel client, Integer count) { assertGauge("keycloak_offline_sessions", realm, client, count); } - private static void assertGauge(String name, RealmModel realm, ClientModel client, int count) { + private static void assertGauge(String name, RealmModel realm, ClientModel client, Integer count) { var gauges = Metrics.globalRegistry.getMeters().stream() .filter(Gauge.class::isInstance) .filter(gauge -> gauge.getId().getName().equals(name)) @@ -219,7 +219,11 @@ private static void assertGauge(String name, RealmModel realm, ClientModel clien .filter(gauge -> client == null || gauge.getId().getTag("client").equals(client.getClientId())) .map(Gauge.class::cast) .toList(); - assertEquals(1, gauges.size()); - assertEquals(count, gauges.get(0).value()); + if (count == null) { + assertEquals(0, gauges.size()); + } else { + assertEquals(1, gauges.size()); + assertEquals(count.doubleValue(), gauges.get(0).value()); + } } }