8000 Missing Quarkus flag for Syslog counting framing by mabartos · Pull Request #40621 · keycloak/keycloak · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Missing Quarkus flag for Syslog counting framing #40621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ Previously the default *browser* flow had a *Browser - Conditional OTP* conditio

Upgraded realms will not be changed. The updated flow will only be available for new realms. Take this change into consideration if you have auto 8000 mated the realm creation.

=== Syslog counting framing now enabled based on protocol

Syslog messages sent over `tcp` (or `ssl-tcp`) protocol now use counting framing by default, prefixing messages with their size as required by some Syslog servers.

To change this behavior, use the `--log-syslog-counting-framing` option with one of the following values: `protocol-dependent` (default), `true`, or `false`.

== Deprecated features

The following sections provide details on deprecated features.
Expand Down
17 changes: 17 additions & 0 deletions docs/guides/server/logging.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,23 @@ To use UDP instead of TCP, add the `--log-syslog-protocol` option as follows:

The available protocols are: `tpc`, `udp`, and `ssl-tcp`.

=== Configuring the Syslog counting framing

By default, Syslog messages sent over TCP or SSL-TCP are prefixed with the message size, as required by certain Syslog receivers.
This behavior is controlled by the `--log-syslog-counting-framing` option.

To explicitly enable or disable this feature, use the following command:

<@kc.start parameters="--log-syslog-counting-framing=true"/>

You can set the value to one of the following:

* `protocol-dependent` (default) – Enable counting framing only when the `log-syslog-protocol` is `tcp` or `ssl-tcp`.
* `true` – Always enable counting framing by prefixing messages with their size.
* `false` – Never use counting framing.

Note that using `protocol-dependent` ensures compatibility with most Syslog servers by enabling the prefix only when required by the protocol.

=== Configuring the Syslog log format
To set the logging format for a logged line, perform these steps:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,16 @@ public String toString() {
.description("Set the Syslog output to JSON or default (plain) unstructured logging.")
.build();

// we can use SyslogConfig.CountingFraming type once https://github.com/quarkusio/quarkus/pull/48479 is present
public static final String SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT = "protocol-dependent";
public static final Option<String> LOG_SYSLOG_COUNTING_FRAMING = new OptionBuilder<>("log-syslog-counting-framing", String.class)
.category(OptionCategory.LOGGING)
.expectedValues(Boolean.TRUE.toString(), Boolean.FALSE.toString(), SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT)
.defaultValue(SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT)
.description("If 'true', the message being sent is prefixed with the size of the message. If '%s', the default value is 'true' when '%s' is 'tcp' or 'ssl-tcp', otherwise 'false'."
.formatted(SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT, LOG_SYSLOG_PROTOCOL.getKey()))
.build();

// Syslog async
public static final Option<Boolean> LOG_SYSLOG_ASYNC = new OptionBuilder<>("log-syslog-async", Boolean.class)
.category(OptionCategory.LOGGING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.keycloak.config.LoggingOptions.LOG_CONSOLE_ENABLED;
import static org.keycloak.config.LoggingOptions.LOG_FILE_ENABLED;
import static org.keycloak.config.LoggingOptions.LOG_SYSLOG_ENABLED;
import static org.keycloak.config.LoggingOptions.SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT;
import static org.keycloak.quarkus.runtime.configuration.Configuration.isSet;
import static org.keycloak.quarkus.runtime.configuration.Configuration.isTrue;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
Expand Down Expand Up @@ -215,6 +216,12 @@ public static PropertyMapper<?>[] getMappers() {
.paramLabel("output")
.transformer(LoggingPropertyMappers::resolveLogOutput)
.build(),
fromOption(LoggingOptions.LOG_SYSLOG_COUNTING_FRAMING)
.isEnabled(LoggingPropertyMappers::isSyslogEnabled, SYSLOG_ENABLED_MSG)
.transformer(LoggingPropertyMappers::resolveSyslogCountingFraming)
.to("quarkus.log.syslog.use-counting-framing")
.paramLabel("strategy")
.build(),
// Syslog async
fromOption(LoggingOptions.LOG_SYSLOG_ASYNC)
.mapFrom(LoggingOptions.LOG_ASYNC)
Expand Down Expand Up @@ -411,4 +418,20 @@ private static void validateSyslogMaxLength(String value) {
throw new PropertyException(String.format("Invalid value for option '--log-syslog-max-length': %s", e.getMessage()));
}
}

// Workaround BEGIN - for https://github.com/keycloak/keycloak/issues/39893
// Remove once the https://github.com/quarkusio/quarkus/issues/48036 is included in Keycloak as Quarkus might handle it on its own
private static String resolveSyslogCountingFraming(String value, ConfigSourceInterceptorContext context) {
if (SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT.equals(value)) {
return Configuration.getOptionalKcValue(LoggingOptions.LOG_SYSLOG_PROTOCOL)
.map(protocol -> switch (protocol) {
case "tcp", "ssl-tcp" -> Boolean.TRUE.toString();
case "udp" -> Boolean.FALSE.toString();
default -> throw new PropertyException("Invalid Syslog protocol: " + protocol);
})
.orElse(Boolean.FALSE.toString());
}
return value;
}
// Workaround END
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -481,6 +482,31 @@ public void syslogMaxLengthMemorySize() {
"Invalid value for option '--log-syslog-max-length': value wrong not in correct format (regular expression): [0-9]+[BbKkMmGgTtPpEeZzYy]?"));
}

