Tracing - Configurable service name and resource attributes

Closes #32056

Signed-off-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
Martin Bartoš 2024-08-13 13:20:37 +02:00 committed by Alexander Schwartz
parent 4d7f25535c
commit 3ff825807f
10 changed files with 160 additions and 4 deletions

View file

@ -22,6 +22,11 @@ It is possible to enable exposing traces using the build time option `tracing-en
<@kc.start parameters="--tracing-enabled=true"/> <@kc.start parameters="--tracing-enabled=true"/>
By default, the trace exporters send out data in batches, using the `gRPC` protocol and endpoint `+http://localhost:4317+`. By default, the trace exporters send out data in batches, using the `gRPC` protocol and endpoint `+http://localhost:4317+`.
The default service name is `keycloak`, specified via the `tracing-service-name` property, which takes precedence over `service.name` defined in the `tracing-resource-attributes` property.
For more information about resource attributes that can be provided via the `tracing-resource-attributes` property, see the https://quarkus.io/guides/opentelemetry#resource[Quarkus OpenTelemetry Resource] guide.
For more tracing settings, see all possible configurations below. For more tracing settings, see all possible configurations below.
== Development setup == Development setup

View file

@ -20,6 +20,7 @@ package org.keycloak.config;
import io.quarkus.opentelemetry.runtime.config.build.SamplerType; import io.quarkus.opentelemetry.runtime.config.build.SamplerType;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
public class TracingOptions { public class TracingOptions {
@ -43,6 +44,16 @@ public class TracingOptions {
.buildTime(true) .buildTime(true)
.build(); .build();
public static final Option<String> TRACING_SERVICE_NAME = new OptionBuilder<>("tracing-service-name", String.class)
.category(OptionCategory.TRACING)
.description("OpenTelemetry service name. Takes precedence over 'service.name' defined in the 'tracing-resource-attributes' property.")
.defaultValue("keycloak")
.build();
public static final Option<List<String>> TRACING_RESOURCE_ATTRIBUTES = OptionBuilder.listOptionBuilder("tracing-resource-attributes", String.class)
.category(OptionCategory.TRACING)
.description("OpenTelemetry resource attributes present in the exported trace to characterize the telemetry producer. Values in format 'key1=val1,key2=val2'. For more information, check the Tracing guide.")
.build();
public static final Option<String> TRACING_PROTOCOL = new OptionBuilder<>("tracing-protocol", String.class) public static final Option<String> TRACING_PROTOCOL = new OptionBuilder<>("tracing-protocol", String.class)
.category(OptionCategory.TRACING) .category(OptionCategory.TRACING)
.description("OpenTelemetry protocol used for the telemetry data.") .description("OpenTelemetry protocol used for the telemetry data.")

View file

@ -31,8 +31,10 @@ import static org.keycloak.config.TracingOptions.TRACING_ENABLED;
import static org.keycloak.config.TracingOptions.TRACING_ENDPOINT; import static org.keycloak.config.TracingOptions.TRACING_ENDPOINT;
import static org.keycloak.config.TracingOptions.TRACING_JDBC_ENABLED; import static org.keycloak.config.TracingOptions.TRACING_JDBC_ENABLED;
import static org.keycloak.config.TracingOptions.TRACING_PROTOCOL; import static org.keycloak.config.TracingOptions.TRACING_PROTOCOL;
import static org.keycloak.config.TracingOptions.TRACING_RESOURCE_ATTRIBUTES;
import static org.keycloak.config.TracingOptions.TRACING_SAMPLER_RATIO; import static org.keycloak.config.TracingOptions.TRACING_SAMPLER_RATIO;
import static org.keycloak.config.TracingOptions.TRACING_SAMPLER_TYPE; import static org.keycloak.config.TracingOptions.TRACING_SAMPLER_TYPE;
import static org.keycloak.config.TracingOptions.TRACING_SERVICE_NAME;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
public class TracingPropertyMappers { public class TracingPropertyMappers {
@ -52,6 +54,16 @@ public class TracingPropertyMappers {
.paramLabel("url") .paramLabel("url")
.validator(TracingPropertyMappers::validateEndpoint) .validator(TracingPropertyMappers::validateEndpoint)
.build(), .build(),
fromOption(TRACING_SERVICE_NAME)
.isEnabled(TracingPropertyMappers::isTracingEnabled, TRACING_ENABLED_MSG)
.to("quarkus.otel.service.name")
.paramLabel("name")
.build(),
fromOption(TRACING_RESOURCE_ATTRIBUTES)
.isEnabled(TracingPropertyMappers::isTracingEnabled, TRACING_ENABLED_MSG)
.to("quarkus.otel.resource.attributes")
.paramLabel("attributes")
.build(),
fromOption(TRACING_PROTOCOL) fromOption(TRACING_PROTOCOL)
.isEnabled(TracingPropertyMappers::isTracingEnabled, TRACING_ENABLED_MSG) .isEnabled(TracingPropertyMappers::isTracingEnabled, TRACING_ENABLED_MSG)
.to("quarkus.otel.exporter.otlp.traces.protocol") .to("quarkus.otel.exporter.otlp.traces.protocol")

View file

@ -43,9 +43,11 @@ public class TracingConfigurationTest extends AbstractConfigurationTest {
"log-file-include-trace", "true", "log-file-include-trace", "true",
"log-syslog-include-trace", "true" "log-syslog-include-trace", "true"
)); ));
assertConfig("tracing-service-name", "keycloak");
assertExternalConfig(Map.of( assertExternalConfig(Map.of(
"quarkus.otel.traces.enabled", "false", "quarkus.otel.traces.enabled", "false",
"quarkus.otel.service.name", "keycloak",
"quarkus.otel.exporter.otlp.traces.endpoint", "http://localhost:4317", "quarkus.otel.exporter.otlp.traces.endpoint", "http://localhost:4317",
"quarkus.otel.exporter.otlp.traces.protocol", "grpc", "quarkus.otel.exporter.otlp.traces.protocol", "grpc",
"quarkus.datasource.jdbc.telemetry", "false", "quarkus.datasource.jdbc.telemetry", "false",
@ -69,6 +71,10 @@ public class TracingConfigurationTest extends AbstractConfigurationTest {
"KC_LOG_FILE_INCLUDE_TRACE", "false", "KC_LOG_FILE_INCLUDE_TRACE", "false",
"KC_LOG_SYSLOG_INCLUDE_TRACE", "false" "KC_LOG_SYSLOG_INCLUDE_TRACE", "false"
)); ));
putEnvVars(Map.of(
"KC_TRACING_SERVICE_NAME", "keycloak-42",
"KC_TRACING_RESOURCE_ATTRIBUTES", "host.name=unknown,service.version=30"
));
initConfig(); initConfig();
@ -80,6 +86,10 @@ public class TracingConfigurationTest extends AbstractConfigurationTest {
"tracing-sampler-type", SamplerType.PARENT_BASED_ALWAYS_ON.getValue(), "tracing-sampler-type", SamplerType.PARENT_BASED_ALWAYS_ON.getValue(),
"tracing-sampler-ratio", "0.5", "tracing-sampler-ratio", "0.5",
"tracing-compression", TracingOptions.TracingCompression.gzip.name(), "tracing-compression", TracingOptions.TracingCompression.gzip.name(),
"tracing-service-name", "keycloak-42",
"tracing-resource-attributes", "host.name=unknown,service.version=30"
));
assertConfig(Map.of(
"log-console-include-trace", "false", "log-console-include-trace", "false",
"log-file-include-trace", "false", "log-file-include-trace", "false",
"log-syslog-include-trace", "false" "log-syslog-include-trace", "false"
@ -92,10 +102,49 @@ public class TracingConfigurationTest extends AbstractConfigurationTest {
"quarkus.datasource.jdbc.telemetry", "false", "quarkus.datasource.jdbc.telemetry", "false",
"quarkus.otel.traces.sampler", SamplerType.PARENT_BASED_ALWAYS_ON.getValue(), "quarkus.otel.traces.sampler", SamplerType.PARENT_BASED_ALWAYS_ON.getValue(),
"quarkus.otel.traces.sampler.arg", "0.5", "quarkus.otel.traces.sampler.arg", "0.5",
"quarkus.otel.exporter.otlp.traces.compression", TracingOptions.TracingCompression.gzip.name() "quarkus.otel.exporter.otlp.traces.compression", TracingOptions.TracingCompression.gzip.name(),
"quarkus.otel.service.name", "keycloak-42",
"quarkus.otel.resource.attributes", "host.name=unknown,service.version=30"
)); ));
} }
@Test
public void serviceNamePreference() {
putEnvVars(Map.of(
"KC_TRACING_ENABLED", "true",
"KC_TRACING_SERVICE_NAME", "service-name",
"KC_TRACING_RESOURCE_ATTRIBUTES", "service.name=new-service-name"
));
initConfig();
assertConfig(Map.of(
"tracing-enabled", "true",
"tracing-service-name", "service-name",
"tracing-resource-attributes", "service.name=new-service-name"
));
assertExternalConfig("quarkus.otel.service.name", "service-name");
}
@Test
public void serviceNameResourceAttributes() {
putEnvVars(Map.of(
"KC_TRACING_ENABLED", "true",
"KC_TRACING_RESOURCE_ATTRIBUTES", "service.name=new-service-name"
));
initConfig();
assertConfig(Map.of(
"tracing-enabled", "true",
"tracing-resource-attributes", "service.name=new-service-name"
));
// the default value should be used
assertExternalConfig("quarkus.otel.service.name", "keycloak");
}
@Test @Test
public void consoleLogTraceOn() { public void consoleLogTraceOn() {
assertLogFormat(LoggingOptions.Handler.console, true, LoggingOptions.DEFAULT_LOG_TRACING_FORMAT); assertLogFormat(LoggingOptions.Handler.console, true, LoggingOptions.DEFAULT_LOG_TRACING_FORMAT);

View file

@ -34,12 +34,12 @@ public class TracingDistTest {
private void assertTracingEnabled(CLIResult result) { private void assertTracingEnabled(CLIResult result) {
result.assertMessage("opentelemetry"); result.assertMessage("opentelemetry");
result.assertMessage("service.name=\"Keycloak\""); result.assertMessage("service.name=\"keycloak\"");
} }
private void assertTracingDisabled(CLIResult result) { private void assertTracingDisabled(CLIResult result) {
result.assertMessage("opentelemetry"); result.assertMessage("opentelemetry");
result.assertNoMessage("service.name=\"Keycloak\""); result.assertNoMessage("service.name=\"keycloak\"");
result.assertNoMessage("Failed to export spans."); result.assertNoMessage("Failed to export spans.");
result.assertNoMessage("Connection refused: localhost/127.0.0.1:4317"); result.assertNoMessage("Connection refused: localhost/127.0.0.1:4317");
} }
@ -63,7 +63,6 @@ public class TracingDistTest {
cliResult.assertStartedDevMode(); cliResult.assertStartedDevMode();
assertTracingEnabled(cliResult); assertTracingEnabled(cliResult);
} }
@Test @Test
@Order(3) @Order(3)
@Launch({"build", "--tracing-enabled=true"}) @Launch({"build", "--tracing-enabled=true"})
@ -150,4 +149,39 @@ public class TracingDistTest {
cliResult.assertNoMessage("traceId=, parentId=, spanId=, sampled="); cliResult.assertNoMessage("traceId=, parentId=, spanId=, sampled=");
cliResult.assertStarted(); cliResult.assertStarted();
} }
@Test
@Launch({"start", "--hostname-strict=false", "--http-enabled=true", "--optimized", "--log-level=io.opentelemetry:fine", "--tracing-service-name=my-service"})
void differentServiceName(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertMessage("opentelemetry");
cliResult.assertMessage("service.name=\"my-service\"");
cliResult.assertStarted();
}
@Test
@Launch({"start", "--hostname-strict=false", "--http-enabled=true", "--optimized", "--log-level=io.opentelemetry:fine", "--tracing-resource-attributes=service.name=new-service"})
void serviceNameResourceAttributes(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
// the default value should be used
assertTracingEnabled(cliResult);
cliResult.assertStarted();
}
@Test
@Launch({"start", "--hostname-strict=false", "--http-enabled=true", "--optimized", "--log-level=io.opentelemetry:fine", "--tracing-resource-attributes=some.key1=some.val1,some.key2=some.val2",})
void resourceAttributes(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertTracingEnabled(cliResult);
cliResult.assertMessage("some.key1=\"some.val1\"");
cliResult.assertMessage("some.key2=\"some.val2\"");
cliResult.assertStarted();
}
} }

