Skip to content

Commit

Permalink
Mute Lucene MMap warning (#92857) (#92895)
Browse files Browse the repository at this point in the history
Starting with Java 19, Lucene has support for using the Java Foreign
Memory API. To do enable this, preview features in the JDK must be
enabled using --enable-preview. If JDK 19 is used, and preview features
are not enabled, a warning message is emitted to stderr. In
Elasticsearch, this message is captured and then passed to the main
logfile.

While the new API may have some benefits in the future, we are not yet
ready to recommend enabling preview features. Since the log message from
Lucene shows as a warning to users, it is very suggestive that they
should enable the feature. In order to avoid that confusion, this commit
hides the messages sent by Lucene by filtering those we log from
stderr.

Note that Lucene emits two messages, and the first contains a timestamp,
so the entire message cannot be known ahead of time. The filtering
implementation is linear. However, since there are a small number of
these, and a similarly small total number of messages that we expect to
see from stderr, the performance should not be a concern.
  • Loading branch information
rjernst committed Jan 13, 2023
1 parent 487d741 commit 62baebe
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,22 @@ public FileVisitResult visitFile(final Path file, final BasicFileAttributes attr
// Redirect stdout/stderr to log4j. While we ensure Elasticsearch code does not write to those streams,
// third party libraries may do that. Note that we do NOT close the streams because other code may have
// grabbed a handle to the streams and intend to write to it, eg log4j for writing to the console
System.setOut(new PrintStream(new LoggingOutputStream(LogManager.getLogger("stdout"), Level.INFO), false, StandardCharsets.UTF_8));
System.setErr(new PrintStream(new LoggingOutputStream(LogManager.getLogger("stderr"), Level.WARN), false, StandardCharsets.UTF_8));
System.setOut(
new PrintStream(new LoggingOutputStream(LogManager.getLogger("stdout"), Level.INFO, List.of()), false, StandardCharsets.UTF_8)
);
System.setErr(
new PrintStream(
new LoggingOutputStream(
LogManager.getLogger("stderr"),
Level.WARN,
// MMapDirectory messages come from Lucene, suggesting to users as a warning that they should enable preview features in
// the JDK
List.of("MMapDirectory")
),
false,
StandardCharsets.UTF_8
)
);

final Logger rootLogger = LogManager.getRootLogger();
Appender appender = Loggers.findAppender(rootLogger, ConsoleAppender.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

/**
* A stream whose output is sent to the configured logger, line by line.
Expand Down Expand Up @@ -42,9 +43,12 @@ static class Buffer {

private final Level level;

LoggingOutputStream(Logger logger, Level level) {
private final List<String> messageFilters;

LoggingOutputStream(Logger logger, Level level, List<String> messageFilters) {
this.logger = logger;
this.level = level;
this.messageFilters = messageFilters;
}

@Override
Expand Down Expand Up @@ -103,8 +107,17 @@ public void close() {
threadLocal = null;
}

private void log(String msg) {
for (String filter : messageFilters) {
if (msg.contains(filter)) {
return;
}
}
this.log0(msg);
}

// pkg private for testing
void log(String msg) {
protected void log0(String msg) {
logger.log(level, msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,22 @@ class TestLoggingOutputStream extends LoggingOutputStream {
List<String> lines = new ArrayList<>();

TestLoggingOutputStream() {
super(null, null);
super(null, null, messageFilters);
}

@Override
void log(String msg) {
protected void log0(String msg) {
lines.add(msg);
}
}

List<String> messageFilters = new ArrayList<>();
TestLoggingOutputStream loggingStream;
PrintStream printStream;

@Before
public void createStream() {
messageFilters.clear();
loggingStream = new TestLoggingOutputStream();
printStream = new PrintStream(loggingStream, false, StandardCharsets.UTF_8);
}
Expand Down Expand Up @@ -115,4 +117,12 @@ public void testThreadIsolation() throws Exception {
printStream.flush();
assertThat(loggingStream.lines, contains("from thread 2", "from thread 1"));
}

public void testMessageFilters() throws Exception {
messageFilters.add("foo bar");
printStream.println("prefix foo bar suffix");
printStream.println("non-filtered message");
printStream.flush();
assertThat(loggingStream.lines, contains("non-filtered message"));
}
}

0 comments on commit 62baebe

Please sign in to comment.