Revert "chore(quarkus): only show OTel Metrics in community build (#49002)" (#49072)

This reverts commit fc667a827a.
This commit is contained in:
Václav Muzikář
2026-05-19 14:33:13 +02:00
committed by GitHub
parent 4aff9a43ce
commit 5e8a7137fa
10 changed files with 21 additions and 99 deletions
@@ -137,9 +137,7 @@ public class Profile {
OPENTELEMETRY("OpenTelemetry support", Type.DEFAULT),
OPENTELEMETRY_LOGS("OpenTelemetry Logs support", Type.PREVIEW, OPENTELEMETRY),
OPENTELEMETRY_METRICS("Micrometer to OpenTelemetry bridge support for metrics", Type.EXPERIMENTAL, 1, false, true,
() -> isClassAvailable("io.quarkus.micrometer.opentelemetry.runtime.MicrometerOtelBridgeRecorder"),
null, OPENTELEMETRY),
OPENTELEMETRY_METRICS("Micrometer to OpenTelemetry bridge support for metrics", Type.EXPERIMENTAL, OPENTELEMETRY),
DECLARATIVE_UI("declarative ui spi", Type.EXPERIMENTAL),
@@ -189,7 +187,6 @@ public class Profile {
private final String unversionedKey;
private final String key;
private final BooleanSupplier isAvailable;
private final boolean hideWhenUnavailable;
private final FeatureUpdatePolicy updatePolicy;
private final Set<Feature> dependencies;
private final boolean deprecated;
@@ -216,16 +213,11 @@ public class Profile {
}
Feature(String label, Type type, int version, boolean deprecated, BooleanSupplier isAvailable, FeatureUpdatePolicy updatePolicy, Feature... dependencies) {
this(label, type, version, deprecated, false, isAvailable, updatePolicy, dependencies);
}
Feature(String label, Type type, int version, boolean deprecated, boolean hideWhenUnavailable, BooleanSupplier isAvailable, FeatureUpdatePolicy updatePolicy, Feature... dependencies) {
this.label = label;
this.type = type;
this.version = version;
this.deprecated = type == Type.DEPRECATED || deprecated;
this.isAvailable = isAvailable;
this.hideWhenUnavailable = hideWhenUnavailable;
this.updatePolicy = updatePolicy == null ? FeatureUpdatePolicy.ROLLING : updatePolicy;
this.key = name().toLowerCase().replaceAll("_", "-");
if (this.name().endsWith("_V" + version)) {
@@ -291,10 +283,6 @@ public class Profile {
return updatePolicy;
}
private boolean isVisible() {
return isAvailable() || !hideWhenUnavailable;
}
public enum Type {
// in priority order
@@ -471,18 +459,11 @@ public class Profile {
}
public static Set<String> getAllUnversionedFeatureNames() {
return Collections.unmodifiableSet(getOrderedFeatures().entrySet().stream()
.filter(e -> e.getValue().stream().anyMatch(Feature::isVisible))
.map(Map.Entry::getKey)
.collect(Collectors.toSet()));
return Collections.unmodifiableSet(getOrderedFeatures().keySet());
}
public static Set<String> getDisableableUnversionedFeatureNames() {
return getOrderedFeatures().entrySet().stream()
.filter(e -> !ESSENTIAL_FEATURES.contains(e.getKey()))
.filter(e -> e.getValue().stream().anyMatch(Feature::isVisible))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
return getOrderedFeatures().keySet().stream().filter(f -> !ESSENTIAL_FEATURES.contains(f)).collect(Collectors.toSet());
}
/**
@@ -601,15 +582,6 @@ public class Profile {
}
}
private static boolean isClassAvailable(String className) {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
public enum FeatureUpdatePolicy {
// Always allow a rolling update when the Feature is enabled/disabled
ROLLING,
+2 -4
View File
@@ -152,8 +152,6 @@ As stated for the general configuration of headers, you can configure custom req
<@kc.start parameters="--telemetry-logs-header-Authorization='Bearer logs-token'"/>
<@profile.ifCommunity>
== Metrics
WARNING: The OpenTelemetry Metrics feature is currently experimental, and it is not recommended for use in production.
@@ -180,6 +178,8 @@ As stated for the general configuration of headers, you can configure custom req
<@kc.start parameters="--telemetry-metrics-header-Authorization='Bearer metrics-token'"/>
<@profile.ifCommunity>
== Development setup
For development purposes, you can use the https://github.com/grafana/docker-otel-lgtm[Grafana OTel-LGTM service], containing OpenTelemetry Collector and backends for logs (Loki), metrics (Prometheus), and traces (Tempo).
@@ -206,10 +206,8 @@ Then, you can navigate to Grafana UI by accessing `+localhost:3000+` and then yo
=== Logs
<@opts.includeOptions includedOptions="telemetry-logs-*"/>
<@profile.ifCommunity>
=== Metrics
<@opts.includeOptions includedOptions="metrics-enabled telemetry-metrics-*"/>
</@profile.ifCommunity>
</@opts.printRelevantOptions>
+5 -17
View File
@@ -204,6 +204,11 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-opentelemetry-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
@@ -261,21 +266,4 @@
</plugins>
</build>
<profiles>
<profile>
<id>community</id>
<activation>
<property>
<name>!product</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-opentelemetry-deployment</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
+5 -14
View File
@@ -121,6 +121,11 @@
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-apache-httpclient-4.3</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-opentelemetry</artifactId>
</dependency>
<dependency>
<groupId>com.apicatalog</groupId>
<artifactId>titanium-json-ld</artifactId>
@@ -851,19 +856,5 @@
</dependency>
</dependencies>
</profile>
<profile>
<id>community</id>
<activation>
<property>
<name>!product</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-opentelemetry</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
@@ -28,7 +28,6 @@ import org.keycloak.config.MetricsOptions;
import org.keycloak.config.OpenApiOptions;
import org.keycloak.config.TelemetryOptions;
import org.keycloak.config.database.Database;
import org.keycloak.quarkus.runtime.cli.PropertyException;
import static java.util.Collections.emptySet;
@@ -188,9 +187,6 @@ public class IgnoredArtifacts {
private static Set<String> otelMetrics() {
boolean isOtelMetricsEnabled = Configuration.isTrue(TelemetryOptions.TELEMETRY_METRICS_ENABLED);
if (isOtelMetricsEnabled && !Profile.Feature.OPENTELEMETRY_METRICS.isAvailable()) {
throw new PropertyException("The OpenTelemetry Metrics feature is not available in this distribution.");
}
return !isOtelMetricsEnabled ? OTEL_METRICS : emptySet();
}
@@ -58,7 +58,6 @@ public class TelemetryPropertyMappers implements PropertyMapperGrouping{
@Override
public List<? extends PropertyMapper<?>> getPropertyMappers() {
TELEMETRY_HEADERS_CACHE = null;
boolean metricsAvailable = Profile.Feature.OPENTELEMETRY_METRICS.isAvailable();
return List.of(
fromFeature(Profile.Feature.OPENTELEMETRY)
.transformer(TelemetryPropertyMappers::checkIfDependantsAreEnabled)
@@ -128,36 +127,36 @@ public class TelemetryPropertyMappers implements PropertyMapperGrouping{
.isMasked(true) // it may contain sensitive information
.build(),
// Telemetry Metrics
fromOption(metricsAvailable ? TELEMETRY_METRICS_ENABLED : toHidden(TELEMETRY_METRICS_ENABLED))
fromOption(TELEMETRY_METRICS_ENABLED)
.isEnabled(TelemetryPropertyMappers::isOtelMetricsFeatureEnabled, OTEL_METRICS_FEATURE_ENABLED_MSG)
.to("quarkus.otel.metrics.enabled")
.build(),
fromOption(metricsAvailable ? TELEMETRY_METRICS_ENDPOINT : toHidden(TELEMETRY_METRICS_ENDPOINT))
fromOption(TELEMETRY_METRICS_ENDPOINT)
.isEnabled(TelemetryPropertyMappers::isTelemetryMetricsEnabled, OTEL_METRICS_ENABLED_MSG)
.mapFrom(TelemetryOptions.TELEMETRY_ENDPOINT)
.to("quarkus.otel.exporter.otlp.metrics.endpoint")
.paramLabel("url")
.validator(TelemetryPropertyMappers::validateEndpoint)
.build(),
fromOption(metricsAvailable ? TELEMETRY_METRICS_PROTOCOL : toHidden(TELEMETRY_METRICS_PROTOCOL))
fromOption(TELEMETRY_METRICS_PROTOCOL)
.isEnabled(TelemetryPropertyMappers::isTelemetryMetricsEnabled, OTEL_METRICS_ENABLED_MSG)
.mapFrom(TelemetryOptions.TELEMETRY_PROTOCOL)
.to("quarkus.otel.exporter.otlp.metrics.protocol")
.paramLabel("protocol")
.build(),
fromOption(metricsAvailable ? TELEMETRY_METRICS_INTERVAL : toHidden(TELEMETRY_METRICS_INTERVAL))
fromOption(TELEMETRY_METRICS_INTERVAL)
.isEnabled(TelemetryPropertyMappers::isTelemetryMetricsEnabled, OTEL_METRICS_ENABLED_MSG)
.to("quarkus.otel.metric.export.interval")
.paramLabel("duration")
.validator(TelemetryPropertyMappers::validateDuration)
.build(),
fromOption(metricsAvailable ? TELEMETRY_METRICS_HEADERS : toHidden(TELEMETRY_METRICS_HEADERS))
fromOption(TELEMETRY_METRICS_HEADERS)
.isEnabled(TelemetryPropertyMappers::isTelemetryMetricsEnabled, OTEL_METRICS_ENABLED_MSG)
.to("quarkus.otel.exporter.otlp.metrics.headers")
.transformer((value, context) -> transformTelemetryHeaders(TELEMETRY_METRICS_HEADER, value))
.isMasked(true)
.build(),
fromOption(metricsAvailable ? TELEMETRY_METRICS_HEADER : toHidden(TELEMETRY_METRICS_HEADER))
fromOption(TELEMETRY_METRICS_HEADER)
.isEnabled(TelemetryPropertyMappers::isTelemetryMetricsEnabled, OTEL_METRICS_ENABLED_MSG)
.paramLabel("<value>")
.isMasked(true) // it may contain sensitive information
@@ -165,10 +164,6 @@ public class TelemetryPropertyMappers implements PropertyMapperGrouping{
);
}
private static <T> Option<T> toHidden(Option<T> option) {
return option.toBuilder().hidden().build();
}
private static String checkIfDependantsAreEnabled(String value, ConfigSourceInterceptorContext context) {
if (TelemetryPropertyMappers.isTelemetryLogsEnabled() || TelemetryPropertyMappers.isTelemetryMetricsEnabled() || TracingPropertyMappers.isTracingEnabled()) {
return Boolean.TRUE.toString();
@@ -36,7 +36,6 @@ import org.keycloak.quarkus.runtime.configuration.AbstractConfigurationTest;
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
import org.apache.commons.io.FileUtils;
import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Test;
import picocli.CommandLine;
@@ -1073,7 +1072,6 @@ public class PicocliTest extends AbstractConfigurationTest {
@Test
public void telemetryParentHeaders() {
Assume.assumeTrue(Profile.Feature.OPENTELEMETRY_METRICS.isAvailable());
// tracing enabled
var nonRunningPicocli = pseudoLaunch("start-dev", "--tracing-enabled=true", "--telemetry-header-Authorization=Bearer asdlkfjadsflkj");
assertNoError(nonRunningPicocli);
@@ -1162,7 +1160,6 @@ public class PicocliTest extends AbstractConfigurationTest {
@Test
public void otelMetricsHeaders() {
Assume.assumeTrue(Profile.Feature.OPENTELEMETRY_METRICS.isAvailable());
// Otel Metrics is disabled
var nonRunningPicocli = pseudoLaunch("start-dev", "--features=opentelemetry-metrics", "--metrics-enabled=true", "--telemetry-metrics-enabled=false", "--telemetry-metrics-header-Authorization=Bearer");
assertError(nonRunningPicocli, "Unknown option:"); //for some reason, the wildcard options does not respect the isEnabled() when disabled
@@ -1648,7 +1645,6 @@ public class PicocliTest extends AbstractConfigurationTest {
@Test
public void otelMetrics() {
Assume.assumeTrue(Profile.Feature.OPENTELEMETRY_METRICS.isAvailable());
// parent feature disabled
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start-dev", "--feature-opentelemetry=disabled", "--feature-opentelemetry-metrics=enabled");
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
@@ -1802,7 +1798,6 @@ public class PicocliTest extends AbstractConfigurationTest {
@Test
public void otelAll() {
Assume.assumeTrue(Profile.Feature.OPENTELEMETRY_METRICS.isAvailable());
// tracing
pseudoLaunch("start-dev", "--tracing-enabled=true");
assertConfig("tracing-enabled", "true");
@@ -50,7 +50,6 @@ import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.in;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
public class IgnoredArtifactsTest extends AbstractConfigurationTest {
@@ -160,7 +159,6 @@ public class IgnoredArtifactsTest extends AbstractConfigurationTest {
@Test
public void otelMetrics(){
assumeTrue(Profile.Feature.OPENTELEMETRY_METRICS.isAvailable());
assertIgnoredArtifacts(IgnoredArtifacts.OTEL_METRICS, TelemetryOptions.TELEMETRY_METRICS_ENABLED);
}
@@ -2,9 +2,6 @@ package org.keycloak.quarkus.runtime.configuration;
import java.util.Map;
import org.keycloak.common.Profile;
import org.junit.Assume;
import org.junit.Test;
public class TelemetryConfigurationTest extends AbstractConfigurationTest {
@@ -129,7 +126,6 @@ public class TelemetryConfigurationTest extends AbstractConfigurationTest {
@Test
public void metricsDefaults() {
Assume.assumeTrue(Profile.Feature.OPENTELEMETRY_METRICS.isAvailable());
initConfig();
assertConfig(Map.of(
@@ -150,7 +146,6 @@ public class TelemetryConfigurationTest extends AbstractConfigurationTest {
@Test
public void metricsPriorities() {
Assume.assumeTrue(Profile.Feature.OPENTELEMETRY_METRICS.isAvailable());
ConfigArgsConfigSource.setCliArgs("--features=opentelemetry-metrics", "--metrics-enabled=true", "--telemetry-metrics-enabled=true", "--telemetry-metrics-endpoint=localhost:2000", "--telemetry-metrics-protocol=http/protobuf");
initConfig();
assertConfig(Map.of(
-6
View File
@@ -128,12 +128,6 @@
</exclusion>
</exclusions>
</dependency>
<!-- needed for FeatureCompatibilityMetadataProviderTest to detect OPENTELEMETRY_METRICS as available -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-opentelemetry</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>