Skip to content

Commit 0f2a168

Browse files
committed
Remove ConsoleStreamSupplier interface
1 parent 3c4802b commit 0f2a168

File tree

2 files changed

+87
-188
lines changed

2 files changed

+87
-188
lines changed

log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java

Lines changed: 87 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,23 @@
1616
*/
1717
package org.apache.logging.log4j.core.appender;
1818

19+
import java.io.FileDescriptor;
20+
import java.io.FileOutputStream;
21+
import java.io.IOException;
1922
import java.io.OutputStream;
2023
import java.nio.charset.Charset;
2124
import java.nio.charset.UnsupportedCharsetException;
22-
import java.util.List;
23-
import java.util.Objects;
2425
import java.util.concurrent.atomic.AtomicInteger;
2526
import org.apache.logging.log4j.core.Appender;
2627
import org.apache.logging.log4j.core.Filter;
2728
import org.apache.logging.log4j.core.Layout;
28-
import org.apache.logging.log4j.core.appender.internal.DefaultConsoleStreamSupplier;
29-
import org.apache.logging.log4j.core.config.Configuration;
3029
import org.apache.logging.log4j.core.config.Property;
3130
import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
32-
import org.apache.logging.log4j.kit.env.PropertyEnvironment;
3331
import org.apache.logging.log4j.plugins.Configurable;
34-
import org.apache.logging.log4j.plugins.Namespace;
3532
import org.apache.logging.log4j.plugins.Plugin;
3633
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
3734
import org.apache.logging.log4j.plugins.PluginFactory;
38-
import org.apache.logging.log4j.plugins.di.Key;
3935
import org.apache.logging.log4j.plugins.validation.constraints.Required;
40-
import org.jspecify.annotations.Nullable;
4136

4237
/**
4338
* Appends log events to <code>System.out</code> or <code>System.err</code> using a layout specified by the user. The
@@ -166,30 +161,15 @@ public B setDirect(final boolean shouldDirect) {
166161

167162
@Override
168163
public ConsoleAppender build() {
169-
final Layout layout = getOrCreateLayout(target.getDefaultCharset());
170-
171-
final Configuration configuration = getConfiguration();
172-
final PropertyEnvironment propertyEnvironment;
173-
final List<ConsoleStreamSupplier> suppliers;
174-
if (configuration != null) {
175-
propertyEnvironment = configuration.getLoggerContext() != null
176-
? configuration.getLoggerContext().getEnvironment()
177-
: PropertyEnvironment.getGlobal();
178-
179-
suppliers = configuration.getComponent(new @Namespace(ConsoleStreamSupplier.NAMESPACE) Key<>() {});
180-
} else {
181-
propertyEnvironment = PropertyEnvironment.getGlobal();
182-
suppliers = List.of(new DefaultConsoleStreamSupplier());
164+
if (direct && follow) {
165+
LOGGER.error("Cannot use both `direct` and `follow` on ConsoleAppender.");
166+
return null;
183167
}
168+
final Layout layout = getOrCreateLayout(target.getDefaultCharset());
184169

185-
final OutputStream stream = suppliers.stream()
186-
.map(s -> s.getOutputStream(follow, direct, target, propertyEnvironment))
187-
.filter(Objects::nonNull)
188-
.findFirst()
189-
.orElse(null);
190-
if (stream == null) {
191-
LOGGER.warn("No output stream found for target {}", target);
192-
}
170+
OutputStream stream = direct
171+
? getDirectOutputStream(target)
172+
: follow ? getFollowOutputStream(target) : getDefaultOutputStream(target);
193173

194174
final String managerName = target.name() + '.' + follow + '.' + direct;
195175
final OutputStreamManager manager =
@@ -207,6 +187,83 @@ private static OutputStreamManager getDefaultManager(final Layout layout) {
207187
return OutputStreamManager.getManager(managerName, new FactoryData(os, managerName, layout), factory);
208188
}
209189

190+
private static OutputStream getDefaultOutputStream(Target target) {
191+
return new CloseShieldOutputStream(target == Target.SYSTEM_OUT ? System.out : System.err);
192+
}
193+
194+
private static OutputStream getDirectOutputStream(Target target) {
195+
return new CloseShieldOutputStream(
196+
new FileOutputStream(target == Target.SYSTEM_OUT ? FileDescriptor.out : FileDescriptor.err));
197+
}
198+
199+
private static OutputStream getFollowOutputStream(Target target) {
200+
return target == Target.SYSTEM_OUT ? new SystemOutStream() : new SystemErrStream();
201+
}
202+
203+
/**
204+
* An implementation of OutputStream that redirects to the current System.err.
205+
*/
206+
private static class SystemErrStream extends OutputStream {
207+
public SystemErrStream() {}
208+
209+
@Override
210+
public void close() {
211+
// do not close sys err!
212+
}
213+
214+
@Override
215+
public void flush() {
216+
System.err.flush();
217+
}
218+
219+
@Override
220+
public void write(final byte[] b) throws IOException {
221+
System.err.write(b);
222+
}
223+
224+
@Override
225+
public void write(final byte[] b, final int off, final int len) throws IOException {
226+
System.err.write(b, off, len);
227+
}
228+
229+
@Override
230+
public void write(final int b) {
231+
System.err.write(b);
232+
}
233+
}
234+
235+
/**
236+
* An implementation of OutputStream that redirects to the current System.out.
237+
*/
238+
private static class SystemOutStream extends OutputStream {
239+
public SystemOutStream() {}
240+
241+
@Override
242+
public void close() {
243+
// do not close sys out!
244+
}
245+
246+
@Override
247+
public void flush() {
248+
System.out.flush();
249+
}
250+
251+
@Override
252+
public void write(final byte[] b) throws IOException {
253+
System.out.write(b);
254+
}
255+
256+
@Override
257+
public void write(final byte[] b, final int off, final int len) throws IOException {
258+
System.out.write(b, off, len);
259+
}
260+
261+
@Override
262+
public void write(final int b) throws IOException {
263+
System.out.write(b);
264+
}
265+
}
266+
210267
/**
211268
* Data to pass to factory method.Unable to instantiate
212269
*/
@@ -250,23 +307,4 @@ public OutputStreamManager createManager(final String name, final FactoryData da
250307
public Target getTarget() {
251308
return target;
252309
}
253-
254-
/**
255-
* Abstracts the various ways `System.out` can be accessed.
256-
*
257-
* @since 3.0.0
258-
*/
259-
public interface ConsoleStreamSupplier {
260-
261-
/**
262-
* The Log4j plugin namespace of plugins implementing this interface.
263-
*/
264-
String NAMESPACE = "Console";
265-
266-
/**
267-
* @return Selects the output stream to use or {@code null} in case of error.
268-
*/
269-
@Nullable
270-
OutputStream getOutputStream(boolean follow, boolean direct, Target target, PropertyEnvironment properties);
271-
}
272310
}

log4j-core/src/main/java/org/apache/logging/log4j/core/appender/internal/DefaultConsoleStreamSupplier.java

Lines changed: 0 additions & 139 deletions
This file was deleted.

0 commit comments

Comments
 (0)