View file

@ -219,6 +219,11 @@ Tracing (Preview):
Preview: OpenTelemetry protocol used for the telemetry data. Possible values Preview: OpenTelemetry protocol used for the telemetry data. Possible values
are: grpc, http/protobuf. Default: grpc. Available only when Tracing is are: grpc, http/protobuf. Default: grpc. Available only when Tracing is
enabled. enabled.
--tracing-resource-attributes <attributes>
Preview: OpenTelemetry resource attributes present in the exported trace to
characterize the telemetry producer. Values in format 'key1=val1,key2=val2'.
For more information, check the Tracing guide. Available only when Tracing
is enabled.
--tracing-sampler-ratio <ratio> --tracing-sampler-ratio <ratio>
Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled. Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled.
Expected double value in interval <0,1). Default: 1.0. Available only when Expected double value in interval <0,1). Default: 1.0. Available only when
@ -228,6 +233,10 @@ Tracing (Preview):
always_on, always_off, traceidratio, parentbased_always_on, always_on, always_off, traceidratio, parentbased_always_on,
parentbased_always_off, parentbased_traceidratio. Default: traceidratio. parentbased_always_off, parentbased_traceidratio. Default: traceidratio.
Available only when Tracing is enabled. Available only when Tracing is enabled.
--tracing-service-name <name>
Preview: OpenTelemetry service name. Takes precedence over 'service.name'
defined in the 'tracing-resource-attributes' property. Default: keycloak.
Available only when Tracing is enabled.
Truststore: Truststore:

View file

@ -219,6 +219,11 @@ Tracing (Preview):
Preview: OpenTelemetry protocol used for the telemetry data. Possible values Preview: OpenTelemetry protocol used for the telemetry data. Possible values
are: grpc, http/protobuf. Default: grpc. Available only when Tracing is are: grpc, http/protobuf. Default: grpc. Available only when Tracing is
enabled. enabled.
--tracing-resource-attributes <attributes>
Preview: OpenTelemetry resource attributes present in the exported trace to
characterize the telemetry producer. Values in format 'key1=val1,key2=val2'.
For more information, check the Tracing guide. Available only when Tracing
is enabled.
--tracing-sampler-ratio <ratio> --tracing-sampler-ratio <ratio>
Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled. Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled.
Expected double value in interval <0,1). Default: 1.0. Available only when Expected double value in interval <0,1). Default: 1.0. Available only when
@ -228,6 +233,10 @@ Tracing (Preview):
always_on, always_off, traceidratio, parentbased_always_on, always_on, always_off, traceidratio, parentbased_always_on,
parentbased_always_off, parentbased_traceidratio. Default: traceidratio. parentbased_always_off, parentbased_traceidratio. Default: traceidratio.
Available only when Tracing is enabled. Available only when Tracing is enabled.
--tracing-service-name <name>
Preview: OpenTelemetry service name. Takes precedence over 'service.name'
defined in the 'tracing-resource-attributes' property. Default: keycloak.
Available only when Tracing is enabled.
Truststore: Truststore:

