Do not enable caching metrics by default and provide a guide

Closes #16751
This commit is contained in:
Pedro Igor 2023-01-31 16:17:03 -03:00 committed by Václav Muzikář
parent d9025231f9
commit b5fb528508
5 changed files with 215 additions and 3 deletions

View file

@ -1,6 +1,7 @@
<#import "/templates/guide.adoc" as tmpl> <#import "/templates/guide.adoc" as tmpl>
<#import "/templates/kc.adoc" as kc> <#import "/templates/kc.adoc" as kc>
<#import "/templates/options.adoc" as opts> <#import "/templates/options.adoc" as opts>
<#import "/templates/links.adoc" as links>
<@tmpl.guide <@tmpl.guide
title="Configuring distributed caches" title="Configuring distributed caches"
@ -223,7 +224,31 @@ For more details, see https://infinispan.org/docs/stable/titles/server/server.ht
By default, the value set to the `cache-stack` option has precedence over the transport stack you define in the cache configuration file. By default, the value set to the `cache-stack` option has precedence over the transport stack you define in the cache configuration file.
If you are defining a custom stack, make sure the `cache-stack` option is not used for the custom changes to take effect. If you are defining a custom stack, make sure the `cache-stack` option is not used for the custom changes to take effect.
=== Securing cache communication == Securing cache communication
The current Infinispan cache implementation should be secured by various security measures such as RBAC, ACLs, and Transport stack encryption. For more information about securing cache communication, see the https://infinispan.org/docs/dev/titles/security/security.html#[Infinispan security guide]. The current Infinispan cache implementation should be secured by various security measures such as RBAC, ACLs, and Transport stack encryption. For more information about securing cache communication, see the https://infinispan.org/docs/dev/titles/security/security.html#[Infinispan security guide].
== Exposing metrics from caches
By default, metrics from caches are not automatically exposed when the metrics are enabled.
For more details about how to enable metrics, see the <@links.server id="configuration-metrics"/> guide.
To enable global metrics for all caches within the `cache-container`, you need to change your cache configuration file (e.g.: `conf/cache-ispn.xml`) to enable `statistics` at the `cache-container` level as follows:
.enabling metrics for all caches
[source]
----
<cache-container name="keycloak" statistics="true">
...
</cache-container>
----
Similarly, you can enable metrics individually for each cache by enabling `statistics` as follows:
.enabling metrics for a specific cache
----
<local-cache name="realms" statistics="true">
...
</local-cache>
----
</@tmpl.guide> </@tmpl.guide>

View file

@ -0,0 +1,79 @@
<#import "/templates/guide.adoc" as tmpl>
<#import "/templates/kc.adoc" as kc>
<#import "/templates/options.adoc" as opts>
<#import "/templates/links.adoc" as links>
<@tmpl.guide
title="Enabling Keycloak Metrics"
summary="Learn how to enable and expose metrics from the server"
includedOptions="metrics-enabled">
Keycloak has built in support for metrics. This guide describes how to enable and configure server metrics.
== Enabling Metrics
It is possible to enable metrics using the build time option `metrics-enabled`:
<@kc.start parameters="--metrics-enabled=true"/>
== Querying Metrics
Keycloak exposes metrics at the following endpoint:
* `/metrics`
The response from the endpoint uses a `text/plain` content type and it is based on the Prometheus text format. The snippet bellow
is an example of a response:
[source]
----
# HELP base_gc_total Displays the total number of collections that have occurred. This attribute lists -1 if the collection count is undefined for this collector.
# TYPE base_gc_total counter
base_gc_total{name="G1 Young Generation",} 14.0
# HELP jvm_memory_usage_after_gc_percent The percentage of long-lived heap pool used after the last GC event, in the range [0..1]
# TYPE jvm_memory_usage_after_gc_percent gauge
jvm_memory_usage_after_gc_percent{area="heap",pool="long-lived",} 0.0
# HELP jvm_threads_peak_threads The peak live thread count since the Java virtual machine started or peak was reset
# TYPE jvm_threads_peak_threads gauge
jvm_threads_peak_threads 113.0
# HELP agroal_active_count Number of active connections. These connections are in use and not available to be acquired.
# TYPE agroal_active_count gauge
agroal_active_count{datasource="default",} 0.0
# HELP base_memory_maxHeap_bytes Displays the maximum amount of memory, in bytes, that can be used for memory management.
# TYPE base_memory_maxHeap_bytes gauge
base_memory_maxHeap_bytes 1.6781410304E10
# HELP process_start_time_seconds Start time of the process since unix epoch.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.675188449054E9
# HELP system_load_average_1m The sum of the number of runnable entities queued to available processors and the number of runnable entities running on the available processors averaged over a period of time
# TYPE system_load_average_1m gauge
system_load_average_1m 4.005859375
...
----
== Available Metrics
The table below summarizes the available metrics groups:
|===
|*Metric* | *Description*
|System
|A set of system-level metrics related to CPU and memory usage.
|JVM
|A set of metrics from the Java Virtual Machine (JVM) related to GC, and heap.
|Database
|A set of metrics from the database connection pool, if using a database.
|HTTP
|A set of global and individual metrics from the HTTP endpoints
|Cache
|A set of metrics from Infinispan caches. See <@links.server id="caching"/> guide for more details.
|===
</@tmpl.guide>

