Skip to content

Commit 0d0affd

Browse files
Add example for logging slow database operations.
1 parent bca0a7d commit 0d0affd

File tree

3 files changed

+153
-1
lines changed

3 files changed

+153
-1
lines changed

deployments/local/dev/docker-compose-keycloakx.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ services:
8080
# - "--log-level=info,org.hibernate:debug"
8181
# - "--log-level=info,org.hibernate.SQL:debug"
8282
# - "--log-level=info,org.hibernate.SQL:debug,org.hibernate.type.descriptor.sql.BasicBinder:trace"
83-
- "--log-level=info,com.github.thomasdarimont.keycloak.custom.health.CustomHealthChecks:info,com.github.thomasdarimont.keycloak.custom:debug,com.arjuna.ats.jta:off,org.keycloak.services.resources.admin.permissions:debug"
83+
- "--log-level=info,com.github.thomasdarimont.keycloak.custom.health.CustomHealthChecks:info,com.github.thomasdarimont.keycloak.custom:debug,com.arjuna.ats.jta:off,org.keycloak.services.resources.admin.permissions:debug,org.hibernate.SQL_SLOW:info"
8484
# - "--verbose"
8585
# - "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog"
8686
- "-Dio.netty.http2.maxHeaderListSize=16384"
@@ -118,6 +118,7 @@ services:
118118
- ./keycloak-ext/keycloak-restrict-client-auth-25.0.0.jar:/opt/keycloak/providers/keycloak-restrict-client-auth.jar:z
119119
- ./keycloak-ext/keycloak-home-idp-discovery-25.0.0.jar:/opt/keycloak/providers/keycloak-home-idp-discovery.jar:z
120120
- ./keycloak-ext/apple-identity-provider-1.13.0.jar:/opt/keycloak/providers/apple-identity-provider.jar:z
121+
- ./keycloak-ext/keycloak-benchmark-dataset-999.0.0-SNAPSHOT.jar:/opt/keycloak/providers/keycloak-benchmark-dataset.jar:z
121122
# - ./keycloak-ext/flyweight-user-storage-provider-extension-1.0.0.0-SNAPSHOT.jar:/opt/keycloak/providers/flyweight-user-storage-provider-extension-1.0.0.0-SNAPSHOT.jar:z
122123
- ./keycloakx/health_check.sh:/health_check.sh:z
123124

keycloak/extensions/src/main/java/com/github/thomasdarimont/keycloak/custom/endpoints/demo/DemosResource.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package com.github.thomasdarimont.keycloak.custom.endpoints.demo;
22

33
import com.github.thomasdarimont.keycloak.custom.oauth.client.OauthClientCredentialsTokenManager;
4+
import jakarta.persistence.Query;
45
import jakarta.ws.rs.Consumes;
56
import jakarta.ws.rs.GET;
67
import jakarta.ws.rs.Path;
78
import jakarta.ws.rs.Produces;
89
import jakarta.ws.rs.core.MediaType;
910
import jakarta.ws.rs.core.Response;
1011
import org.keycloak.broker.provider.util.SimpleHttp;
12+
import org.keycloak.connections.jpa.JpaConnectionProvider;
1113
import org.keycloak.models.KeycloakSession;
1214