@Test
public void syslogCountingFraming() {
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-counting-framing=TRUE");
assertThat(nonRunningPicocli.exitCode, is(CommandLine.ExitCode.USAGE));
assertThat(nonRunningPicocli.getErrString(), containsString(
"Invalid value for option '--log-syslog-counting-framing': TRUE. Expected values are: true, false, protocol-dependent"));

nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-counting-framing=true");
assertThat(nonRunningPicocli.exitCode, is(CommandLine.ExitCode.OK));
assertThat(nonRunningPicocli.config.getConfigValue("quarkus.log.syslog.use-counting-framing").getValue(), is("true"));

nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-counting-framing=false");
assertThat(nonRunningPicocli.exitCode, is(CommandLine.ExitCode.OK));
assertThat(nonRunningPicocli.config.getConfigValue("quarkus.log.syslog.use-counting-framing").getValue(), is("false"));

nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-protocol=ssl-tcp", "--log-syslog-counting-framing=protocol-dependent");
assertThat(nonRunningPicocli.exitCode, is(CommandLine.ExitCode.OK));
assertThat(nonRunningPicocli.config.getConfigValue("quarkus.log.syslog.use-counting-framing").getValue(), is("true"));

nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-counting-framing=wrong");
assertThat(nonRunningPicocli.exitCode, is(CommandLine.ExitCode.USAGE));
assertThat(nonRunningPicocli.getErrString(), containsString(
"Invalid value for option '--log-syslog-counting-framing': wrong. Expected values are: true, false, protocol-dependent"));
}

