Add a Maven profile to remove GELF support (#22615)

Closes #22515

Co-authored-by: Václav Muzikář <vmuzikar@redhat.com>
This commit is contained in:
Martin Bartoš 2023-08-29 19:03:08 +02:00 committed by GitHub
parent 108fefe90b
commit 7c013e8d48
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 155 additions and 15 deletions

View file

@ -1,6 +1,7 @@
<#import "/templates/guide.adoc" as tmpl>
<#import "/templates/kc.adoc" as kc>
<#import "/templates/links.adoc" as links>
<#import "/templates/profile.adoc" as profile>
<@tmpl.guide
title="Configuring logging"
@ -12,7 +13,9 @@ Keycloak uses the JBoss Logging framework. The following is a high-level overvie
* root
** console (_default_)
** file
<@profile.ifCommunity>
** GELF
</@profile.ifCommunity>
== Logging configuration
Logging is done on a per-category basis in Keycloak. You can configure logging for the root log level or for more specific categories such as `org.hibernate` or `org.keycloak`. This {section} describes how to configure logging.
@ -69,7 +72,14 @@ To enable log handlers, enter the following command:
<@kc.start parameters="--log=\"<handler1>,<handler2>\""/>
The available handlers are `console`, `file` and `gelf`. The more specific handler configuration mentioned below will only take effect when the handler is added to this comma-separated list.
The available handlers are
<@profile.ifCommunity>
`console`, `file` and `gelf`.
</@profile.ifCommunity>
<@profile.ifProduct>
`console` and `file`.
</@profile.ifProduct>
The more specific handler configuration mentioned below will only take effect when the handler is added to this comma-separated list.
== Console log handler
The console log handler is enabled by default, providing unstructured log messages for the console.
@ -178,6 +188,8 @@ To configure a different logging format for the file log handler, enter the foll
See <<Configuring the console log format>> for more information and a table of the available pattern configuration.
<@profile.ifCommunity>
== Centralized logging using GELF
Keycloak can send logs to a centralized log management system such as the following:
@ -497,4 +509,6 @@ Currently, the Keycloak configuration does not support partly dynamic configurat
To add user-defined fields, you can provide these fields through a quarkus.properties file. See <@links.server id="configuration"/> and the _Using raw Quarkus properties_ section.
</@profile.ifCommunity>
</@tmpl.guide>

View file

@ -1,8 +1,10 @@
package org.keycloak.config;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.function.Predicate;
public class LoggingOptions {
@ -11,6 +13,7 @@ public class LoggingOptions {
public static final Output DEFAULT_CONSOLE_OUTPUT = Output.DEFAULT;
public static final String DEFAULT_LOG_FILENAME = "keycloak.log";
public static final String DEFAULT_LOG_PATH = "data" + File.separator + "log" + File.separator + DEFAULT_LOG_FILENAME;
public static final Boolean GELF_ACTIVATED = isGelfActivated();
public enum Handler {
console,
@ -18,9 +21,19 @@ public class LoggingOptions {
gelf
}
public static List<String> getAvailableHandlerNames() {
final Predicate<Handler> checkGelf = (handler) -> GELF_ACTIVATED || !handler.equals(Handler.gelf);
return Arrays.stream(Handler.values())
.filter(checkGelf)
.map(Handler::name)
.toList();
}
public static final Option LOG = new OptionBuilder("log", List.class, Handler.class)
.category(OptionCategory.LOGGING)
.description("Enable one or more log handlers in a comma-separated list.")
.expectedValues(() -> getAvailableHandlerNames())
.defaultValue(DEFAULT_LOG_HANDLER)
.build();
@ -168,4 +181,13 @@ public class LoggingOptions {
.description("Include source code location.")
.defaultValue(Boolean.TRUE)
.build();
private static boolean isGelfActivated() {
try {
Thread.currentThread().getContextClassLoader().loadClass("io.quarkus.logging.gelf.GelfConfig");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}

View file

@ -149,10 +149,6 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-logging-json-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-logging-gelf-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
@ -197,4 +193,21 @@
</plugins>
</build>
<profiles>
<profile>
<id>includeGelf</id>
<activation>
<property>
<name>!product</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-logging-gelf-deployment</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View file

@ -109,10 +109,6 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-logging-json</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-logging-gelf</artifactId>
</dependency>
<!-- SmallRye -->
<dependency>
@ -736,4 +732,21 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>includeGelf</id>
<activation>
<property>
<name>!product</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-logging-gelf</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View file

@ -1,18 +1,18 @@
package org.keycloak.quarkus.runtime.configuration.mappers;
import static java.util.Optional.of;
import static org.keycloak.config.LoggingOptions.GELF_ACTIVATED;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import static org.keycloak.quarkus.runtime.integration.QuarkusPlatform.addInitializationException;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.jboss.logmanager.LogContext;
import org.keycloak.config.LoggingOptions;
import org.keycloak.quarkus.runtime.Messages;
@ -24,7 +24,7 @@ public final class LoggingPropertyMappers {
private LoggingPropertyMappers(){}
public static PropertyMapper[] getMappers() {
return new PropertyMapper[] {
PropertyMapper[] defaultMappers = new PropertyMapper[]{
fromOption(LoggingOptions.LOG)
.paramLabel("<handler>")
.build(),
@ -68,7 +68,14 @@ public final class LoggingPropertyMappers {
.to("quarkus.log.level")
.transformer(LoggingPropertyMappers::resolveLogLevel)
.paramLabel("category:level")
.build(),
.build()
};
return GELF_ACTIVATED ? ArrayUtils.addAll(defaultMappers, getGelfMappers()) : defaultMappers;
}
public static PropertyMapper[] getGelfMappers() {
return new PropertyMapper[]{
fromOption(LoggingOptions.LOG_GELF_ENABLED)
.mapFrom("log")
.to("quarkus.log.handler.gelf.enabled")
@ -126,7 +133,7 @@ public final class LoggingPropertyMappers {
}
String[] logHandlerValues = handlers.split(",");
List<String> availableLogHandlers = Arrays.stream(LoggingOptions.Handler.values()).map(Enum::name).collect(Collectors.toList());
final List<String> availableLogHandlers = LoggingOptions.getAvailableHandlerNames();
if (!availableLogHandlers.containsAll(List.of(logHandlerValues))) {
addInitializationException(Messages.notRecognizedValueInList("log", handlers, String.join(",", availableLogHandlers)));

View file

@ -163,6 +163,26 @@
</plugins>
</build>
</profile>
<profile>
<id>includeGelf</id>
<activation>
<property>
<name>!product</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<includeGelf>true</includeGelf>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View file

@ -0,0 +1,43 @@
/*
* Copyright 2023 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.
*/
package org.keycloak.it.cli.dist;
import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult;
import org.junit.jupiter.api.Test;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.RawDistOnly;
import org.keycloak.quarkus.runtime.cli.command.StartDev;
@DistributionTest
@RawDistOnly(reason = "Verifying the help message output doesn't need long spin-up of docker dist tests.")
public class GelfRemovedTest {
public static final String INCLUDE_GELF_PROPERTY = "includeGelf";
@Test
@Launch({StartDev.NAME, "--help-all"})
void checkGelfRemoved(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
if (Boolean.getBoolean(INCLUDE_GELF_PROPERTY)) {
cliResult.assertMessage("gelf");
} else {
cliResult.assertNoMessage("gelf");
}
}
}

View file

@ -18,12 +18,15 @@
package org.keycloak.it.cli.dist;
import static org.junit.Assert.assertEquals;
import static org.keycloak.it.cli.dist.GelfRemovedTest.INCLUDE_GELF_PROPERTY;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG;
import java.util.List;
import org.approvaltests.Approvals;
import org.approvaltests.namer.NamedEnvironment;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.keycloak.it.approvaltests.KcNamerFactory;
@ -44,6 +47,11 @@ import io.quarkus.test.junit.main.LaunchResult;
@RawDistOnly(reason = "Verifying the help message output doesn't need long spin-up of docker dist tests.")
public class HelpCommandDistTest {
@BeforeAll
public static void assumeGelfEnabled() {
Assumptions.assumeTrue(Boolean.getBoolean(INCLUDE_GELF_PROPERTY), "Assume GELF support is given in order to simplify these test cases");
}
@Test
@Launch({})
void testDefaultToHelp(LaunchResult result) {
@ -52,7 +60,7 @@ public class HelpCommandDistTest {
}
@Test
@Launch({ "--help" })
@Launch({"--help"})
void testHelp(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertHelp(cliResult);