1315
import java.util.Map;
@@ -45,4 +47,21 @@ public Response demoCachedServiceAccountToken() throws Exception {
4547

4648
return Response.ok(data).build();
4749
}
50+
51+
/**
52+
* http://localhost:8080/auth/realms/acme-internal/custom-resources/demos/slow-query
53+
*
54+
* @return
55+
* @throws Exception
56+
*/
57+
@Path("slow-query")
58+
@GET
59+
public Response demoSlowQuery() throws Exception {
60+
61+
var provider = session.getProvider(JpaConnectionProvider.class);
62+
Query nativeQuery = provider.getEntityManager().createNativeQuery("SELECT pg_sleep(5)");
63+
nativeQuery.getResultList();
64+
65+
return Response.ok(Map.of("executed", true)).build();
66+
}
4867
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<!--
2+
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
3+
~ and other contributors as indicated by the @author tags.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
18+
<!-- Workaround to use custom hibernate properties, see: https://github.com/keycloak/keycloak/issues/19427#issuecomment-2792484805 -->
19+
20+
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
23+
version="3.0">
24+
<persistence-unit name="keycloak-default" transaction-type="RESOURCE_LOCAL">
25+
<class>org.keycloak.models.jpa.entities.ClientEntity</class>
26+
<class>org.keycloak.models.jpa.entities.ClientAttributeEntity</class>
27+
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
28+
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
29+
<class>org.keycloak.models.jpa.entities.RealmAttributeEntity</class>
30+
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
31+
<class>org.keycloak.models.jpa.entities.ComponentConfigEntity</class>
32+
<class>org.keycloak.models.jpa.entities.ComponentEntity</class>
33+
<class>org.keycloak.models.jpa.entities.UserFederationProviderEntity</class>
34+
<class>org.keycloak.models.jpa.entities.UserFederationMapperEntity</class>
35+
<class>org.keycloak.models.jpa.entities.RoleEntity</class>
36+
<class>org.keycloak.models.jpa.entities.RoleAttributeEntity</class>
37+
<class>org.keycloak.models.jpa.entities.FederatedIdentityEntity</class>
38+
<class>org.keycloak.models.jpa.entities.MigrationModelEntity</class>
39+
<class>org.keycloak.models.jpa.entities.UserEntity</class>
40+
<class>org.keycloak.models.jpa.entities.RealmLocalizationTextsEntity</class>
41+
<class>org.keycloak.models.jpa.entities.UserRequiredActionEntity</class>
42+
<class>org.keycloak.models.jpa.entities.UserAttributeEntity</class>
43+
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
44+
<class>org.keycloak.models.jpa.entities.IdentityProviderEntity</class>
45+
<class>org.keycloak.models.jpa.entities.IdentityProviderMapperEntity</class>
46+
<class>org.keycloak.models.jpa.entities.ProtocolMapperEntity</class>
47+
<class>org.keycloak.models.jpa.entities.UserConsentEntity</class>
48+
<class>org.keycloak.models.jpa.entities.UserConsentClientScopeEntity</class>
49+
<class>org.keycloak.models.jpa.entities.AuthenticationFlowEntity</class>
50+
<class>org.keycloak.models.jpa.entities.AuthenticationExecutionEntity</class>
51+
<class>org.keycloak.models.jpa.entities.AuthenticatorConfigEntity</class>
52+
<class>org.keycloak.models.jpa.entities.RequiredActionProviderEntity</class>
53+
<class>org.keycloak.models.jpa.session.PersistentUserSessionEntity</class>
54+
<class>org.keycloak.models.jpa.session.PersistentClientSessionEntity</class>
55+
<class>org.keycloak.models.jpa.entities.RevokedTokenEntity</class>
56+
<class>org.keycloak.models.jpa.entities.GroupEntity</class>
57+
<class>org.keycloak.models.jpa.entities.GroupAttributeEntity</class>
58+
<class>org.keycloak.models.jpa.entities.GroupRoleMappingEntity</class>
59+
<class>org.keycloak.models.jpa.entities.UserGroupMembershipEntity</class>
60+
<class>org.keycloak.models.jpa.entities.ClientScopeEntity</class>
61+
<class>org.keycloak.models.jpa.entities.ClientScopeAttributeEntity</class>
62+
<class>org.keycloak.models.jpa.entities.ClientScopeRoleMappingEntity</class>
63+
<class>org.keycloak.models.jpa.entities.ClientScopeClientMappingEntity</class>
64+
<class>org.keycloak.models.jpa.entities.DefaultClientScopeRealmMappingEntity</class>
65+
<class>org.keycloak.models.jpa.entities.ClientInitialAccessEntity</class>
66+
67+
<!-- JpaAuditProviders -->
68+
<class>org.keycloak.events.jpa.EventEntity</class>
69+
<class>org.keycloak.events.jpa.AdminEventEntity</class>
70+
71+
<!-- Authorization -->
72+
<class>org.keycloak.authorization.jpa.entities.ResourceServerEntity</class>
73+
<class>org.keycloak.authorization.jpa.entities.ResourceEntity</class>
74+
<class>org.keycloak.authorization.jpa.entities.ScopeEntity</class>
75+
<class>org.keycloak.authorization.jpa.entities.PolicyEntity</class>
76+
<class>org.keycloak.authorization.jpa.entities.PermissionTicketEntity</class>
77+
<class>org.keycloak.authorization.jpa.entities.ResourceAttributeEntity</class>
78+
79+
<!-- User Federation Storage -->
80+
<class>org.keycloak.storage.jpa.entity.BrokerLinkEntity</class>
81+
<class>org.keycloak.storage.jpa.entity.FederatedUser</class>
82+
<class>org.keycloak.storage.jpa.entity.FederatedUserAttributeEntity</class>
83+
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentEntity</class>
84+
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentClientScopeEntity</class>
85+
<class>org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity</class>
86+
<class>org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity</class>
87+
<class>org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity</class>
88+
<class>org.keycloak.storage.jpa.entity.FederatedUserRoleMappingEntity</class>
89+
90+
<!-- Organization -->
91+
<class>org.keycloak.models.jpa.entities.OrganizationEntity</class>
92+
<class>org.keycloak.models.jpa.entities.OrganizationDomainEntity</class>
93+
94+
<exclude-unlisted-classes>true</exclude-unlisted-classes>
95+
96+
<properties>
97+
<property name="jboss.as.jpa.managed" value="false"/>
98+
99+
<!-- Execute multiple insert and update statements in a single call to improve bulk insert / update performance.
100+
See https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#best-practices-jdbc-batching
101+
and https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#batch-session-batch:
102+
recommendation between 10 and 50 -->
103+
<property name="hibernate.jdbc.batch_size" value="32" />
104+
105+
<!-- (optional) Allows for more batching for nested objects and less deadlocks, but according to
106+
https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#batch-jdbcbatch
107+
may also hava a negative impact on performance.
108+
See also https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#best-practices-jdbc-batching.
109+
Keycloak uses many nested objects spread across multiple tables, so a benefit is likely.
110+
-->
111+
<property name="hibernate.order_inserts" value="true" />
112+
<property name="hibernate.order_updates" value="true" />
113+
114+
<!-- Batch fetching collections of entity proxies, default 1. Eases N+1 issues to some extent.
115+
See https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#fetching-batch -->
116+
<property name="hibernate.default_batch_fetch_size" value="8" />
117+
118+
<!-- Improve cache hits for execution plans.
119+
See https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#configurations-query -->
120+
<property name="hibernate.query.in_clause_parameter_padding" value="true"/>
121+
122+
<!-- Increase number of elements fetched at once from Oracle database query result up from 10.
123+
MSSQL returns the whole result at once.
124+
See https://docs.oracle.com/en/database/oracle/oracle-database/21/jjdbc/resultset.html -->
125+
<property name="hibernate.jdbc.fetch_size" value="64" />
126+
127+
<property name="hibernate.log_slow_query" value="5000"/>
128+
<property name="hibernate.use_sql_comments" value="true"/>
129+
130+
</properties>
131+
</persistence-unit>
132+
</persistence>

0 commit comments

Comments
 (0)