@Test
public void providerChanged() {
build("build", "--db=dev-file");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@

package org.keycloak.quarkus.runtime.configuration;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.keycloak.config.LoggingOptions.DEFAULT_LOG_FORMAT;
import static org.keycloak.config.LoggingOptions.DEFAULT_SYSLOG_OUTPUT;
import static org.keycloak.config.LoggingOptions.SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT;

import java.util.Map;
import java.util.Set;
Expand All @@ -35,9 +38,6 @@
import org.keycloak.config.LoggingOptions;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
import org.keycloak.quarkus.runtime.configuration.Configuration;

import io.smallrye.config.SmallRyeConfig;

public class LoggingConfigurationTest extends AbstractConfigurationTest {
Expand Down Expand Up @@ -86,7 +86,8 @@ public void syslogDefaults() {
"log-syslog-app-name", "keycloak",
"log-syslog-protocol", "tcp",
"log-syslog-format", DEFAULT_LOG_FORMAT,
"log-syslog-output", DEFAULT_SYSLOG_OUTPUT.toString()
"log-syslog-output", DEFAULT_SYSLOG_OUTPUT.toString(),
"log-syslog-counting-framing", SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT
));
assertThat(Configuration.getOptionalKcValue(LoggingOptions.LOG_SYSLOG_MAX_LENGTH).orElse(null), CoreMatchers.nullValue());

Expand All @@ -96,6 +97,7 @@ public void syslogDefaults() {
"quarkus.log.syslog.syslog-type", "rfc5424",
"quarkus.log.syslog.app-name", "keycloak",
"quarkus.log.syslog.protocol", "tcp",
"quarkus.log.syslog.use-counting-framing", "true",
"quarkus.log.syslog.format", DEFAULT_LOG_FORMAT,
"quarkus.log.syslog.json.enabled", "false"
));
Expand All @@ -113,6 +115,7 @@ public void syslogDifferentValues() {
"KC_LOG_SYSLOG_MAX_LENGTH", "4096",
"KC_LOG_SYSLOG_APP_NAME", "keycloak2",
"KC_LOG_SYSLOG_PROTOCOL", "udp",
"KC_LOG_SYSLOG_COUNTING_FRAMING", "false",
"KC_LOG_SYSLOG_FORMAT", "some format",
"KC_LOG_SYSLOG_OUTPUT", "json"
));
Expand All @@ -126,6 +129,7 @@ public void syslogDifferentValues() {
"log-syslog-max-length", "4096",
"log-syslog-app-name", "keycloak2",
"log-syslog-protocol", "udp",
"log-syslog-counting-framing", "false",
"log-syslog-format", "some format",
"log-syslog-output", "json"
));
Expand All @@ -137,6 +141,7 @@ public void syslogDifferentValues() {
"quarkus.log.syslog.max-length", "4096",
"quarkus.log.syslog.app-name", "keycloak2",
"quarkus.log.syslog.protocol", "udp",
"quarkus.log.syslog.use-counting-framing", "false",
"quarkus.log.syslog.format", "some format",
"quarkus.log.syslog.json.enabled", "true"
));
Expand Down Expand Up @@ -168,6 +173,40 @@ public void syslogMaxLength() {
assertExternalConfig("quarkus.log.syslog.max-length", "512");
}

@Test
public void syslogCountingFraming() {
assertSyslogCountingFramingProtocolDependent("tcp", true);
assertSyslogCountingFramingProtocolDependent("udp", false);
assertSyslogCountingFramingProtocolDependent("ssl-tcp", true);
try {
assertSyslogCountingFramingProtocolDependent("error", false);
fail("Wrong protocol name should throw an error");
} catch (PropertyException expected) {
assertThat(expected.getMessage(), containsString("Invalid Syslog protocol: error"));
}
}

protected void assertSyslogCountingFramingProtocolDependent(String protocol, boolean expectedCountingFraming) {
putEnvVars(Map.of(
"KC_LOG", "syslog",
"KC_LOG_SYSLOG_PROTOCOL", protocol
));

initConfig();

assertConfig(Map.of(
"log-syslog-enabled", "true",
"log-syslog-protocol", protocol,
"log-syslog-counting-framing", SYSLOG_COUNTING_FRAMING_PROTOCOL_DEPENDENT
));
assertExternalConfig(Map.of(
"quarkus.log.syslog.enable", "true",
"quarkus.log.syslog.protocol", protocol,
"quarkus.log.syslog.use-counting-framing", Boolean.toString(expectedCountingFraming)
));
onAfter();
}