View file

@ -84,7 +84,6 @@ public class CacheManagerFactory {
} }
if (metricsEnabled) { if (metricsEnabled) {
builder.getNamedConfigurationBuilders().values().stream().forEach(b -> b.statistics().enable());
builder.getGlobalConfigurationBuilder().addModule(MicrometerMeterRegisterConfigurationBuilder.class); builder.getGlobalConfigurationBuilder().addModule(MicrometerMeterRegisterConfigurationBuilder.class);
builder.getGlobalConfigurationBuilder().module(MicrometerMeterRegisterConfigurationBuilder.class).meterRegistry(Metrics.globalRegistry); builder.getGlobalConfigurationBuilder().module(MicrometerMeterRegisterConfigurationBuilder.class).meterRegistry(Metrics.globalRegistry);
} }

View file

@ -19,13 +19,18 @@ package org.keycloak.it.cli.dist;
import static io.restassured.RestAssured.when; import static io.restassured.RestAssured.when;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.keycloak.it.junit5.extension.BeforeStartDistribution;
import org.keycloak.it.junit5.extension.DistributionTest; import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.LegacyStore; import org.keycloak.it.junit5.extension.LegacyStore;
import org.keycloak.it.junit5.extension.RawDistOnly;
import org.keycloak.it.utils.KeycloakDistribution; import org.keycloak.it.utils.KeycloakDistribution;
import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.Launch;
@ -49,7 +54,17 @@ public class MetricsDistTest {
when().get("/metrics").then() when().get("/metrics").then()
.statusCode(200) .statusCode(200)
.body(containsString("jvm_gc_")) .body(containsString("jvm_gc_"))
.body(containsString("vendor_cache_manager_keycloak_cache_realms_")); .body(not(containsString("vendor_cache_manager_keycloak_cache_realms_")));
}
@Test
@Launch({ "start-dev", "--metrics-enabled=true", "--cache-config-file=cache-local.xml" })
@BeforeStartDistribution(EnableCachingStatistics.class)
@RawDistOnly(reason = "No support mounting files to containers. Testing raw dist is enough.")
void testExposeCachingMetrics() {
when().get("/metrics").then()
.statusCode(200)
.body(containsString("vendor_cache_manager_keycloak_cache_"));
} }
@Test @Test
@ -101,4 +116,11 @@ public class MetricsDistTest {
distribution.stop(); distribution.stop();
} }
} }
public static class EnableCachingStatistics implements Consumer<KeycloakDistribution> {
@Override
public void accept(KeycloakDistribution dist) {
dist.copyOrReplaceFileFromClasspath("/cache-local.xml", Paths.get("conf", "cache-local.xml"));
}
}
} }

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2019 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd"
xmlns="urn:infinispan:config:11.0">
<cache-container name="keycloak" statistics="true">
<local-cache name="default">
<transaction transaction-manager-lookup="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup"/>
</local-cache>
<local-cache name="realms">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory max-count="10000"/>
</local-cache>
<local-cache name="users">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory max-count="10000"/>
</local-cache>
<local-cache name="sessions">
<expiration lifespan="-1"/>
</local-cache>
<local-cache name="authenticationSessions">
<expiration lifespan="-1"/>
</local-cache>
<local-cache name="offlineSessions">
<expiration lifespan="-1"/>
</local-cache>
<local-cache name="clientSessions">
<expiration lifespan="-1"/>
</local-cache>
<local-cache name="offlineClientSessions">
<expiration lifespan="-1"/>
</local-cache>
<local-cache name="loginFailures">
<expiration lifespan="-1"/>
</local-cache>
<local-cache name="authorization">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory max-count="10000"/>
</local-cache>
<local-cache name="work">
<expiration lifespan="-1"/>
</local-cache>
<local-cache name="keys">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="3600000"/>
<memory max-count="1000"/>
</local-cache>
<local-cache name="actionTokens">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="-1" lifespan="-1" interval="300000"/>
<memory max-count="-1"/>
</local-cache>
</cache-container>
</infinispan>