From 2a5c4c906f36765d22c0e077ee7a9952b63a29b8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:01:39 +0100 Subject: [PATCH] Backport PR #15925 to 8.12: Set Netty's maxOrder options to previous default (#15928) Updates Netty's configuration of maxOrder to a previously proven value, if not already customised by the user. Adds a step to the JvmOption parsing tool, which is used to compose the JVM options string to pass down to Logstash at startup. The added step rework the parsed options to set the allocator max order -Dio.netty.allocator.maxOrder=11 so that the maximum pooled buffer is up to 16MB and not 4MB. This option is added iff it's not yet specified by the user (cherry picked from commit 52ce3ff8f63e4987c9d107197a16400bcf8bc185) Co-authored-by: Andrea Selva --- tools/jvm-options-parser/build.gradle | 6 ++-- .../logstash/launchers/JvmOptionsParser.java | 22 +++++++++++- .../launchers/JvmOptionsParserTest.java | 36 +++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/tools/jvm-options-parser/build.gradle b/tools/jvm-options-parser/build.gradle index 4687aea17ce..81119874856 100644 --- a/tools/jvm-options-parser/build.gradle +++ b/tools/jvm-options-parser/build.gradle @@ -31,11 +31,11 @@ buildscript { } } -project.sourceCompatibility = JavaVersion.VERSION_1_8 -project.targetCompatibility = JavaVersion.VERSION_1_8 +project.sourceCompatibility = JavaVersion.VERSION_11 +project.targetCompatibility = JavaVersion.VERSION_11 dependencies { - testImplementation "junit:junit:4.12" + testImplementation "junit:junit:4.13.1" } javadoc { diff --git a/tools/jvm-options-parser/src/main/java/org/logstash/launchers/JvmOptionsParser.java b/tools/jvm-options-parser/src/main/java/org/logstash/launchers/JvmOptionsParser.java index acf6beb7008..a11399e6e6e 100644 --- a/tools/jvm-options-parser/src/main/java/org/logstash/launchers/JvmOptionsParser.java +++ b/tools/jvm-options-parser/src/main/java/org/logstash/launchers/JvmOptionsParser.java @@ -32,6 +32,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -180,7 +181,26 @@ private void handleJvmOptions(Optional jvmOptionsFile, String lsJavaOpts) // Set mandatory JVM options jvmOptionsContent.addAll(getMandatoryJvmOptions(javaMajorVersion)); - System.out.println(String.join(" ", jvmOptionsContent)); + final Set jvmFinalOptions = nettyMaxOrderDefaultTo11(jvmOptionsContent); + + System.out.println(String.join(" ", jvmFinalOptions)); + } + + /** + * Inplace method that verifies if Netty's maxOrder option is already set, else configure it to have + * the default value of 11. + * + * @param options the collection of options to examine. + * @return the collection of input option eventually with Netty maxOrder added. + * */ + private Set nettyMaxOrderDefaultTo11(Set options) { + boolean maxOrderAlreadyContained = options.stream().anyMatch(s -> s.startsWith("-Dio.netty.allocator.maxOrder")); + if (maxOrderAlreadyContained) { + return options; + } + final Set acc = new HashSet<>(options); + acc.add("-Dio.netty.allocator.maxOrder=11"); + return acc; } /** diff --git a/tools/jvm-options-parser/src/test/java/org/logstash/launchers/JvmOptionsParserTest.java b/tools/jvm-options-parser/src/test/java/org/logstash/launchers/JvmOptionsParserTest.java index b8228f1b60d..cab093bcc82 100644 --- a/tools/jvm-options-parser/src/test/java/org/logstash/launchers/JvmOptionsParserTest.java +++ b/tools/jvm-options-parser/src/test/java/org/logstash/launchers/JvmOptionsParserTest.java @@ -8,11 +8,15 @@ import java.io.BufferedReader; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; +import java.io.PrintWriter; import java.io.StringReader; import java.lang.reflect.Field; import java.util.Map; +import java.util.function.Consumer; import static org.junit.Assert.*; @@ -123,6 +127,38 @@ public void testErrorLinesAreReportedCorrectly() throws IOException { assertEquals("anotherInvalidOption", res.getInvalidLines().get(4)); } + @Test + public void testNettyMaxOrderRuleAppliesIfNotAlreadyDefinedExplicitlyByUser() throws IOException { + File optionsFile = writeIntoTempOptionsFile(writer -> writer.println("-Dsome.other.netty.property=123")); + + JvmOptionsParser.handleJvmOptions(new String[] {"/path/to/ls_home", optionsFile.toString()}, "-Dcli.opts=something"); + + // Verify + final String output = outputStreamCaptor.toString(); + assertTrue("Existing properties other than Netty's maxOrder ar preserved", output.contains("-Dsome.other.netty.property=123")); + assertTrue("Netty's maxOrder MUST be forcibly defined to the expected default", output.contains("-Dio.netty.allocator.maxOrder=11")); + } + + @Test + public void testNettyMaxOrderRuleDoNotAppliesIfAlreadyDefinedExplicitlyByUser() throws IOException { + File optionsFile = writeIntoTempOptionsFile(writer -> writer.println("-Dio.netty.allocator.maxOrder=10")); + + JvmOptionsParser.handleJvmOptions(new String[] {"/path/to/ls_home", optionsFile.toString()}, "-Dcli.opts=something"); + + // Verify + final String output = outputStreamCaptor.toString(); + assertTrue("Netty's maxOrder MUST be forcibly defined to the expected default", output.contains("-Dio.netty.allocator.maxOrder=10")); + + } + + private File writeIntoTempOptionsFile(Consumer writer) throws IOException { + File optionsFile = temp.newFile("jvm.options"); + PrintWriter optionsWriter = new PrintWriter(new FileWriter(optionsFile)); + writer.accept(optionsWriter); + optionsWriter.close(); + return optionsFile; + } + private void verifyOptions(String message, String expected, JvmOptionsParser.ParseResult res) { assertEquals(message, expected, String.join(System.lineSeparator(), res.getJvmOptions())); }