@Test
public void logLevelsHandlers() {
putEnvVars(Map.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ Logging:
The queue length to use before flushing writing when logging to Syslog.
Default: 512. Available only when Syslog is activated and asynchronous
logging is enabled.
--log-syslog-counting-framing <strategy>
If 'true', the message being sent is prefixed with the size of the message. If
'protocol-dependent', the default value is 'true' when 'log-syslog-protocol'
is 'tcp' or 'ssl-tcp', otherwise 'false'. Possible values are: true, false,
protocol-dependent. Default: protocol-dependent. Available only when Syslog
is activated.
--log-syslog-endpoint <host:port>
Set the IP address and port of the Syslog server. Default: localhost:514.
Available only when Syslog is activated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ Logging:
The queue length to use before flushing writing when logging to Syslog.
Default: 512. Available only when Syslog is activated and asynchronous
logging is enabled.
--log-syslog-counting-framing <strategy>
If 'true', the message being sent is prefixed with the size of the message. If
'protocol-dependent', the default value is 'true' when 'log-syslog-protocol'
is 'tcp' or 'ssl-tcp', otherwise 'false'. Possible values are: true, false,
protocol-dependent. Default: protocol-dependent. Available only when Syslog
is activated.
--log-syslog-endpoint <host:port>
Set the IP address and port of the Syslog server. Default: localhost:514.
Available only when Syslog is activated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,12 @@ Logging:
The queue length to use before flushing writing when logging to Syslog.
Default: 512. Available only when Syslog is activated and asynchronous
logging is enabled.
--log-syslog-counting-framing <strategy>
If 'true', the message being sent is prefixed with the size of the message. If
'protocol-dependent', the default value is 'true' when 'log-syslog-protocol'
is 'tcp' or 'ssl-tcp', otherwise 'false'. Possible values are: true, false,
protocol-dependent. Default: protocol-dependent. Available only when Syslog
is activated.
--log-syslog-endpoint <host:port>
Set the IP address and port of the Syslog server. Default: localhost:514.
Available only when Syslog is activated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,12 @@ Logging:
The queue length to use before flushing writing when logging to Syslog.
Default: 512. Available only when Syslog is activated and asynchronous
logging is enabled.
--log-syslog-counting-framing <strategy>
If 'true', the message being sent is prefixed with the size of the message. If
'protocol-dependent', the default value is 'true' when 'log-syslog-protocol'
is 'tcp' or 'ssl-tcp', otherwise 'false'. Possible values are: true, false,
protocol-dependent. Default: protocol-dependent. Available only when Syslog
is activated.
--log-syslog-endpoint <host:port>
Set the IP address and port of the Syslog server. Default: localhost:514.
Available only when Syslog is activated.
Expand Down
3D11
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,12 @@ Logging:
The queue length to use before flushing writing when logging to Syslog.
Default: 512. Available only when Syslog is activated and asynchronous
logging is enabled.
--log-syslog-counting-framing <strategy>
If 'true', the message being sent is prefixed with the size of the message. If
'protocol-dependent', the default value is 'true' when 'log-syslog-protocol'
is 'tcp' or 'ssl-tcp', otherwise 'false'. Possible values are: true, false,
protocol-dependent. Default: protocol-dependent. Available only when Syslog
is activated.
--log-syslog-endpoint <host:port>
Set the IP address and port of the Syslog server. Default: localhost:514.
Available only when Syslog is activated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,12 @@ Logging:
The queue length to use before flushing writing when logging to Syslog.
Default: 512. Available only when Syslog is activated and asynchronous
logging is enabled.
--log-syslog-counting-framing <strategy>
If 'true', the message being sent is prefixed with the size of the message. If
'protocol-dependent', the default value is 'true' when 'log-syslog-protocol'
is 'tcp' or 'ssl-tcp', otherwise 'false'. Possible values are: true, false,
protocol-dependent. Default: protocol-dependent. Available only when Syslog
is activated.
--log-syslog-endpoint <host:port>
Set the IP address and port of the Syslog server. Default: localhost:514.
Available only when Syslog is activated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,12 @@ Logging:
The queue length to use before flushing writing when logging to Syslog.
Default: 512. Available only when Syslog is activated and asynchronous
logging is enabled.
--log-syslog-counting-framing <strategy>
If 'true', the message being sent is prefixed with the size of the message. If
'protocol-dependent', the default value is 'true' when 'log-syslog-protocol'
is 'tcp' or 'ssl-tcp', otherwise 'false'. Possible values are: true, false,
protocol-dependent. Default: protocol-dependent. Available only when Syslog
is activated.
--log-syslog-endpoint <host:port>
Set the IP address and port of the Syslog server. Default: localhost:514.
Available only when Syslog is activated.
Expand Down
Loading
0