View file

@ -430,6 +430,11 @@ Tracing (Preview):
Preview: OpenTelemetry protocol used for the telemetry data. Possible values Preview: OpenTelemetry protocol used for the telemetry data. Possible values
are: grpc, http/protobuf. Default: grpc. Available only when Tracing is are: grpc, http/protobuf. Default: grpc. Available only when Tracing is
enabled. enabled.
--tracing-resource-attributes <attributes>
Preview: OpenTelemetry resource attributes present in the exported trace to
characterize the telemetry producer. Values in format 'key1=val1,key2=val2'.
For more information, check the Tracing guide. Available only when Tracing
is enabled.
--tracing-sampler-ratio <ratio> --tracing-sampler-ratio <ratio>
Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled. Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled.
Expected double value in interval <0,1). Default: 1.0. Available only when Expected double value in interval <0,1). Default: 1.0. Available only when
@ -439,6 +444,10 @@ Tracing (Preview):
always_on, always_off, traceidratio, parentbased_always_on, always_on, always_off, traceidratio, parentbased_always_on,
parentbased_always_off, parentbased_traceidratio. Default: traceidratio. parentbased_always_off, parentbased_traceidratio. Default: traceidratio.
Available only when Tracing is enabled. Available only when Tracing is enabled.
--tracing-service-name <name>
Preview: OpenTelemetry service name. Takes precedence over 'service.name'
defined in the 'tracing-resource-attributes' property. Default: keycloak.
Available only when Tracing is enabled.
Truststore: Truststore:

View file

@ -431,6 +431,11 @@ Tracing (Preview):
Preview: OpenTelemetry protocol used for the telemetry data. Possible values Preview: OpenTelemetry protocol used for the telemetry data. Possible values
are: grpc, http/protobuf. Default: grpc. Available only when Tracing is are: grpc, http/protobuf. Default: grpc. Available only when Tracing is
enabled. enabled.
--tracing-resource-attributes <attributes>
Preview: OpenTelemetry resource attributes present in the exported trace to
characterize the telemetry producer. Values in format 'key1=val1,key2=val2'.
For more information, check the Tracing guide. Available only when Tracing
is enabled.
--tracing-sampler-ratio <ratio> --tracing-sampler-ratio <ratio>
Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled. Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled.
Expected double value in interval <0,1). Default: 1.0. Available only when Expected double value in interval <0,1). Default: 1.0. Available only when
@ -440,6 +445,10 @@ Tracing (Preview):
always_on, always_off, traceidratio, parentbased_always_on, always_on, always_off, traceidratio, parentbased_always_on,
parentbased_always_off, parentbased_traceidratio. Default: traceidratio. parentbased_always_off, parentbased_traceidratio. Default: traceidratio.
Available only when Tracing is enabled. Available only when Tracing is enabled.
--tracing-service-name <name>
Preview: OpenTelemetry service name. Takes precedence over 'service.name'
defined in the 'tracing-resource-attributes' property. Default: keycloak.
Available only when Tracing is enabled.
Truststore: Truststore:

View file

@ -377,10 +377,19 @@ Tracing (Preview):
Preview: OpenTelemetry protocol used for the telemetry data. Possible values Preview: OpenTelemetry protocol used for the telemetry data. Possible values
are: grpc, http/protobuf. Default: grpc. Available only when Tracing is are: grpc, http/protobuf. Default: grpc. Available only when Tracing is
enabled. enabled.
--tracing-resource-attributes <attributes>
Preview: OpenTelemetry resource attributes present in the exported trace to
characterize the telemetry producer. Values in format 'key1=val1,key2=val2'.
For more information, check the Tracing guide. Available only when Tracing
is enabled.
--tracing-sampler-ratio <ratio> --tracing-sampler-ratio <ratio>
Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled. Preview: OpenTelemetry sampler ratio. Probability that a span will be sampled.
Expected double value in interval <0,1). Default: 1.0. Available only when Expected double value in interval <0,1). Default: 1.0. Available only when
Tracing is enabled. Tracing is enabled.
--tracing-service-name <name>
Preview: OpenTelemetry service name. Takes precedence over 'service.name'
defined in the 'tracing-resource-attributes' property. Default: keycloak.
Available only when Tracing is enabled.
Truststore: Truststore: